Skip to content

Add TrySubscribeOnce API in IDistributedApplicationEventing #9042

@mitchdenny

Description

@mitchdenny

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.

Metadata

Metadata

Labels

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions