예제 #1
0
    public static Channel <T> WithByteSerializer <T>(
        this Channel <ReadOnlyMemory <byte> > downstreamChannel,
        IByteSerializer <T> serializer,
        BoundedChannelOptions?channelOptions = null,
        CancellationToken cancellationToken  = default)
    {
        channelOptions ??= new BoundedChannelOptions(16)
        {
            FullMode     = BoundedChannelFullMode.Wait,
            SingleReader = true,
            SingleWriter = true,
            AllowSynchronousContinuations = true,
        };
        var pair = ChannelPair.CreateTwisted(
            Channel.CreateBounded <T>(channelOptions),
            Channel.CreateBounded <T>(channelOptions));

        downstreamChannel.Connect(pair.Channel1,
                                  serializer.Read,
                                  Write,
                                  ChannelCompletionMode.Full,
                                  cancellationToken);
        return(pair.Channel2);

        ReadOnlyMemory <byte> Write(T value)
        {
            using var bufferWriter = serializer.Write(value);
            return(bufferWriter.WrittenMemory.ToArray());
        }
    }
예제 #2
0
        public async Task ConnectTest2()
        {
            var options = new BoundedChannelOptions(1)
            {
                AllowSynchronousContinuations = true,
            };
            var cp1 = ChannelPair.CreateTwisted(
                Channel.CreateBounded <int>(options),
                Channel.CreateBounded <int>(options));
            var cp2 = ChannelPair.CreateTwisted(
                Channel.CreateBounded <int>(options),
                Channel.CreateBounded <int>(options));
            var _ = cp1.Channel2.ConnectAsync(cp2.Channel1,
                                              m => {
                Out.WriteLine($"-> {m}");
                return(m);
            },
                                              m => {
                Out.WriteLine($"<- {m}");
                return(m);
            }
                                              );

            await PassThroughTest(cp1.Channel1, cp2.Channel2);
            await PassThroughTest(cp2.Channel2, cp1.Channel1);
        }
예제 #3
0
        public async Task TwistedPairTest()
        {
            var options = new BoundedChannelOptions(1)
            {
                AllowSynchronousContinuations = true,
            };
            var cp = ChannelPair.CreateTwisted(
                Channel.CreateBounded <int>(options),
                Channel.CreateBounded <int>(options));

            await PassThroughTest(cp.Channel1, cp.Channel2);
            await PassThroughTest(cp.Channel2, cp.Channel1);
        }
예제 #4
0
        public async Task ConnectTest1()
        {
            var options = new BoundedChannelOptions(1)
            {
                AllowSynchronousContinuations = true,
            };
            var cp1 = ChannelPair.CreateTwisted(
                Channel.CreateBounded <int>(options),
                Channel.CreateBounded <int>(options));
            var cp2 = ChannelPair.CreateTwisted(
                Channel.CreateBounded <int>(options),
                Channel.CreateBounded <int>(options));
            var _ = cp1.Channel2.ConnectAsync(cp2.Channel1, ChannelCompletionMode.CompleteAndPropagateError);

            await PassThroughTest(cp1.Channel1, cp2.Channel2);
            await PassThroughTest(cp2.Channel2, cp1.Channel1);
        }
예제 #5
0
    public static Channel <T> WithLogger <T>(
        this Channel <T> channel,
        string channelName,
        ILogger logger, LogLevel logLevel, int?maxLength = null,
        BoundedChannelOptions?channelOptions             = null,
        CancellationToken cancellationToken = default)
    {
        var mustLog = logLevel != LogLevel.None && logger.IsEnabled(logLevel);

        if (!mustLog)
        {
            return(channel);
        }

        channelOptions ??= new BoundedChannelOptions(16)
        {
            FullMode     = BoundedChannelFullMode.Wait,
            SingleReader = true,
            SingleWriter = true,
            AllowSynchronousContinuations = true,
        };
        var pair = ChannelPair.CreateTwisted(
            Channel.CreateBounded <T>(channelOptions),
            Channel.CreateBounded <T>(channelOptions));

        T LogMessage(T message, bool isIncoming)
        {
            var text = message?.ToString() ?? "<null>";

            if (maxLength.HasValue && text.Length > maxLength.GetValueOrDefault())
            {
                text = text.Substring(0, maxLength.GetValueOrDefault()) + "...";
            }
            logger.Log(logLevel, $"{channelName} {(isIncoming ? "<-" : "->")} {text}");
            return(message);
        }

        channel.Connect(pair.Channel1,
                        m => LogMessage(m, true),
                        m => LogMessage(m, false),
                        ChannelCompletionMode.Full,
                        cancellationToken);
        return(pair.Channel2);
    }
예제 #6
0
    public TestChannelPair(string name, ITestOutputHelper? @out = null, int capacity = 16)
    {
        Name = name;
        Out  = @out;
        var options = new BoundedChannelOptions(capacity)
        {
            FullMode = BoundedChannelFullMode.Wait,
            AllowSynchronousContinuations = true,
            SingleReader = false,
            SingleWriter = false,
        };

        if (Out == null)
        {
            var cp = ChannelPair.CreateTwisted(
                Channel.CreateBounded <T>(options),
                Channel.CreateBounded <T>(options));
            Channel1 = cp.Channel1;
            Channel2 = cp.Channel2;
        }
        else
        {
            var cp1 = ChannelPair.CreateTwisted(
                Channel.CreateBounded <T>(options),
                Channel.CreateBounded <T>(options));
            var cp2 = ChannelPair.CreateTwisted(
                Channel.CreateBounded <T>(options),
                Channel.CreateBounded <T>(options));
            _ = cp1.Channel2.Connect(cp2.Channel1,
                                     m => {
                Out.WriteLine($"{Name}.Channel1 -> {m}");
                return(m);
            },
                                     m => {
                Out.WriteLine($"{Name}.Channel2 -> {m}");
                return(m);
            },
                                     ChannelCompletionMode.Full
                                     );
            Channel1 = cp1.Channel1;
            Channel2 = cp2.Channel2;
        }
    }
예제 #7
0
    public static Channel <T> WithTextSerializer <T>(
        this Channel <string> downstreamChannel,
        ITextSerializer <T> serializer,
        BoundedChannelOptions?channelOptions = null,
        CancellationToken cancellationToken  = default)
    {
        channelOptions ??= new BoundedChannelOptions(16)
        {
            FullMode     = BoundedChannelFullMode.Wait,
            SingleReader = true,
            SingleWriter = true,
            AllowSynchronousContinuations = true,
        };
        var pair = ChannelPair.CreateTwisted(
            Channel.CreateBounded <T>(channelOptions),
            Channel.CreateBounded <T>(channelOptions));

        downstreamChannel.Connect(pair.Channel1,
                                  serializer.Read,
                                  serializer.Write,
                                  ChannelCompletionMode.Full,
                                  cancellationToken);
        return(pair.Channel2);
    }