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()); } }
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); }
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); }
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); }
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); }
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); }
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; } }
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); }
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); }