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);
            });
        }
示例#2
0
        /// <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);
            }
        }