You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
#1283 fixes a bug where a resource subscription whose subscriptions/listen stream ends (server teardown, revoked resource, dropped connection) leaves a stale internal entry, so a bare re-Subscribe no-ops. That PR clears the subscription silently so re-Subscribe re-opens it, with no new exported API.
Silent cleanup, though, gives the application no way to observe that a subscription ended or to react to it — reconnect with its own backoff, surface a UI state, stop retrying. Today a client gets no signal at all when a live subscription dies underneath it.
Proposed API
typeClientOptionsstruct {
// ...// ResourceSubscriptionEndedHandler is called (under SEP-2575) when the// subscriptions/listen stream backing a Subscribe ends for a reason other// than a client-initiated Unsubscribe or Close.ResourceSubscriptionEndedHandlerfunc(context.Context, *ResourceSubscriptionEndedRequest)
}
// ResourceSubscriptionEndedRequest describes a resource subscription whose// SEP-2575 subscriptions/listen stream has ended without a client-initiated// Unsubscribe or Close.typeResourceSubscriptionEndedRequeststruct {
URIstring// the resource whose subscription endedErrerror// the terminating error, or nil on a graceful listen resultGracefulbool// whether it ended with a normal result rather than an error
}
The SDK does not auto-resubscribe — a permanently revoked URI would hot-loop. The application owns retry/backoff and may call Subscribe again for the URI from within the handler. This is safe: the entry is cleared before the handler fires, and a per-subscription generation guard makes re-subscribe-from-callback (and an Unsubscribe→Subscribe race) well-defined.
Fires only for non-client-initiated ends; Unsubscribe and Close do not invoke it.
Cross-SDK context
The python and typescript SDKs already surface subscription-termination signals to callers (python raises on subscription loss / ends the async iteration; typescript reports a close reason distinguishing local vs graceful vs remote). This proposal gives Go clients an equivalent, idiomatic callback.
Process
This adds exported API (ResourceSubscriptionEndedHandler, ResourceSubscriptionEndedRequest), so per CONTRIBUTING it goes through the proposal process — filing ahead of a PR. A working implementation already exists (it was the original form of #1283, before the behavior fix was split out to land without new API); happy to open the PR once the shape is approved.
Related: #1283 (behavior-only fix, no new exported API).
Motivation
#1283 fixes a bug where a resource subscription whose
subscriptions/listenstream ends (server teardown, revoked resource, dropped connection) leaves a stale internal entry, so a bare re-Subscribeno-ops. That PR clears the subscription silently so re-Subscribere-opens it, with no new exported API.Silent cleanup, though, gives the application no way to observe that a subscription ended or to react to it — reconnect with its own backoff, surface a UI state, stop retrying. Today a client gets no signal at all when a live subscription dies underneath it.
Proposed API
Semantics
Subscribere-opens it.Subscribeagain for the URI from within the handler. This is safe: the entry is cleared before the handler fires, and a per-subscription generation guard makes re-subscribe-from-callback (and anUnsubscribe→Subscriberace) well-defined.UnsubscribeandClosedo not invoke it.Cross-SDK context
The python and typescript SDKs already surface subscription-termination signals to callers (python raises on subscription loss / ends the async iteration; typescript reports a close reason distinguishing local vs graceful vs remote). This proposal gives Go clients an equivalent, idiomatic callback.
Process
This adds exported API (
ResourceSubscriptionEndedHandler,ResourceSubscriptionEndedRequest), so per CONTRIBUTING it goes through the proposal process — filing ahead of a PR. A working implementation already exists (it was the original form of #1283, before the behavior fix was split out to land without new API); happy to open the PR once the shape is approved.Related: #1283 (behavior-only fix, no new exported API).