コード例 #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 <ChannelPair?> GetOrCreateChannelPair(SocketGuild guild, string lang)
        {
            string safeLang      = GetSafeLangString(lang);
            string guildLang     = _serverConfig.GetLanguageForGuild(guild.Id);
            string safeGuildLang = GetSafeLangString(guildLang);

            if (_channelPairs.TryGetValue(safeLang, out var pair))
            {
                return(pair);
            }

            var category = guild.CategoryChannels.SingleOrDefault(a => a.Name == TranslationConstants.CategoryName);

            if (category == default)
            {
                throw new InvalidOperationException($"The channel category {TranslationConstants.CategoryName} does not exist");
            }

            var supportedLang = await _translation.IsLangSupported(lang);

            if (!supportedLang)
            {
                throw new LanguageNotSupportedException($"{lang} is not supported at this time.");
            }

            var fromLangName = $"{safeLang}-to-{safeGuildLang}";
            var toLangName   = $"{safeGuildLang}-to-{safeLang}";

            var fromLangChannel = await guild.CreateTextChannelAsync(fromLangName, p => p.CategoryId = category.Id);

            var toLangChannel = await guild.CreateTextChannelAsync(toLangName, p => p.CategoryId = category.Id);

            var localizedTopic = await _translation.GetTranslation(guildLang, lang, $"Responses will be translated to {guildLang} and posted in this channel's pair {toLangChannel.Mention}");

            await fromLangChannel.ModifyAsync(p => p.Topic = localizedTopic.Translated.Text);

            var unlocalizedTopic = $"Responses will be translated to {lang} and posted in this channel's pair {fromLangChannel.Mention}";
            await toLangChannel.ModifyAsync(p => p.Topic = unlocalizedTopic);

            pair = new ChannelPair
            {
                TranslationChannel = fromLangChannel,
                StandardLangChanel = toLangChannel
            };

            if (!_channelPairs.TryAdd(safeLang, pair))
            {
                _logger.LogWarning($"The channel pairs {{{fromLangName}, {toLangName}}} have already been tracked, cleaning up");
                await pair.TranslationChannel.DeleteAsync();

                await pair.StandardLangChanel.DeleteAsync();

                _channelPairs.TryGetValue(safeLang, out pair);
            }

            return(pair);
        }
コード例 #4
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);
        }
コード例 #5
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);
        }
コード例 #6
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);
    }
コード例 #7
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;
        }
    }
コード例 #8
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);
    }
コード例 #9
0
        private Task BuildChannelMap(SocketGuild guild)
        {
            var category = guild.CategoryChannels.SingleOrDefault(a => a.Name == TranslationConstants.CategoryName);

            if (category == null)
            {
                return(Task.CompletedTask);
            }

            _logger.LogDebug($"Guild available for {guild.Name}, rebuilding pair map");
            var tempChannels = category.Channels.OfType <ITextChannel>().Where(a => !TranslationConstants.PermanentChannels.Contains(a.Name)).ToList();

            if (tempChannels.Count == 0)
            {
                return(Task.CompletedTask);
            }

            var pairs = new Dictionary <string, ChannelPair>();

            var guildLang     = _serverConfig.GetLanguageForGuild(guild.Id);
            var safeGuildLang = GetSafeLangString(guildLang);

            foreach (var channel in tempChannels)
            {
                _logger.LogDebug($"Checking {channel.Name}");
                var lang = channel.GetLangFromChannelName(safeGuildLang);
                if (lang == null)
                {
                    _logger.LogDebug($"{channel.Name} is not a translation channel, skipping");
                    continue;
                }

                var safeLang = GetSafeLangString(lang);
                var isStandardLangChannel = channel.IsStandardLangChannel(safeGuildLang);
                _logger.LogDebug($"channel is the {safeGuildLang} lang channel? {isStandardLangChannel}");

                if (!pairs.TryGetValue(safeLang, out var pair))
                {
                    _logger.LogDebug("Creating new pair");
                    pair            = new ChannelPair();
                    pairs[safeLang] = pair;
                }

                if (isStandardLangChannel)
                {
                    pair.StandardLangChanel = channel;
                }
                else
                {
                    pair.TranslationChannel = channel;
                }
            }

            foreach (var pair in pairs.ToList())
            {
                if (pair.Value.StandardLangChanel == default || pair.Value.TranslationChannel == default)
                {
                    _logger.LogDebug($"Pair is missing either the language channel or the {safeGuildLang} channel, skipping");
                    continue;
                }

                _logger.LogDebug($"Addping pair for {pair.Key}");
                _channelPairs[pair.Key] = pair.Value;
            }
            _logger.LogDebug($"Completed rebuilding pair map");
            return(Task.CompletedTask);
        }