Skip to content

TieredProviderSelector TQuery,TResult

NexusLabs.Needlr.AgentFramework

NexusLabs.Needlr.AgentFramework.Providers

TieredProviderSelector<TQuery,TResult> Class

Default ITieredProviderSelector<TQuery,TResult> that iterates providers in ascending Priority order, gated by an IQuotaGate. Exception handling is configurable via FailurePolicies; the default options (Default) preserve the framework's historical behaviour of falling through to the next provider on ProviderUnavailableException.

public sealed class TieredProviderSelector<TQuery,TResult> : NexusLabs.Needlr.AgentFramework.Providers.ITieredProviderSelector<TQuery, TResult>

Type parameters

TQuery

TResult

Inheritance System.Object 🡒 TieredProviderSelector\<TQuery,TResult>

Implements NexusLabs.Needlr.AgentFramework.Providers.ITieredProviderSelector<TQuery,TResult>

Remarks

The quota partition key is resolved from the ambient IAgentExecutionContextAccessor using a QuotaPartitionSelector(IAgentExecutionContext). By default, UserId is used as the partition. Consumers that need a different partitioning strategy (e.g., tenant ID, API key) can provide a custom QuotaPartitionSelector(IAgentExecutionContext) via the constructor.

When no execution context is active (e.g., during integration tests that don't establish a scope), the partition is null and quota is global.

Failure policies and skip cache. When a provider throws, FailurePolicies are evaluated in order against the thrown exception (first match wins). A matching policy causes the selector to fall through to the next provider; if the policy specifies a SkipDuration, an entry is added to a per-instance in-memory skip cache so subsequent calls bypass the failing provider until the skip-until timestamp elapses. The cache is a thread-safe System.Collections.Concurrent.ConcurrentDictionary<> keyed by provider name. Skip state is per-selector-instance and lives only in the host process; it is not persisted.

Quota release. Quota release happens in a single finally block so it runs on the success path, on a matched-policy fall-through, on an unmatched-exception re-throw, and even when a OnHit callback throws. The release records succeeded: true only when the provider returned a value.

Cancellation. When the active System.Threading.CancellationToken is cancelled, the selector skips policy evaluation entirely and propagates the System.OperationCanceledException directly. Cancelled calls do not apply skip mode and do not fall through to the next provider.

Constructors

TieredProviderSelector(IEnumerable<ITieredProvider<TQuery,TResult>>, IQuotaGate, IAgentExecutionContextAccessor, QuotaPartitionSelector, TieredProviderSelectorOptions, TimeProvider) Constructor

public TieredProviderSelector(System.Collections.Generic.IEnumerable<NexusLabs.Needlr.AgentFramework.Providers.ITieredProvider<TQuery,TResult>> providers, NexusLabs.Needlr.AgentFramework.Providers.IQuotaGate quotaGate, NexusLabs.Needlr.AgentFramework.Context.IAgentExecutionContextAccessor contextAccessor, NexusLabs.Needlr.AgentFramework.Providers.QuotaPartitionSelector? partitionSelector=null, NexusLabs.Needlr.AgentFramework.Providers.TieredProviderSelectorOptions? options=null, System.TimeProvider? timeProvider=null);

Parameters

providers System.Collections.Generic.IEnumerable<NexusLabs.Needlr.AgentFramework.Providers.ITieredProvider<TQuery,TResult>>

All registered providers (filtering and ordering is handled internally).

quotaGate IQuotaGate

Quota gate for reservation/release. Use AlwaysGrantQuotaGate for no-op.

contextAccessor IAgentExecutionContextAccessor

Accessor for ambient execution context (provides partition identity).

partitionSelector QuotaPartitionSelector(IAgentExecutionContext)

Custom partition selector. Defaults to DefaultPartitionSelector (UserId).

options TieredProviderSelectorOptions

Failure-handling policy configuration. Defaults to Default, which falls through on ProviderUnavailableException with no skip and no callback.

timeProvider System.TimeProvider

Time source used for skip-cache "now" comparisons. Defaults to System.TimeProvider.System. Inject a fake time provider in tests to drive deterministic skip-mode behaviour.

Fields

TieredProviderSelector<TQuery,TResult>.DefaultPartitionSelector Field

The default partition selector: uses UserId from the ambient context.

public static readonly QuotaPartitionSelector DefaultPartitionSelector;

Field Value

QuotaPartitionSelector(IAgentExecutionContext)

Methods

TieredProviderSelector<TQuery,TResult>.ExecuteAsync(TQuery, CancellationToken) Method

Executes the query against providers in priority order until one succeeds.

public System.Threading.Tasks.Task<TResult> ExecuteAsync(TQuery query, System.Threading.CancellationToken cancellationToken);

Parameters

query TQuery

cancellationToken System.Threading.CancellationToken

Implements ExecuteAsync(TQuery, CancellationToken)

Returns

System.Threading.Tasks.Task<TResult>

Exceptions

NoProvidersRegisteredException
No enabled providers were registered, so there was nothing to attempt.

AllProvidersFailedException
At least one provider was registered, but every provider failed or was denied by the quota gate.

Remarks

Both exceptions inherit from NoProvidersAvailableException, so callers can catch that base type to handle both conditions uniformly.