open-feature / open-feature/rust-sdk

Proposal: synchronous (non-blocking) flag evaluation API alongside the async one

Open
#141 0 comments 0 reactions 0 assignees View on GitHub
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

Open the contributing 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.