Updated Design for TrySubscribeOnce API
This issue is to introduce idempotent subscription support to eventing, similar to TryAddLifecycleHook<T>, but for distributed application events.
Proposed API: TrySubscribeOnce
This API will provide both resource and non-resource variants, mirroring the existing Subscribe methods. The callback uses Func<T, CancellationToken, Task>, and the API is generic for event type consistency.
Non-resource event subscription
bool TrySubscribeOnce<T>(
object key,
Func<T, CancellationToken, Task> callback,
[NotNullWhen(true)] out DistributedApplicationEventSubscription? subscription
) where T : IDistributedApplicationEvent;
// Overload: uses the IDistributedApplicationEventing instance as the key
bool TrySubscribeOnce<T>(
Func<T, CancellationToken, Task> callback,
[NotNullWhen(true)] out DistributedApplicationEventSubscription? subscription
) where T : IDistributedApplicationEvent;
Resource-scoped event subscription
bool TrySubscribeOnce<T>(
IResource resource,
object key,
Func<T, CancellationToken, Task> callback,
[NotNullWhen(true)] out DistributedApplicationEventSubscription? subscription
) where T : IDistributedApplicationResourceEvent;
// Overload: uses the IDistributedApplicationEventing instance as the key
bool TrySubscribeOnce<T>(
IResource resource,
Func<T, CancellationToken, Task> callback,
[NotNullWhen(true)] out DistributedApplicationEventSubscription? subscription
) where T : IDistributedApplicationResourceEvent;
Behavior
- The
key can be any object. This enables idempotency per logical subscription and supports both arbitrary keys and the "type as key" lifecycle hook pattern.
- If a subscription with the key already exists, the call is a no-op, returns
false, and the out var is null.
- If a subscription is added, the call returns
true and the out var contains the subscription.
- The
[NotNullWhen(true)] attribute is used on the out parameter for better nullability analysis.
- Reusing a key is expected and safe; this is the purpose of the API.
- No migration or removal of lifecycle hook usage will be performed in this PR.
Rationale
- Mirrors the existing
Subscribe API (generic, resource/non-resource, async callback).
- Makes it easy to enforce "subscribe once" semantics.
- Flexible: supports both "type as key" and arbitrary key scenarios.
This issue description was updated to include the detailed API design and the use of [NotNullWhen(true)] for the out subscription parameter.
Updated Design for TrySubscribeOnce API
This issue is to introduce idempotent subscription support to eventing, similar to
TryAddLifecycleHook<T>, but for distributed application events.Proposed API:
TrySubscribeOnceThis API will provide both resource and non-resource variants, mirroring the existing
Subscribemethods. The callback usesFunc<T, CancellationToken, Task>, and the API is generic for event type consistency.Non-resource event subscription
Resource-scoped event subscription
Behavior
keycan be any object. This enables idempotency per logical subscription and supports both arbitrary keys and the "type as key" lifecycle hook pattern.false, and the out var isnull.trueand the out var contains the subscription.[NotNullWhen(true)]attribute is used on the out parameter for better nullability analysis.Rationale
SubscribeAPI (generic, resource/non-resource, async callback).This issue description was updated to include the detailed API design and the use of
[NotNullWhen(true)]for the out subscription parameter.