feat(shipping): delay international shipments via shippingSlowdown feature flag#3354
feat(shipping): delay international shipments via shippingSlowdown feature flag#3354tlee768 wants to merge 29 commits into
Conversation
…wn feature flag Closes open-telemetry#346 Assisted-by: This contribution was prepared with the assistance of an AI development tool.
Assisted-by: This contribution was prepared with the assistance of an AI development tool.
… slowdown duration Assisted-by: This contribution was prepared with the assistance of an AI development tool.
… slowdown duration Assisted-by: This contribution was prepared with the assistance of an AI development tool.
…ependency to compose Assisted-by: This contribution was prepared with the assistance of an AI development tool.
Assisted-by: This contribution was prepared with the assistance of an AI development tool.
Assisted-by: This contribution was prepared with the assistance of an AI development tool.
Assisted-by: This contribution was prepared with the assistance of an AI development tool.
Assisted-by: This contribution was prepared with the assistance of an AI development tool.
Assisted-by: This contribution was prepared with the assistance of an AI development tool.
…w OTel API Assisted-by: This contribution was prepared with the assistance of an AI development tool.
Assisted-by: This contribution was prepared with the assistance of an AI development tool.
Assisted-by: This contribution was prepared with the assistance of an AI development tool.
Assisted-by: This contribution was prepared with the assistance of an AI development tool.
|
|
3e754f0 to
9afc649
Compare
awc::Client is !Send + !Sync (uses Rc internally), so it cannot be stored in a struct captured by the Send + Sync FlagChecker closure. Instead, store one Client per actix worker thread using thread_local!, initialized lazily on first use. Cloning the Client is cheap (bumps an Rc, not the pool). Assisted-by: This contribution was prepared with the assistance of an AI development tool.
The #[instrument] span was never bridged to OTel since tracing-opentelemetry is not wired up, so the span and its fields were silently dropped. Assisted-by: This contribution was prepared with the assistance of an AI development tool.
Assisted-by: This contribution was prepared with the assistance of an AI development tool.
9feecdc to
82945d7
Compare
|
@tlee768 thanks for the contribution, can you please fix the markdownlint errors:
|
Replace closure-based FlagChecker type alias with an enum that supports generic evaluate::<T>() calls, enabling non-bool flags in the future. Assisted-by: This contribution was prepared with the assistance of an AI development tool.
…r methods Assisted-by: This contribution was prepared with the assistance of an AI development tool.
There was a problem hiding this comment.
Pull request overview
Adds a new shippingSlowdown feature flag (default off) to the Rust Shipping service to introduce an artificial delay for international (non‑US) /ship-order requests when enabled, using flagd’s OFREP REST API and emitting tracing around evaluations.
Changes:
- Introduce a flagd OFREP client and a
FlagCheckerabstraction to evaluateshippingSlowdown(with a test mock path). - Apply a configurable slowdown delay in
ship_orderfor non‑US addresses when the flag is enabled, and add request-path tests. - Wire flagd dependency + env vars into docker compose files and add the flag definition to
demo.flagd.json.
Reviewed changes
Copilot reviewed 8 out of 8 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| src/shipping/src/shipping_service/feature_flag.rs | Adds a flagd OFREP HTTP client with OTel-instrumented requests and safe fallbacks. |
| src/shipping/src/shipping_service.rs | Adds FlagChecker, injects it + a slowdown duration into ship_order, and adds tests for US/international behavior. |
| src/shipping/src/main.rs | Registers FlagChecker and default slowdown duration into Actix app state. |
| src/shipping/README.md | Documents the new feature flag and related environment variables. |
| src/flagd/demo.flagd.json | Adds the shippingSlowdown flag definition (default variant off). |
| docker-compose.yml | Passes flagd OFREP env vars to shipping and adds flagd to depends_on. |
| docker-compose.minimal.yml | Same as full compose: env var pass-through and flagd dependency for shipping. |
| CHANGELOG.md | Notes the new shipping feature flag integration. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| name = "ShippingSlowdown", | ||
| message = "Delaying international shipment due to shippingSlowdown feature flag" | ||
| ); | ||
| actix_web::rt::time::sleep(**slowdown).await; |
There was a problem hiding this comment.
web::Data<T> wraps an Arc<T>, so Deref for web::Data<Duration> yields Arc<Duration>, not Duration directly. The double deref is correct:
*slowdown→Arc<Duration>(viaweb::Data::deref)**slowdown→Duration(viaArc::deref)
This compiles and works as intended.
| #[actix_web::test] | ||
| async fn test_ship_order_us_flag_on() { | ||
| let slowdown = std::time::Duration::from_millis(50); | ||
| let checker = FlagChecker::mock().with("shippingSlowdown", true); | ||
| let start = std::time::Instant::now(); | ||
| let order = call_ship_order(Some(make_address("US")), checker, slowdown).await; | ||
| assert!(start.elapsed() < slowdown); |
There was a problem hiding this comment.
The US path does no sleeping — it's just mock flag evaluation + tracking ID generation. 50ms is well above what actix's test harness takes to process a trivial request, so this shouldn't flake in practice. If it does, we can bump the slowdown duration, but I'd rather not add complexity (tokio time mocking, etc.) preemptively.
puckpuck
left a comment
There was a problem hiding this comment.
Hey @tlee768 thanks for this, and I really want this to happen as a feature flag for the demo. There is an official flagd provider for rust that we should use here instead of a custom client and enum to manage the feature flag evaluation.
There was a problem hiding this comment.
Why are we not using the open_feature_flagd provider for Rust instead of creating our own client here? https://docs.rs/open-feature-flagd/latest/open_feature_flagd/
…gd crate Use FlagdProvider from open-feature-flagd instead of a hand-rolled HTTP client, removing the FlagdClient wrapper and FlagChecker enum. The ship_order handler now takes dyn FeatureProvider directly, and tests use MockFeatureProvider from the open-feature crate. Assisted-by: This contribution was prepared with the assistance of an AI development tool.
Use the crate's default gRPC resolver (port 8013) instead of REST/OFREP (port 8016). Update docker-compose files to pass FLAGD_PORT instead of FLAGD_OFREP_PORT to the shipping service. Assisted-by: This contribution was prepared with the assistance of an AI development tool.
… up immediately The default RPC resolver wraps evaluations in an LRU cache with a 60s TTL, causing demo.flagd.json edits to be invisible until the cache expires. Setting cache_settings: None bypasses the cache and makes every evaluation a fresh gRPC unary call, matching the behaviour of the old OFREP client. Assisted-by: This contribution was prepared with the assistance of an AI development tool.
Narrow open-feature-flagd to the rpc feature only (drops reqwest, datalogic-rs, notify, semver, etc.). Remove manual FLAGD_HOST/PORT reads since FlagdOptions::default() already reads them from env. Assisted-by: This contribution was prepared with the assistance of an AI development tool.
Short-circuit the && so the gRPC call to flagd only happens when the address is outside the US. Assisted-by: This contribution was prepared with the assistance of an AI development tool.
44e8cde to
3501c1c
Compare
fb321e7 to
7b6b22e
Compare
|
Instead of a Doing this allows us to remove all DEFAULT_SLOWDOWN and the slowdown function parameter, since this is pulled from the featureflag itself now. If the flag doesn't exists we default it to 0 (no sleep). |
…lShippingSlowdown flag The flag value itself now carries the delay in seconds (default 0), removing the need for DEFAULT_SLOWDOWN and the injected duration parameter. Assisted-by: This contribution was prepared with the assistance of an AI development tool.
Done |
Summary
shippingSlowdownfeature flag (default off) that introduces a 10-second delay for non-US shipping requests when enabledFLAGD_HOSTandFLAGD_OFREP_PORTenv vars and flagd dependency to docker-composeCloses #346
Test plan
cargo testpasses insrc/shippingdocker compose upstarts shipping service with flagd dependencyshippingSlowdownflag is enabledAssisted-by: This contribution was prepared with the assistance of an AI development tool.