using Shouldly; using ZB.MOM.NatsNet.Server; using ZB.MOM.NatsNet.Server.Internal; namespace ZB.MOM.NatsNet.Server.Tests.ImplBacklog; public sealed partial class ConcurrencyTests1 { [Fact] // T:2469 public async Task NoRaceRoutePoolAndPerAccountConfigReload_ShouldSucceed() { var (server, err) = NatsServer.NewServer(new ServerOptions()); err.ShouldBeNull(); server.ShouldNotBeNull(); var logger = new ConcurrencyCaptureLogger(); server!.SetLogger(logger, false, false); var cts = new CancellationTokenSource(TimeSpan.FromSeconds(1)); var publishTask = Task.Run(async () => { while (!cts.Token.IsCancellationRequested) { server.RateLimitWarnf("route pool update for account {0}", "A"); await Task.Delay(1, cts.Token); } }, cts.Token); var reloadTask = Task.Run(async () => { while (!cts.Token.IsCancellationRequested) { var opts = server.GetOpts(); opts.Cluster.PoolSize = opts.Cluster.PoolSize == 2 ? 3 : 2; opts.Cluster.PinnedAccounts = opts.Cluster.PoolSize == 2 ? ["A"] : ["A", "B"]; server.SetOpts(opts); await Task.Delay(1, cts.Token); } }, cts.Token); await Task.WhenAll( publishTask.ContinueWith(_ => { }, TaskScheduler.Default), reloadTask.ContinueWith(_ => { }, TaskScheduler.Default)); server.GetOpts().Cluster.PoolSize.ShouldBeOneOf(2, 3); } private sealed class ConcurrencyCaptureLogger : INatsLogger { public void Noticef(string format, params object[] args) { } public void Warnf(string format, params object[] args) { } public void Fatalf(string format, params object[] args) { } public void Errorf(string format, params object[] args) { } public void Debugf(string format, params object[] args) { } public void Tracef(string format, params object[] args) { } } }