private async Task Receive()
            {
                var call = await _callTask.ConfigureAwait(false);

                try {
                    await foreach (var response in call.ResponseStream.ReadAllAsync(_cancellationToken)
                                   .ConfigureAwait(false))
                    {
                        if (!_pendingRequests.TryRemove(Uuid.FromDto(response.CorrelationId), out var writeResult))
                        {
                            continue;                             // TODO: Log?
                        }

                        try {
                            writeResult.TrySetResult(response.ToWriteResult());
                        } catch (Exception ex) when(ex is not RpcException)
                        {
                            writeResult.TrySetException(ex);
                        }
                    }
                } catch (Exception ex) {
                    _onException(ex);
                    foreach (var(_, source) in _pendingRequests)
                    {
                        source.TrySetException(ex);
                    }
                }
            }
        private static ClusterMessages.ClusterInfo ConvertGrpcClusterInfo(Gossip.ClusterInfo clusterInfo)
        {
            var receivedMembers = Array.ConvertAll(clusterInfo.Members.ToArray(), x =>
                                                   new ClusterMessages.MemberInfo {
                InstanceId          = Uuid.FromDto(x.InstanceId).ToGuid(),
                State               = (ClusterMessages.VNodeState)x.State,
                IsAlive             = x.IsAlive,
                HttpEndPointAddress = x.HttpEndPoint.Address,
                HttpEndPointPort    = (int)x.HttpEndPoint.Port
            });

            return(new ClusterMessages.ClusterInfo {
                Members = receivedMembers
            });
        }
예제 #3
0
        private async Task Subscribe()
        {
            try {
                while (await _call !.ResponseStream.MoveNext().ConfigureAwait(false) &&
                       !_disposed.IsCancellationRequested)
                {
                    var current = _call !.ResponseStream.Current;
                    switch (current.ContentCase)
                    {
                    case ReadResp.ContentOneofCase.Event:
                        try {
                            await _eventAppeared(this, ConvertToResolvedEvent(current),
                                                 current.Event.CountCase switch {
                                ReadResp.Types.ReadEvent.CountOneofCase.RetryCount => current.Event.RetryCount,
                                _ => default
                            }, _disposed.Token).ConfigureAwait(false);

                            if (_autoAck)
                            {
                                await AckInternal(Uuid.FromDto(current.Event.Link?.Id ?? current.Event.Event.Id))
                                .ConfigureAwait(false);
                            }
                        } catch (Exception ex) when(ex is ObjectDisposedException ||
                                                    ex is OperationCanceledException)
                        {
                            SubscriptionDropped(SubscriptionDroppedReason.Disposed);
                            return;
                        } catch (Exception ex) {
                            try {
                                SubscriptionDropped(SubscriptionDroppedReason.SubscriberError, ex);
                            } finally {
                                _disposed.Cancel();
                            }

                            return;
                        }

                        break;
                    }
예제 #4
0
        public async ValueTask <ClusterMessages.ClusterInfo> GetAsync(EndPoint endPoint,
                                                                      CancellationToken cancellationToken = default)
        {
            if (Interlocked.CompareExchange(ref _disposed, 0, 0) != 0)
            {
                throw new ObjectDisposedException(GetType().ToString());
            }

            var channel = _channels.GetOrAdd(endPoint, endpoint => ChannelFactory.CreateChannel(_settings, endpoint));

            var client = new Gossip.Gossip.GossipClient(channel);

            var result = await client.ReadAsync(new Empty(), cancellationToken : cancellationToken);

            return(new ClusterMessages.ClusterInfo {
                Members = result.Members.Select(x =>
                                                new ClusterMessages.MemberInfo {
                    InstanceId = Uuid.FromDto(x.InstanceId).ToGuid(),
                    State = (ClusterMessages.VNodeState)x.State,
                    IsAlive = x.IsAlive,
                    EndPoint = new DnsEndPoint(x.HttpEndPoint.Address, (int)x.HttpEndPoint.Port)
                }).ToArray()
            });
        }