コード例 #1
0
        public void PooledLineBuffer_Partial_Line_Double_With_NewLine()
        {
            var plb       = new PooledLineBuffer();
            var recvCount = 0;
            var errCount  = 0;
            var result    = string.Empty;

            var buf = GetBuffer("dead");

            plb.Receive(buf, buf.Length,
                        (src, dst, count) => Array.Copy(src, 0, dst, 0, count),
                        (x) => recvCount++, (ex) => errCount++);

            buf = GetBuffer("beef\n");

            plb.Receive(buf, buf.Length,
                        (src, dst, count) => Array.Copy(src, 0, dst, 0, count),
                        (x) =>
            {
                recvCount++;
                result = GetString(x);
            }, (ex) => errCount++);

            recvCount.Should().Be(1);
            errCount.Should().Be(0);
            result.Should().Be("deadbeef");
        }
コード例 #2
0
        public void PooledLineBuffer_Combo2()
        {
            var plb      = new PooledLineBuffer();
            var errCount = 0;
            var results  = new List <string>();

            var buf = GetBuffer("dead\nbeef");

            plb.Receive(buf, buf.Length,
                        (src, dst, count) => Array.Copy(src, 0, dst, 0, count),
                        (x) =>
            {
                results.Add(GetString(x));
            }, (ex) => errCount++);

            buf = GetBuffer("c0de\n");

            plb.Receive(buf, buf.Length,
                        (src, dst, count) => Array.Copy(src, 0, dst, 0, count),
                        (x) =>
            {
                results.Add(GetString(x));
            }, (ex) => errCount++);

            results.Count.Should().Be(2);
            errCount.Should().Be(0);
            results[0].Should().Be("dead");
            results[1].Should().Be("beefc0de");
        }
コード例 #3
0
        public void PooledLineBuffer_Partial_Enforce_Limits_Queued()
        {
            var plb       = new PooledLineBuffer(5);
            var recvCount = 0;
            var errCount  = 0;

            var buf = GetBuffer("dead");

            plb.Receive(buf, buf.Length,
                        (src, dst, count) => Array.Copy(src, 0, dst, 0, count),
                        (x) =>
            {
                recvCount++;
            }, (ex) => errCount++);

            recvCount.Should().Be(0);
            errCount.Should().Be(0);

            buf = GetBuffer("bee");

            plb.Receive(buf, buf.Length,
                        (src, dst, count) => Array.Copy(src, 0, dst, 0, count),
                        (x) =>
            {
                recvCount++;
            }, (ex) => errCount++);

            recvCount.Should().Be(0);
            errCount.Should().Be(1);
        }
コード例 #4
0
        public void PooledLineBuffer_Partial_Line_Double_With_NewLine_With_Leading_NewLines()
        {
            var plb       = new PooledLineBuffer(LogManager.CreateNullLogger());
            var recvCount = 0;
            var errCount  = 0;
            var result    = string.Empty;

            var buf = GetBuffer("\n\nabc");

            plb.Receive(buf, buf.Length,
                        (src, dst, count) => Array.Copy(src, 0, dst, 0, count),
                        (x) => recvCount++, (ex) => errCount++);

            buf = GetBuffer("def\n");

            plb.Receive(buf, buf.Length,
                        (src, dst, count) => Array.Copy(src, 0, dst, 0, count),
                        (x) =>
            {
                recvCount++;
                result = GetString(x);
            }, (ex) => errCount++);

            Assert.Equal(recvCount, 1);
            Assert.Equal(result, "abcdef");
            Assert.Equal(errCount, 0);
        }
コード例 #5
0
        public void PooledLineBuffer_Combo2()
        {
            var plb      = new PooledLineBuffer(LogManager.CreateNullLogger());
            var errCount = 0;
            var results  = new List <string>();

            var buf = GetBuffer("abc\ndef");

            plb.Receive(buf, buf.Length,
                        (src, dst, count) => Array.Copy(src, 0, dst, 0, count),
                        (x) =>
            {
                results.Add(GetString(x));
            }, (ex) => errCount++);

            buf = GetBuffer("ghi\n");

            plb.Receive(buf, buf.Length,
                        (src, dst, count) => Array.Copy(src, 0, dst, 0, count),
                        (x) =>
            {
                results.Add(GetString(x));
            }, (ex) => errCount++);

            Assert.Equal(results.Count, 2);
            Assert.Equal(results[0], "abc");
            Assert.Equal(results[1], "defghi");
            Assert.Equal(errCount, 0);
        }
コード例 #6
0
        public void PooledLineBuffer_Partial_Enforce_Limits_Queued()
        {
            var plb       = new PooledLineBuffer(LogManager.CreateNullLogger(), 5);
            var recvCount = 0;
            var errCount  = 0;

            var buf = GetBuffer("abcd");

            plb.Receive(buf, buf.Length,
                        (src, dst, count) => Array.Copy(src, 0, dst, 0, count),
                        (x) =>
            {
                recvCount++;
            }, (ex) => errCount++);

            Assert.Equal(recvCount, 0);
            Assert.Equal(errCount, 0);

            buf = GetBuffer("def");

            plb.Receive(buf, buf.Length,
                        (src, dst, count) => Array.Copy(src, 0, dst, 0, count),
                        (x) =>
            {
                recvCount++;
            }, (ex) => errCount++);

            Assert.Equal(recvCount, 0);
            Assert.Equal(errCount, 1);
        }
コード例 #7
0
        public void PooledLineBuffer_Partial_Line()
        {
            var plb       = new PooledLineBuffer();
            var recvCount = 0;
            var errCount  = 0;

            var buf = GetBuffer("deadbeef");

            plb.Receive(buf, buf.Length,
                        (src, dst, count) => Array.Copy(src, 0, dst, 0, count),
                        (x) => recvCount++, (ex) => errCount++);

            recvCount.Should().Be(0);
            errCount.Should().Be(0);
        }
コード例 #8
0
        public void PooledLineBuffer_Partial_Line()
        {
            var plb       = new PooledLineBuffer(LogManager.CreateNullLogger());
            var recvCount = 0;
            var errCount  = 0;

            var buf = GetBuffer("abc");

            plb.Receive(buf, buf.Length,
                        (src, dst, count) => Array.Copy(src, 0, dst, 0, count),
                        (x) => recvCount++, (ex) => errCount++);

            Assert.Equal(recvCount, 0);
            Assert.Equal(errCount, 0);
        }
コード例 #9
0
        public void PooledLineBuffer_Partial_Dont_Emit_Empty_Lines()
        {
            var plb       = new PooledLineBuffer();
            var recvCount = 0;
            var errCount  = 0;

            var buf = GetBuffer("\n\n\n");

            plb.Receive(buf, buf.Length,
                        (src, dst, count) => Array.Copy(src, 0, dst, 0, count),
                        (x) =>
            {
                recvCount++;
            }, (ex) => errCount++);

            recvCount.Should().Be(0);
            errCount.Should().Be(0);
        }
コード例 #10
0
        public void PooledLineBuffer_Single_Line()
        {
            var plb       = new PooledLineBuffer(LogManager.CreateNullLogger());
            var recvCount = 0;
            var errCount  = 0;
            var result    = string.Empty;

            var buf = GetBuffer("abc\n");

            plb.Receive(buf, buf.Length,
                        (src, dst, count) => Array.Copy(src, 0, dst, 0, count),
                        (x) =>
            {
                recvCount++;
                result = GetString(x);
            }, (ex) => errCount++);

            Assert.Equal(recvCount, 1);
            Assert.Equal(result, "abc");
            Assert.Equal(errCount, 0);
        }
コード例 #11
0
        public void PooledLineBuffer_Single_Character_Lines()
        {
            var plb      = new PooledLineBuffer();
            var errCount = 0;
            var results  = new List <string>();

            var buf = GetBuffer("a\n");

            plb.Receive(buf, buf.Length,
                        (src, dst, count) => Array.Copy(src, 0, dst, 0, count),
                        (x) =>
            {
                results.Add(GetString(x));
            }, (ex) => errCount++);

            buf = GetBuffer("b\n");

            plb.Receive(buf, buf.Length,
                        (src, dst, count) => Array.Copy(src, 0, dst, 0, count),
                        (x) =>
            {
                results.Add(GetString(x));
            }, (ex) => errCount++);

            buf = GetBuffer("c\n");

            plb.Receive(buf, buf.Length,
                        (src, dst, count) => Array.Copy(src, 0, dst, 0, count),
                        (x) =>
            {
                results.Add(GetString(x));
            }, (ex) => errCount++);

            results.Count.Should().Be(3);
            errCount.Should().Be(0);
            results[0].Should().Be("a");
            results[1].Should().Be("b");
            results[2].Should().Be("c");
        }
コード例 #12
0
        public void PooledLineBuffer_Single_Character_Lines()
        {
            var plb      = new PooledLineBuffer(LogManager.CreateNullLogger());
            var errCount = 0;
            var results  = new List <string>();

            var buf = GetBuffer("a\n");

            plb.Receive(buf, buf.Length,
                        (src, dst, count) => Array.Copy(src, 0, dst, 0, count),
                        (x) =>
            {
                results.Add(GetString(x));
            }, (ex) => errCount++);

            buf = GetBuffer("b\n");

            plb.Receive(buf, buf.Length,
                        (src, dst, count) => Array.Copy(src, 0, dst, 0, count),
                        (x) =>
            {
                results.Add(GetString(x));
            }, (ex) => errCount++);

            buf = GetBuffer("c\n");

            plb.Receive(buf, buf.Length,
                        (src, dst, count) => Array.Copy(src, 0, dst, 0, count),
                        (x) =>
            {
                results.Add(GetString(x));
            }, (ex) => errCount++);

            Assert.Equal(results.Count, 3);
            Assert.Equal(results[0], "a");
            Assert.Equal(results[1], "b");
            Assert.Equal(results[2], "c");
            Assert.Equal(errCount, 0);
        }
コード例 #13
0
        private IObservable <PooledArraySegment <byte> > WebsocketSubscribeEndpoint(DaemonEndpointConfig endPoint, int port, string method, object payload = null,
                                                                                    JsonSerializerSettings payloadJsonSerializerSettings = null)
        {
            return(Observable.Defer(() => Observable.Create <PooledArraySegment <byte> >(obs =>
            {
                var cts = new CancellationTokenSource();

                var thread = new Thread(async(_) =>
                {
                    using (cts)
                    {
                        while (!cts.IsCancellationRequested)
                        {
                            try
                            {
                                using (var plb = new PooledLineBuffer(logger))
                                {
                                    using (var client = new ClientWebSocket())
                                    {
                                        // connect
                                        var uri = new Uri($"ws://{endPoint.Host}:{port}");

                                        logger.Debug(() => $"Establishing WebSocket connection to {uri}");
                                        await client.ConnectAsync(uri, cts.Token);

                                        // subscribe
                                        var buf = ArrayPool <byte> .Shared.Rent(0x10000);

                                        try
                                        {
                                            var request = new JsonRpcRequest(method, payload, GetRequestId());
                                            var json = JsonConvert.SerializeObject(request, payloadJsonSerializerSettings).ToCharArray();
                                            var byteLength = Encoding.UTF8.GetBytes(json, 0, json.Length, buf, 0);
                                            var segment = new ArraySegment <byte>(buf, 0, byteLength);

                                            logger.Debug(() => $"Sending WebSocket subscription request to {uri}");
                                            await client.SendAsync(segment, WebSocketMessageType.Text, true, cts.Token);

                                            // stream response
                                            segment = new ArraySegment <byte>(buf);

                                            while (!cts.IsCancellationRequested && client.State == WebSocketState.Open)
                                            {
                                                var response = await client.ReceiveAsync(buf, cts.Token);

                                                if (response.MessageType == WebSocketMessageType.Binary)
                                                {
                                                    throw new InvalidDataException("expected text, received binary data");
                                                }

                                                plb.Receive(segment, response.Count,
                                                            (src, dst, count) => Array.Copy(src.Array, src.Offset, dst, 0, count),
                                                            obs.OnNext, (ex) => { }, response.EndOfMessage);
                                            }
                                        }

                                        finally
                                        {
                                            ArrayPool <byte> .Shared.Return(buf);
                                        }
                                    }
                                }
                            }

                            catch (Exception ex)
                            {
                                logger.Error(() => $"{ex.GetType().Name} '{ex.Message}' while streaming websocket responses. Reconnecting in 5s");
                            }

                            await Task.Delay(TimeSpan.FromSeconds(5), cts.Token);
                        }
                    }
                });

                thread.Start();

                return Disposable.Create(() =>
                {
                    cts.Cancel();
                });
            })));
        }
コード例 #14
0
 public StratumClient()
 {
     _logger           = Log.ForContext <StratumClient>().ForContext("Pool", "XMR");
     _pooledLineBuffer = new PooledLineBuffer(MaxInboundRequestLength);
 }
コード例 #15
0
        private void SetupConnection(Loop loop, Tcp tcp)
        {
            Contract.RequiresNonNull(tcp, nameof(tcp));

            // initialize send queue
            sendQueue                  = new ConcurrentQueue <PooledArraySegment <byte> >();
            sendQueueDrainer           = loop.CreateAsync(DrainSendQueue);
            sendQueueDrainer.UserToken = tcp;

            Received = Observable.Create <PooledArraySegment <byte> >(observer =>
            {
                var plb = new PooledLineBuffer(logger, MaxInboundRequestLength);

                tcp.OnRead((handle, buffer) =>
                {
                    // onAccept
                    using (buffer)
                    {
                        if (buffer.Count == 0 || !isAlive)
                        {
                            return;
                        }

                        plb.Receive(buffer, buffer.Count,
                                    (src, dst, count) => src.ReadBytes(dst, count),
                                    observer.OnNext,
                                    observer.OnError);
                    }
                }, (handle, ex) =>
                {
                    // onError
                    observer.OnError(ex);
                }, handle =>
                {
                    // onCompleted
                    isAlive = false;
                    observer.OnCompleted();

                    // release handles
                    sendQueueDrainer.UserToken = null;
                    sendQueueDrainer.Dispose();

                    // empty queues
                    while (sendQueue.TryDequeue(out var fragment))
                    {
                        fragment.Dispose();
                    }

                    plb.Dispose();

                    handle.CloseHandle();
                });

                return(Disposable.Create(() =>
                {
                    if (tcp.IsValid)
                    {
                        logger.Debug(() => $"[{ConnectionId}] Last subscriber disconnected from receiver stream");

                        isAlive = false;
                        tcp.Shutdown();
                    }
                }));
            })