Skip to content

Latest commit

 

History

History
89 lines (64 loc) · 4.72 KB

rfc0039_behavior_major_versions.md

File metadata and controls

89 lines (64 loc) · 4.72 KB

RFC: Behavior Major Versions

Status: RFC

Applies to: client

For a summarized list of proposed changes, see the Changes Checklist section.

This RFC describes "Behavior Major Versions," a mechanism to allow SDKs to ship breaking behavioral changes like a new retry strategy, while allowing customers who rely on extremely consistent behavior to evolve at their own pace.

By adding behavior major versions (BMV) to the Rust SDK, we will make it possible to ship new secure/recommended defaults to new customers without impacting legacy customers.

The fundamental issue stems around our inability to communicate and decouple releases of service updates and behavior within a single major version.

Both legacy and new SDKs have the need to alter their SDKs default. Historically, this caused new customers on legacy SDKs to be subject to legacy defaults, even when a better alternative existed.

For new SDKs, a GA cutline presents difficult choices around timeline and features that can’t be added later without altering behavior.

Both of these use cases are addressed by Behavior Major Versions.

Terminology

  • Some Term: A definition for that term

The user experience if this RFC is implemented

In the current version of the SDK, users can construct clients without indicating any sort of behavior major version. Once this RFC is implemented, there will be three ways to set a behavior major version:

  1. In code via aws_config::from_env_with_version(BehaviorMajorVersion::latest()) and <service>::Config::builder().behavior_major_version(...)
  2. By enabling behavior-version-latest in either aws-config (which brings back from_env) OR a specific generated SDK crate
# Cargo.toml
[dependencies]
aws-config = { version = "1", features = ["behavior-version-latest"] }
# OR
aws-sdk-s3 = { version = "1", features = ["behavior-version-latest"] }

If no BehaviorMajorVersion is set, the client will panic during construction.

BehaviorMajorVersion is an opaque struct with initializers like ::latest(), ::v1(). Downstream code can check the version by calling methods like ::supports_v1()

When new BMV are added, the previous version constructor will be marked as deprecated. This serves as a mechanism to alert customers that a new BMV exists to allow them to upgrade.

How to actually implement this RFC

In order to implement this feature, we need to create a BehaviorMajorVersion struct, add config options to SdkConfig and aws-config, and wire it throughout the stack.

/// Behavior major-version of the client
///
/// Over time, new best-practice behaviors are introduced. However, these behaviors might not be backwards
/// compatible. For example, a change which introduces new default timeouts or a new retry-mode for
/// all operations might be the ideal behavior but could break existing applications.
#[derive(Debug, Clone)]
pub struct BehaviorMajorVersion {
    // currently there is only 1 MV so we don't actually need anything in here.
}

We also will add BehaviorVersionLatestRuntimePlugin, a runtime plugin that is enabled when the behavior-version-latest feature is enabled in runtime crates.

To help customers migrate, we are including from_env hooks that set behavior-version-latest that are deprecated. This allows customers to see that they are missing the required cargo feature and add it to remove the deprecation warning.

Design Alternatives Considered

An original design was also considered that made BMV optional and relied on documentation to steer customers in the right direction. This was deemed too weak of a mechanism to ensure that customers aren't broken by unexpected changes.

Changes checklist

  • Create BehaviorMajorVersion and the BMV runtime plugin
  • Add BMV as a required runtime component
  • Wire up setters throughout the stack
  • Add tests of BMV (set via aws-config, cargo features & code params)
  • Remove aws_config::from_env deprecation stand-ins