Пример #1
0
        public async Task ListenAndBuffer()
        {
            const int sec = 1000; // Delays counted in ms

            try
            {
                var request = new TransactionNotificationsRequest();
                using (var stream = _client.TransactionNotifications(request, cancellationToken: _cancelToken))
                {
                    var responses = stream.ResponseStream;

                    while (!_cancelToken.IsCancellationRequested)
                    {
                        var respTask = responses.MoveNext();

                        // If no notifications are received in the next minute, use a ping
                        // (with a 3s pong timeout) to check that connection is still active.
                        while (respTask != await Task.WhenAny(respTask, Task.Delay(60 * sec)))
                        {
                            var pingCall = _client.PingAsync(new PingRequest());
                            var pingTask = pingCall.ResponseAsync;

                            var finishedTask = await Task.WhenAny(respTask, pingTask, Task.Delay(3 * sec));

                            if (finishedTask == respTask)
                            {
                                break;
                            }
                            else if (finishedTask == pingTask)
                            {
                                continue;
                            }
                            else
                            {
                                throw new TimeoutException("Timeout listening for transaction notification");
                            }
                        }

                        // Check whether the stream was ended cleany by the server.  Accessing this
                        // result will throw a RpcException with the Unavailable status code if
                        // the task instead ended due to losing the connection.
                        if (!respTask.Result)
                        {
                            break;
                        }

                        // Marshal the notification and append to the buffer.
                        var n = responses.Current;
                        var detachedBlocks      = n.DetachedBlocks.Select(hash => new Sha256Hash(hash.ToByteArray())).ToHashSet();
                        var attachedBlocks      = n.AttachedBlocks.Select(MarshalBlock).ToList();
                        var unminedTransactions = n.UnminedTransactions.Select(MarshalWalletTransaction).ToList();
                        var unminedHashes       = n.UnminedTransactionHashes.Select(hash => new Sha256Hash(hash.ToByteArray())).ToHashSet();

                        var changes = new WalletChanges(detachedBlocks, attachedBlocks, unminedTransactions, unminedHashes);
                        _buffer.Post(changes);
                    }
                }

                _buffer.Complete();
            }
            catch (TaskCanceledException)
            {
                _buffer.Complete();
            }
            catch (RpcException ex) when(ex.Status.StatusCode == StatusCode.Cancelled)
            {
                _buffer.Complete();
            }
            catch (Exception ex)
            {
                var block = (IDataflowBlock)_buffer;
                block.Fault(ex);
            }
        }
Пример #2
0
        public async Task ListenAndBuffer()
        {
            const int sec = 1000; // Delays counted in ms

            try
            {
                var request = new TransactionNotificationsRequest();
                using (var stream = _client.TransactionNotifications(request, cancellationToken: _cancelToken))
                {
                    var responses = stream.ResponseStream;

                    while (!_cancelToken.IsCancellationRequested)
                    {
                        var respTask = responses.MoveNext();

                        // If no notifications are received in the next minute, use a ping
                        // (with a 3s pong timeout) to check that connection is still active.
                        while (respTask != await Task.WhenAny(respTask, Task.Delay(60 * sec)))
                        {
                            var pingCall = _client.PingAsync(new PingRequest());
                            var pingTask = pingCall.ResponseAsync;

                            var finishedTask = await Task.WhenAny(respTask, pingTask, Task.Delay(3 * sec));
                            if (finishedTask == respTask)
                                break;
                            else if (finishedTask == pingTask)
                                continue;
                            else
                                throw new TimeoutException("Timeout listening for transaction notification");
                        }

                        // Check whether the stream was ended cleany by the server.  Accessing this
                        // result will throw a RpcException with the Unavailable status code if
                        // the task instead ended due to losing the connection.
                        if (!respTask.Result)
                            break;

                        // Marshal the notification and append to the buffer.
                        var n = responses.Current;
                        var detachedBlocks = n.DetachedBlocks.Select(hash => new Blake256Hash(hash.ToByteArray())).ToHashSet();
                        var attachedBlocks = n.AttachedBlocks.Select(MarshalBlock).ToList();
                        var unminedTransactions = n.UnminedTransactions.Select(MarshalWalletTransaction).ToList();
                        var unminedHashes = n.UnminedTransactionHashes.Select(hash => new Blake256Hash(hash.ToByteArray())).ToHashSet();

                        var changes = new WalletChanges(detachedBlocks, attachedBlocks, unminedTransactions, unminedHashes);
                        _buffer.Post(changes);
                    }
                }

                _buffer.Complete();
            }
            catch (TaskCanceledException)
            {
                _buffer.Complete();
            }
            catch (RpcException ex) when (ex.Status.StatusCode == StatusCode.Cancelled)
            {
                _buffer.Complete();
            }
            catch (Exception ex)
            {
                var block = (IDataflowBlock)_buffer;
                block.Fault(ex);
            }
        }