open-feature / open-feature/rust-sdk
Proposal: synchronous (non-blocking) flag evaluation API alongside the async one
- Dominant language
- Rust
- Stars
- 51
- Forks
- 13
- Avg merge
- 3d 24m
- Merged PRs (30d)
- 3
Description
# Summary
The Rust SDK currently exposes an async-only evaluation API: every `Client::get_*_value`/`get_*_details` method and every `FeatureProvider::resolve_*` method is `async`. This proposal asks for a complementary synchronous evaluation path for providers whose resolution is purely in-memory, without removing or changing the existing async API.
# Motivation
Our backend servers resolve flags from a local, periodically refreshed in-memory cache (with state polled from S3 in a background task,). For such providers, evaluation itself performs no I/O , yet the async-only API still forces us to set`.await` through dozens of unrelated functions, even though the underlying evaluation is a hash-map lookup.
The Java SDK also provides a sync-first API (`client.getBooleanValue(...)`)
# Spec compliance
[Requirement 1.4.12](https://openfeature.dev/specification/sections/flag-evaluation#requirement-1412)
states:
> The client **SHOULD** provide asynchronous **or non-blocking** mechanisms for flag evaluation.
This is a `SHOULD`, not a `MUST`.
# Design sketch (for discussion)
1. `SyncFeatureProvider` trait: same surface as `FeatureProvider` but with plain `fn resolve_*_value(...) -> EvaluationResult>` methods. Intended for providers backed by local state (files, env vars, in-memory caches).
2. Sync accessors on `Client` (e.g. `get_bool_value_sync(...) -> EvaluationResult`): available when the bound provider implements `SyncFeatureProvider`;
3. Sync-safe internal state for the sync path: the sync accessors must not go through `tokio::sync::RwLock::blocking_*`. Options include a
`std::sync::RwLock`/`arc-swap`-style snapshot for provider registration.
Open questions:
- Should this live behind a cargo feature (e.g. `sync`) to keep the default dependency footprint unchanged?
If the maintainers are open to this direction, I'm happy to work on a PR implementing the agreed design.
Contributor guide
Research direction
Start by reading the existing Client::get_*_value/get_*_details and FeatureProvider::resolve_* entry points, then inspect how tokio::sync::RwLock is used for provider state. Done means maintainers agree on the sync trait, Client accessors, state strategy, and cargo-feature decision while preserving the async API.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- api, backend
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Needs clarification
- Newbie friendliness
- 35/100