// remove a subscription from one member private async ValueTask <bool> RemoveSubscriptionAsync(MemberSubscription subscription, CancellationToken cancellationToken) { // fast: if the connection is down, consider the subscription removed if (!subscription.Connection.Active) { return(true); } try { // remove the member subscription = trigger the server-side un-subscribe // this *may* throw if we fail to talk to the member // this *may* return false for some reason var unsubscribeRequest = subscription.ClusterSubscription.CreateUnsubscribeRequest(subscription.ServerSubscriptionId); var responseMessage = await _clusterMessaging.SendToMemberAsync(unsubscribeRequest, subscription.Connection, cancellationToken).CfAwait(); var removed = subscription.ClusterSubscription.ReadUnsubscribeResponse(responseMessage); return(removed); } catch (Exception e) { // if the connection is down, consider the subscription removed if (!subscription.Connection.Active) { return(true); } // otherwise something went wrong and maybe we want to try again _logger.LogError(e, "Caught an exception while unsubscribing to events."); return(false); } }
// add a member subscription to be collected, start the collect task if needed private void CollectSubscription(MemberSubscription subscription) { lock (_collectMutex) { _collectSubscriptions.Add(subscription); _collectTask ??= CollectSubscriptionsAsync(_cancel.Token); } }
/// <summary> /// Removes a subscription from one member. /// </summary> /// <param name="memberSubscription">The subscription.</param> /// <param name="cancellationToken">A cancellation token.</param> /// <returns>Whether the subscription was removed.</returns> /// <remarks> /// <para>This methods always remove the event handlers associated with the subscription, regardless /// of the response from the server. Even when the server returns false, meaning it failed to /// properly remove the subscription, no events for that subscription will be triggered anymore /// because the client will ignore these events when the server sends them.</para> /// </remarks> private async ValueTask <bool> RemoveMemberSubscriptionAsync(MemberSubscription memberSubscription, CancellationToken cancellationToken = default) { // always remove the correlated subscription _correlatedSubscriptions.TryRemove(memberSubscription.CorrelationId, out _); // trigger the server-side un-subscribe var unsubscribeRequest = memberSubscription.ClusterSubscription.CreateUnsubscribeRequest(memberSubscription.ServerSubscriptionId); var responseMessage = await _clusterMessaging.SendToMemberAsync(unsubscribeRequest, memberSubscription.Connection, cancellationToken).CfAwait(); var removed = memberSubscription.ClusterSubscription.ReadUnsubscribeResponse(responseMessage); return(removed); }
/// <summary> /// Removes a subscription from one member. /// </summary> /// <param name="memberSubscription">The subscription.</param> /// <param name="cancellationToken">A cancellation token.</param> /// <returns>Whether the subscription was removed.</returns> /// <remarks> /// <para>This methods always remove the event handlers associated with the subscription, regardless /// of the response from the server. Even when the server returns false, meaning it failed to /// properly remove the subscription, no events for that subscription will be triggered anymore /// because the client will ignore these events when the server sends them.</para> /// </remarks> private async ValueTask <bool> RemoveSubscriptionAsync(MemberSubscription memberSubscription, CancellationToken cancellationToken = default) { // whatever happens, remove the event handler // if the client hasn't properly unsubscribed, it may receive more event messages, // which will be ignored since their correlation identifier won't match any handler. _correlatedSubscriptions.TryRemove(memberSubscription.CorrelationId, out _); // trigger the server-side un-subscribe var unsubscribeRequest = memberSubscription.ClusterSubscription.CreateUnsubscribeRequest(memberSubscription.ServerSubscriptionId); var responseMessage = await _clusterMessaging.SendToMemberAsync(unsubscribeRequest, memberSubscription.Connection, cancellationToken).CAF(); return(memberSubscription.ClusterSubscription.ReadUnsubscribeResponse(responseMessage)); }