public async Task TestGrpc() { const int BINDING_PORT = 28888; var logger = loggerFactory.CreateLogger(nameof(TestGrpc)); var gossiperImpl = new GossiperImpl(); gossiperImpl.OnPull += (_, e) => { logger.LogInformation("OnPull"); e.Rumors = Enumerable.Empty <Rumor>(); }; gossiperImpl.OnPush += (_, e) => logger.LogInformation("Receive rumors: [{0}]", string.Join(", ", e.Rumors.Select(r => r.GetHashCode()))); var server = new Server { Ports = { new ServerPort("127.0.0.1", BINDING_PORT, ServerCredentials.Insecure) }, Services = { Gossiper.BindService(gossiperImpl) } }; server.Start(); var client = new Gossiper.GossiperClient(new Channel($"127.0.0.1:{BINDING_PORT}", ChannelCredentials.Insecure)); var pullResult = client.Pull(new PullRequest(), deadline: DateTime.UtcNow.AddMilliseconds(200)); while (await pullResult.ResponseStream.MoveNext()) { logger.LogInformation("Pulled rumor {0}", pullResult.ResponseStream.Current.GetHashCode()); } var pushCall = client.Push(deadline: DateTime.UtcNow.AddMilliseconds(200)); await pushCall.RequestStream.WriteAsync(new Rumor { Counter = 1, Payload = new Any() }); await pushCall.RequestStream.CompleteAsync(); var pushResult = await pushCall; logger.LogInformation("Client push finished"); await server.ShutdownAsync(); }
public async Task TestObservePullService() { const int BINDING_PORT = 38888; var logger = loggerFactory.CreateLogger(nameof(TestObserveService)); var options = Options.Create(new EpidemicBroadcastServiceOption { MinimalSleepIntervalMilliseconds = 10, RoundIntervalMilliseconds = 100, EstimatedNodeCountMin = 5, FanInNodeCountMax = 1, FanOutNodeCountMax = 2, PushRoundsFactor = 1, PullRoundsFactor = 1, DeadRoundsFactor = 1 }); var stopwatchProvider = new SystemStopwatchProvider(); var service = new EpidemicBroadcastService( loggerFactory.CreateLogger <EpidemicBroadcastService>(), options, stopwatchProvider) { GossiperClientFactory = target => new Gossiper.GossiperClient(new Channel(target, ChannelCredentials.Insecure)), MemberListProvider = () => Enumerable.Range(BINDING_PORT, 5).Select(p => $"127.0.0.1:{p}").ToArray() }; var server = new Server { Ports = { new ServerPort("127.0.0.1", BINDING_PORT, ServerCredentials.Insecure) }, Services = { Gossiper.BindService(service.GossiperImpl) } }; service.OnRumorReceived += (_, e) => logger.LogInformation("Rumor {0} received.", e.Payload.GetHashCode()); server.Start(); await service.StartAsync(); service.Broadcast(new Any()); await Task.Delay(500); var client = new Gossiper.GossiperClient(new Channel($"127.0.0.1:{BINDING_PORT}", ChannelCredentials.Insecure)); using (var pushCall = client.Push(deadline: DateTime.UtcNow.AddMilliseconds(200))) { await pushCall.RequestStream.WriteAsync(new Rumor { Counter = 3, Payload = new Any() }); await pushCall.RequestStream.CompleteAsync(); var pushResult = await pushCall; logger.LogInformation("Client push finished"); } await Task.Delay(110); using (var pullResult = client.Pull(new PullRequest(), deadline: DateTime.UtcNow.AddMilliseconds(200))) { while (await pullResult.ResponseStream.MoveNext()) { logger.LogInformation("Pulled rumor {0}", pullResult.ResponseStream.Current.GetHashCode()); } logger.LogInformation("Client pull finished"); } await service.StopAsync(); await server.ShutdownAsync(); await Task.Delay(1000); }
public async Task TestIntegration() { const int NODE_COUNT = 20; const int STARTING_PORT = 18888; var logger = loggerFactory.CreateLogger(nameof(TestIntegration)); logger.LogInformation("{0}({1}, {2})", nameof(TestIntegration), NODE_COUNT, STARTING_PORT); var options = Options.Create(new EpidemicBroadcastServiceOption { MinimalSleepIntervalMilliseconds = 10, RoundIntervalMilliseconds = 1000, EstimatedNodeCountMin = NODE_COUNT, FanInNodeCountMax = 1, FanOutNodeCountMax = 2, PushRoundsFactor = 1, PullRoundsFactor = 1, DeadRoundsFactor = 1 }); var stopwatchProvider = new SystemStopwatchProvider(); var services = Enumerable.Repeat <object>(null, NODE_COUNT) .Select((_, idx) => new EpidemicBroadcastService( (idx == 0 ? (ILoggerFactory)loggerFactory : NullLoggerFactory.Instance).CreateLogger <EpidemicBroadcastService>(), options, stopwatchProvider) { GossiperClientFactory = target => new Gossiper.GossiperClient(new Channel(target, ChannelCredentials.Insecure)), MemberListProvider = () => Enumerable.Range(STARTING_PORT, NODE_COUNT).Select(p => $"127.0.0.1:{p}").ToArray() }) .ToArray(); var servers = services.Select((s, i) => new Server { Ports = { new ServerPort("127.0.0.1", STARTING_PORT + i, ServerCredentials.Insecure) }, Services = { Gossiper.BindService(s.GossiperImpl) } }).ToArray(); foreach (var s in servers) { s.Start(); } services.Select <EpidemicBroadcastService, object>((s, idx) => { s.OnRumorReceived += (_, e) => logger.LogWarning( "Rumor {0} received at service {1}!", e.Payload.GetHashCode(), idx); return(null); }); await Task.WhenAll(services.Select(s => s.StartAsync())); services[0].Broadcast(new Any()); await Task.Delay(1000 * 10); await Task.WhenAll(services.Select(s => s.StopAsync())); await Task.WhenAll(servers.Select(s => s.ShutdownAsync())); }
internal static async Task Main(string[] args) { LogManager.Configuration = new XmlLoggingConfiguration("nlog.config"); var configuration = BuildConfiguration(args); var services = new ServiceCollection(); services.AddSingleton(configuration); services.AddLogging(b => b.AddNLog().SetMinimumLevel(LogLevel.Trace)); services.Configure <ClusterOptions>(configuration.GetSection("Cluster")); var selfNodeEndpoint = configuration.GetValue <string>("Root:EndPoint"); var selfBindingPort = int.Parse(selfNodeEndpoint.Split(new[] { ':' }, 2)[1]); var clientFactory = new Func <string, Gossiper.GossiperClient>(target => { var channel = new Channel(target, ChannelCredentials.Insecure); return(new Gossiper.GossiperClient(channel)); }); services.AddScoped(serviceProvider => { var seedsEndpoint = serviceProvider.GetRequiredService <IConfiguration>() .GetValue <string>("Root:Seeds") .Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries); return(Node.Create( selfNodeEndpoint, seedsEndpoint, () => serviceProvider.GetRequiredService <ILogger <Node> >())); }); services.AddScoped(serviceProvider => new GossiperImpl( serviceProvider.GetRequiredService <ILogger <GossiperImpl> >(), clientFactory, serviceProvider.GetRequiredService <Node>())); services.AddScoped(serviceProvider => new Cluster( serviceProvider.GetRequiredService <ILogger <Cluster> >(), serviceProvider.GetRequiredService <IOptionsMonitor <ClusterOptions> >(), serviceProvider.GetRequiredService <Node>(), clientFactory)); var container = services.BuildServiceProvider(); var logger = container.GetRequiredService <ILogger <Program> >(); var node = container.GetRequiredService <Node>(); node.NodeStateChanged += (_, e) => { logger.LogWarning( "Node {0} state changed from {1} to {2}", e.EndPoint, e.PreviousNodeState, e.CurrentNodeState); }; GrpcEnvironment.SetLogger(new GrpcLoggerAdapter( container.GetRequiredService <ILogger <GrpcEnvironment> >(), container.GetRequiredService <ILoggerFactory>())); var server = new Server { Services = { Gossiper.BindService(container.GetRequiredService <GossiperImpl>()) }, Ports = { new ServerPort(selfNodeEndpoint.Split(':')[0], selfBindingPort, ServerCredentials.Insecure) } }; server.Start(); var cluster = container.GetRequiredService <Cluster>(); await cluster.StartAsync(); logger.LogInformation("Server is running"); Console.ReadKey(); Task.WaitAll( server.ShutdownAsync(), cluster.StopAsync()); }