private void TryRegister(Connection connection) { if (!_listenerAddedConnection.CompareAndSet(null, connection)) { //already registering/registered to another connection return; } var clientMessage = ClientAddClusterViewListenerCodec.EncodeRequest(); void HandlePartitionsViewEvent(int version, ICollection <KeyValuePair <Guid, IList <int> > > partitions) => _partitionService.HandlePartitionsViewEvent(connection, partitions, version); void EventHandler(ClientMessage message) => ClientAddClusterViewListenerCodec.EventHandler.HandleEvent(message, HandleMembersViewEvent, HandlePartitionsViewEvent); IFuture <ClientMessage> future = _clientInvocationService.InvokeListenerOnConnection(clientMessage, EventHandler, connection); future.ToTask().ContinueWith(task => { if (!task.IsFaulted) { if (task.Result != null) { return; } } //completes with exception, listener needs to be re-registered TryReRegisterToRandomConnection(connection); }); }
/// <summary> /// Subscribes a connection to cluster events. /// </summary> /// <param name="connection">The connection.</param> /// <param name="correlationId">The correlation identifier.</param> /// <param name="cancellationToken">A cancellation token.</param> /// <returns>A task that will complete when the subscription has been processed, and represent whether it was successful.</returns> private async Task <bool> SubscribeToClusterEventsAsync(MemberConnection connection, long correlationId, CancellationToken cancellationToken) { // aka subscribe to member/partition view events HConsole.TraceLine(this, "subscribe"); // handles the event ValueTask HandleEventAsync(ClientMessage message, object _) => ClientAddClusterViewListenerCodec.HandleEventAsync(message, HandleCodecMemberViewEvent, HandleCodecPartitionViewEvent, connection.Id, _clusterState.LoggerFactory); try { var subscribeRequest = ClientAddClusterViewListenerCodec.EncodeRequest(); _correlatedSubscriptions[correlationId] = new ClusterSubscription(HandleEventAsync); _ = await _clusterMessaging.SendToMemberAsync(subscribeRequest, connection, correlationId, cancellationToken).CfAwait(); HConsole.WriteLine(this, "subscribed"); return(true); } catch (Exception e) { HConsole.WriteLine(this, "failed " + e); _correlatedSubscriptions.TryRemove(correlationId, out _); _logger.LogWarning(e, "Failed to subscribe to cluster events, may retry."); return(false); } }