Example #1
0
        public async Task Cluster()
        {
            // this test expects a server

            HConsole.Configure(x => x.Configure(this).SetIndent(0).SetPrefix("TEST"));
            HConsole.WriteLine(this, "Begin");

            HConsole.WriteLine(this, "Cluster?");

            var serializationService = new SerializationServiceBuilder(new NullLoggerFactory())
                                       .SetVersion(1)
                                       .Build();

            var options = new HazelcastOptions();

            //options.Networking.Addresses.Add("sgay-l4");
            options.Networking.Addresses.Add("localhost");

            var cluster = new Cluster(options, serializationService, new NullLoggerFactory());
            await cluster.Connections.ConnectAsync(CancellationToken.None).CfAwait();

            // now we can send messages...
            //await cluster.SendAsync(new ClientMessage()).CAF();

            // events?
            await Task.Delay(4000).CfAwait();

            HConsole.WriteLine(this, "End");
            await Task.Delay(100).CfAwait();
        }
        public static async Task Run(params string[] args)
        {
            // create an Hazelcast client and connect to a server running on localhost
            var options = HazelcastOptions.Build(args);
            var hz1     = HazelcastClientFactory.CreateClient(options);
            await hz1.StartAsync();

            var connected = new SemaphoreSlim(0);

            // create another Hazelcast client and connect to a server running on localhost
            options.AddSubscriber(on => on
                                  .ClientStateChanged((c, eventArgs) =>
            {
                Console.WriteLine($"State: {eventArgs.State}");
                if (eventArgs.State == ClientLifecycleState.Connected)
                {
                    connected.Release();
                }
            }));
            var hz2 = HazelcastClientFactory.CreateClient(options);
            await hz2.StartAsync();

            // wait for the event
            await connected.WaitAsync();

            // terminate the clients
            await hz1.DisposeAsync();

            await hz2.DisposeAsync();
        }
Example #3
0
        public static async Task Run()
        {
            // create an Hazelcast client and connect to a Cloud server
            var options = HazelcastOptions.Build();
            var cloud   = options.Networking.Cloud;

            cloud.Enabled        = true;
            cloud.DiscoveryToken = "DISCOVERY_TOKEN_HASH"; // copied from Cloud console

            var ssl = options.Networking.Ssl;

            ssl.Enabled = true;
            //ssl.ValidateCertificateChain = false;
            ssl.CertificatePath = "CLIENT_PFX_CERTIFICATE_PATH"; // downloaded from CLoud console

            await using var client = HazelcastClientFactory.CreateClient(options);
            await client.StartAsync();

            // use a map
            await using var map = await client.GetDictionaryAsync <string, string>("ssl-example");

            await map.SetAsync("key", "value");

            var value = await map.GetAsync("key");

            Console.WriteLine($"\"key\": \"{value}\"");
            await client.DestroyAsync(map);
        }
Example #4
0
        public void BuildExceptions()
        {
            Action <IConfigurationBuilder> setup = null;

            Assert.Throws <ArgumentNullException>(() => HazelcastOptions.Build(setup));
            Assert.Throws <ArgumentNullException>(() => HazelcastOptions.Build(setup, null, "key"));
        }
Example #5
0
        public async Task TimeoutsAfterMultipleRetries()
        {
            var address = NetworkAddress.Parse("127.0.0.1:11001");

            using var _ = HConsole.Capture(consoleOptions => consoleOptions
                                           .ClearAll()
                                           .Configure().SetMaxLevel()
                                           .Configure(this).SetPrefix("TEST")
                                           .Configure <AsyncContext>().SetMinLevel()
                                           .Configure <SocketConnectionBase>().SetIndent(1).SetLevel(0).SetPrefix("SOCKET"));

            HConsole.WriteLine(this, "Begin");

            HConsole.WriteLine(this, "Start server");
            await using var server = new Server(address, async(xsvr, xconn, xmsg)
                                                => await HandleAsync(xsvr, xconn, xmsg, async(svr, conn, msg) =>
            {
                HConsole.WriteLine(svr, "Handle request (wait...)");
                await Task.Delay(500).CfAwait();

                HConsole.WriteLine(svr, "Respond with error.");
                var response = ErrorsServerCodec.EncodeResponse(new[]
                {
                    // make sure the error is retryable
                    new ErrorHolder(RemoteError.RetryableHazelcast, "classname", "message", Enumerable.Empty <StackTraceElement>())
                });

                //HConsole.WriteLine(svr, "Respond with success.");
                //var response = ClientPingServerCodec.EncodeResponse();

                response.CorrelationId = msg.CorrelationId;
                await conn.SendAsync(response).CfAwait();
            }), LoggerFactory);
            await server.StartAsync().CfAwait();

            HConsole.WriteLine(this, "Start client");
            var options = HazelcastOptions.Build(configure: (configuration, options) =>
            {
                options.Networking.Addresses.Add("127.0.0.1:11001");
                options.Messaging.RetryTimeoutSeconds = 3; // default value is 120s
            });

            await using var client = (HazelcastClient) await HazelcastClientFactory.StartNewClientAsync(options);

            HConsole.WriteLine(this, "Send message");
            var message = ClientPingServerCodec.EncodeRequest();

            // note: the error only happens *after* the server has responded
            // we could wait for the response for ever
            await AssertEx.ThrowsAsync <TaskTimeoutException>(async() =>
            {
                // server will respond w/ error every 500ms and client will retry
                // until the 3s retry timeout (options above) is reached
                await client.Cluster.Messaging.SendAsync(message).CfAwait();
            });

            await server.StopAsync().CfAwait();
        }
        public async Task Test()
        {
            //var host = Dns.GetHostEntry(_hostname);
            //var ipAddress = host.AddressList[0];
            //var endpoint = new IPEndPoint(ipAddress, _port);

            var address = NetworkAddress.Parse("127.0.0.1:11001");

            HConsole.Configure(this, config => config.SetIndent(0).SetPrefix("TEST"));
            HConsole.WriteLine(this, "Begin");

            HConsole.WriteLine(this, "Start server");
            var server = new Server(address, ReceiveMessage, LoggerFactory);
            await server.StartAsync().CAF();

            var options = HazelcastOptions.Build(Array.Empty <string>(), configure: (configuration, options) =>
            {
                options.Networking.Addresses.Add("127.0.0.1:11001");
            });

            HConsole.WriteLine(this, "Start client 1");
            await using var client1 = (HazelcastClient)HazelcastClientFactory.CreateClient(options);
            await client1.StartAsync().CAF();

            HConsole.WriteLine(this, "Send message 1 to client 1");
            var message  = CreateMessage("ping");
            var response = await client1.Cluster.Messaging.SendAsync(message, CancellationToken.None).CAF();

            HConsole.WriteLine(this, "Got response: " + GetText(response));

            HConsole.WriteLine(this, "Start client 2");
            await using var client2 = (HazelcastClient)HazelcastClientFactory.CreateClient(options);
            await client2.StartAsync().CAF();

            HConsole.WriteLine(this, "Send message 1 to client 2");
            message  = CreateMessage("a");
            response = await client2.Cluster.Messaging.SendAsync(message, CancellationToken.None).CAF();

            HConsole.WriteLine(this, "Got response: " + GetText(response));

            HConsole.WriteLine(this, "Send message 2 to client 1");
            message  = CreateMessage("foo");
            response = await client1.Cluster.Messaging.SendAsync(message, CancellationToken.None).CAF();

            HConsole.WriteLine(this, "Got response: " + GetText(response));

            //XConsole.WriteLine(this, "Stop client");
            //await client1.CloseAsync().CAF();

            HConsole.WriteLine(this, "Stop server");
            await server.StopAsync().CAF();

            await Task.Delay(1000).CAF();

            HConsole.WriteLine(this, "End");
            await Task.Delay(100).CAF();
        }
Example #7
0
        public void ServiceProvider()
        {
            var services        = new ServiceCollection();
            var serviceProvider = services.BuildServiceProvider();
            var options         = new HazelcastOptions {
                ServiceProvider = serviceProvider
            };

            Assert.That(options.ServiceProvider, Is.SameAs(serviceProvider));
        }
Example #8
0
        public async Task CanRetryAndSucceed()
        {
            var address = NetworkAddress.Parse("127.0.0.1:11001");

            HConsole.Configure(x => x.Configure(this).SetIndent(0).SetPrefix("TEST"));
            HConsole.WriteLine(this, "Begin");

            HConsole.WriteLine(this, "Start server");
            var count = 0;

            await using var server = new Server(address, async(xsvr, xconn, xmsg)
                                                => await HandleAsync(xsvr, xconn, xmsg, async(svr, conn, msg) =>
            {
                HConsole.WriteLine(svr, "Handle request.");
                ClientMessage response;
                if (++count > 3)
                {
                    HConsole.WriteLine(svr, "Respond with success.");
                    response = ClientPingServerCodec.EncodeResponse();
                }
                else
                {
                    HConsole.WriteLine(svr, "Respond with error.");
                    response        = CreateErrorMessage(RemoteError.RetryableHazelcast);
                    response.Flags |= ClientMessageFlags.BeginFragment | ClientMessageFlags.EndFragment;
                }
                response.CorrelationId = msg.CorrelationId;
                await conn.SendAsync(response).CfAwait();
            }), LoggerFactory);
            await server.StartAsync().CfAwait();

            HConsole.WriteLine(this, "Start client");
            var options = HazelcastOptions.Build(configure: (configuration, options) =>
            {
                options.Networking.Addresses.Add("127.0.0.1:11001");
            });

            await using var client = (HazelcastClient) await HazelcastClientFactory.StartNewClientAsync(options);

            HConsole.WriteLine(this, "Send message");
            var message = ClientPingServerCodec.EncodeRequest();

            var token = new CancellationTokenSource(3_000).Token;
            await client.Cluster.Messaging.SendAsync(message, token); // default is 120s

            Assert.AreEqual(4, count);

            await server.StopAsync().CfAwait();
        }
Example #9
0
        private static HazelcastOptions ReadResource(string json)
        {
            var stream = new MemoryStream(Encoding.UTF8.GetBytes(json));

            var builder = new ConfigurationBuilder();

            builder.AddJsonStream(stream);
            var configuration = builder.Build();

            var options = new HazelcastOptions();

            configuration.HzBind(HazelcastOptions.Hazelcast, options);

            return(options);
        }
        /// <summary>
        /// Creates the Hazelcast options.
        /// </summary>
        protected virtual HazelcastOptions CreateHazelcastOptions()
        {
            var options = HazelcastOptions.Build(builder =>
            {
                builder.AddDefaults(null);
                builder.AddHazelcast(null);
                builder.AddUserSecrets(GetType().Assembly, true);
            }, null, ConfigurationSecretsKey);

            options.Networking.Addresses.Clear();
            options.Networking.Addresses.Add("127.0.0.1:5701");

            options.LoggerFactory.Creator = () => LoggerFactory;

            return(options);
        }
Example #11
0
        public void AddSubscriber()
        {
            var options = new HazelcastOptions();

            options.AddSubscriber(new TestSubscriber());
            options.AddSubscriber("TestSubscriber");
            options.AddSubscriber(typeof(TestSubscriber));
            options.AddSubscriber <TestSubscriber>();
            options.AddSubscriber(x => x.StateChanged((sender, args) => { }));

            Assert.That(options.Subscribers.Count, Is.EqualTo(5));

            Assert.Throws <ArgumentNullException>(() => options.AddSubscriber((Type)null));
            Assert.Throws <ArgumentException>(() => options.AddSubscriber((string)null));
            Assert.Throws <ArgumentNullException>(() => options.AddSubscriber((IHazelcastClientEventSubscriber)null));
        }
Example #12
0
        public void EmptyOptionsFileWithComments()
        {
            var json = Resources.EmptyWithComments;

            var stream = new MemoryStream(Encoding.UTF8.GetBytes(json));

            var builder = new ConfigurationBuilder();

            builder.AddJsonStream(stream);
            var configuration = builder.Build();

            var options = new HazelcastOptions();

            configuration.HzBind(HazelcastOptions.Hazelcast, options);

            Assert.AreEqual("dev", options.ClusterName);
        }
        public async Task Test()
        {
            using var _ = HConsoleForTest();

            var options = HazelcastOptions.Build();

            options.Messaging.RetryTimeoutSeconds = 1;

            var loggerFactory = new NullLoggerFactory();

            var address = NetworkAddress.Parse("127.0.0.1:11000");

            var state = new ServerState
            {
                Id       = 0,
                MemberId = Guid.NewGuid(),
                Address  = address
            };

            await using var server = new Server(address, ServerHandler, loggerFactory, state, "0")
                        {
                            MemberId = state.MemberId,
                        };
            await server.StartAsync();

            var serializationService = HazelcastClientFactory.CreateSerializationService(options.Serialization, loggerFactory);
            var authenticator        = new Authenticator(options.Authentication, serializationService);

            ISequence <int>  connectionIdSequence  = new Int32Sequence();
            ISequence <long> correlationIdSequence = new Int64Sequence();

            var memberConnection = new MemberConnection(address, authenticator,
                                                        options.Messaging, options.Networking, options.Networking.Ssl,
                                                        connectionIdSequence, correlationIdSequence,
                                                        loggerFactory);

            var memberConnectionHasClosed = false;

            memberConnection.Closed += connection =>
            {
                memberConnectionHasClosed = true;
                return(default);
        protected async ValueTask <IHazelcastClient> StartClientAsync(string serverXml, bool enableSsl, bool?validateCertificateChain,
                                                                      bool?validateCertificateName, bool?checkCertificateRevocation, string certSubjectName, byte[] clientCertificate,
                                                                      string certPassword, bool failFast = false)
        {
            RcCluster = await RcClient.CreateClusterAsync(serverXml);

            RcMember = await RcClient.StartMemberAsync(RcCluster);

            var options = HazelcastOptions.Build();

            options.Networking.Addresses.Clear();
            //options.Networking.Addresses.Add("localhost:5701");
            options.Networking.Addresses.Add("127.0.0.1:5701");
            ((IClusterOptions)options).ClusterName = RcCluster.Id;
            options.LoggerFactory.Creator          = () => LoggerFactory;

            var sslOptions = options.Networking.Ssl;

            sslOptions.Enabled = enableSsl;
            sslOptions.ValidateCertificateChain   = validateCertificateChain ?? sslOptions.ValidateCertificateChain;
            sslOptions.ValidateCertificateName    = validateCertificateName ?? sslOptions.ValidateCertificateName;
            sslOptions.CertificateName            = certSubjectName ?? sslOptions.CertificateName;
            sslOptions.CheckCertificateRevocation = checkCertificateRevocation ?? sslOptions.CheckCertificateRevocation;

            if (failFast)
            {
                // default value is 20s but if we know we are going to fail, no point trying again and again
                options.Networking.ConnectionRetry.ClusterConnectionTimeoutMilliseconds = 2_000;
            }

            if (enableSsl && clientCertificate != null)
            {
                var certFilePath = CreateTmpFile(clientCertificate);
                sslOptions.CertificatePath = certFilePath;
                if (certPassword != null)
                {
                    sslOptions.CertificatePassword = certPassword;
                }
            }

            return(await HazelcastClientFactory.StartNewClientAsync(options));
        }
Example #15
0
        public void LoadBalancingOptions3()
        {
            const string json   = @"{ ""hazelcast"": {
""loadBalancer"" : {
    ""typeName"": ""Hazelcast.Clustering.LoadBalancing.RandomLoadBalancer, Hazelcast.Net""
}
}}";
            var          stream = new MemoryStream(Encoding.UTF8.GetBytes(json));

            var builder = new ConfigurationBuilder();

            builder.AddJsonStream(stream);
            var configuration = builder.Build();

            var options = new HazelcastOptions();

            configuration.HzBind(HazelcastOptions.Hazelcast, options);

            Assert.IsInstanceOf <RandomLoadBalancer>(options.LoadBalancer.Service);
        }
Example #16
0
        public static async Task Run()
        {
            // create an Hazelcast client and connect to a Cloud server
            var options = HazelcastOptions.Build();

            options.Networking.Cloud.Enabled        = true;
            options.Networking.Cloud.DiscoveryToken = "DISCOVERY_TOKEN_HASH"; // copied from Cloud console
            await using var client = HazelcastClientFactory.CreateClient(options);
            await client.StartAsync();

            // use a map
            await using var map = await client.GetDictionaryAsync <string, string>("ssl-example");

            await map.SetAsync("key", "value");

            var value = await map.GetAsync("key");

            Console.WriteLine($"\"key\": \"{value}\"");
            await client.DestroyAsync(map);
        }
        public async Task TimeoutsIfServerIsTooSlow()
        {
            var address = NetworkAddress.Parse("127.0.0.1:11001");

            HConsole.Configure(this, config => config.SetIndent(0).SetPrefix("TEST"));
            HConsole.WriteLine(this, "Begin");

            HConsole.WriteLine(this, "Start server");
            await using var server = new Server(address, async(svr, conn, msg) =>
            {
                HConsole.WriteLine(svr, "Handle request (slowww...)");
                await Task.Delay(10_000).CAF();

                HConsole.WriteLine(svr, "Respond with success.");
                var response           = ClientPingServerCodec.EncodeResponse();
                response.CorrelationId = msg.CorrelationId;
                await conn.SendAsync(response).CAF();
            }, LoggerFactory);
            await server.StartAsync().CAF();

            HConsole.WriteLine(this, "Start client");
            var options = HazelcastOptions.Build(configure: (configuration, options) =>
            {
                options.Networking.Addresses.Add("127.0.0.1:11001");
            });

            await using var client = (HazelcastClient)HazelcastClientFactory.CreateClient(options);
            await client.StartAsync().CAF();

            HConsole.WriteLine(this, "Send message");
            var message = ClientPingServerCodec.EncodeRequest();

            Assert.ThrowsAsync <TaskCanceledException>(async() =>
            {
                var token = new CancellationTokenSource(3_000).Token;
                await client.Cluster.Messaging.SendAsync(message, token); // default is 120s
            });

            // TODO dispose the client, the server
            await server.StopAsync().CAF();
        }
Example #18
0
        public async Task ServerShutdown()
        {
            var address = NetworkAddress.Parse("127.0.0.1:11000");

            HConsole.Configure(x => x.Configure(this).SetIndent(0).SetPrefix("TEST"));
            HConsole.WriteLine(this, "Begin");

            HConsole.WriteLine(this, "Start server");
            await using var server = new Server(address, async(xsvr, xconn, xmsg)
                                                => await HandleAsync(xsvr, xconn, xmsg, ReceiveMessage), LoggerFactory);
            await server.StartAsync().CfAwait();

            var options = HazelcastOptions.Build(Array.Empty <string>(), configure: (configuration, options) =>
            {
                options.Networking.Addresses.Add("127.0.0.1:11000");
            });

            HConsole.WriteLine(this, "Start client 1");
            await using var client1 = (HazelcastClient) await HazelcastClientFactory.StartNewClientAsync(options);

            HConsole.WriteLine(this, "Send message 1 to client 1");
            var message  = CreateMessage("ping");
            var response = await client1.Cluster.Messaging.SendAsync(message, CancellationToken.None).CfAwait();

            HConsole.WriteLine(this, "Got response: " + GetText(response));

            HConsole.WriteLine(this, "Stop server");
            await server.StopAsync().CfAwait();

            await Task.Delay(1000).CfAwait();

            HConsole.WriteLine(this, "Send message 2 to client 1");
            message = CreateMessage("ping");
            Assert.ThrowsAsync <ClientOfflineException>(async() => await client1.Cluster.Messaging.SendAsync(message, CancellationToken.None).CfAwait());

            HConsole.WriteLine(this, "End");
            await Task.Delay(100).CfAwait();
        }
        //
        // this is a complete example of a simple console application where
        // every component is configured and created explicitly.
        //
        // configuration (https://docs.microsoft.com/en-us/aspnet/core/fundamentals/configuration)
        //
        //   environment
        //     optional Hazelcast.Build(...) 'environmentName' argument: Development, Staging, Production (default), ...
        //     falls back to DOTNET_ENVIRONMENT + ASPNETCORE_ENVIRONMENT environment variables
        //     determines <env>, default is Production
        //
        //   configuration file
        //     appsettings.json
        //     appsettings.<env>.json
        //     hazelcast.json
        //     hazelcast.<env>.json
        //
        //     {
        //       "hazelcast": {
        //         "networking": {
        //           "addresses": [ "server:port" ]
        //         }
        //       }
        //     }
        //
        //   environment variables
        //     hazelcast__networking__addresses__0=server:port (standard .NET)
        //     hazelcast.networking.addresses.0=server:port (hazelcast-specific)
        //
        //   command line
        //     hazelcast:networking:addresses:0=server:port (standard .NET)
        //     hazelcast.networking.addresses.0=server:port (hazelcast-specific)
        //

        public static async Task Run(string[] args)
        {
            // build options
            var options = HazelcastOptions.Build(args);

            // build a console logger factory from scratch
            var loggerFactory = LoggerFactory.Create(builder =>
            {
                builder.AddConsole();
            });

            // and register the logger factory in the options
            options.Logging.LoggerFactory.Creator = () => loggerFactory;

            // create a logger, a client factory and a client
            var logger = loggerFactory.CreateLogger <Worker>();

            await using var client = HazelcastClientFactory.CreateClient(options); // disposed when method exits

            // create the worker, and run
            var worker = new Worker(client, logger);
            await worker.RunAsync();
        }
        public static async Task Run()
        {
            // enable client statistics
            // set the statistics send period, default value is 3 seconds
            Environment.SetEnvironmentVariable("hazelcast.client.statistics.enabled", "true");
            Environment.SetEnvironmentVariable("hazelcast.client.statistics.period.seconds", "3");

            // create an Hazelcast client and connect to a server running on localhost
            var options = HazelcastOptions.Build();

            options.NearCache.Configurations["myMap"] = new NearCacheNamedOptions
            {
                MaxSize            = 1000,
                InvalidateOnChange = true,
                EvictionPolicy     = EvictionPolicy.Lru,
                InMemoryFormat     = InMemoryFormat.Binary
            };
            var hz = HazelcastClientFactory.CreateClient(options);
            await hz.StartAsync();

            // get a map
            var map = await hz.GetDictionaryAsync <string, string>("myMap");

            // generate stats
            for (var i = 0; i < 100000; i++)
            {
                await map.SetAsync("key-" + i, "value-" + i);

                Thread.Sleep(500);
            }

            // is that all?
            // "after client connected you can use Management Center to visualize client statistics"

            // terminate the client
            await hz.DisposeAsync();
        }
 public void BuildExceptions()
 {
     Assert.Throws <ArgumentNullException>(() => HazelcastOptions.Build((Action <IConfigurationBuilder>)null));
     Assert.Throws <ArgumentNullException>(() => HazelcastOptions.Build(null, null, "key"));
 }
Example #22
0
        public void AltKey()
        {
            const string json1 = @"{
    ""hazelcast"": {
        ""clientName"": ""client"",
        ""clusterName"": ""cluster"",
        ""networking"": {
            ""addresses"": [
                ""127.0.0.1""
            ]
        }
    }
}";

            const string json2 = @"{
    ""alt"": {
        ""clientName"": ""altClient"",
        ""networking"": {
            ""addresses"": [
                ""127.0.0.2""
            ]
        }
    }
}";

            var stream1 = new MemoryStream(Encoding.UTF8.GetBytes(json1));
            var stream2 = new MemoryStream(Encoding.UTF8.GetBytes(json2));

            var builder = new ConfigurationBuilder();

            builder.AddJsonStream(stream1);
            builder.AddJsonStream(stream2);
            var configuration = builder.Build();

            var options = new HazelcastOptions();

            configuration.HzBind(HazelcastOptions.Hazelcast, options);
            configuration.HzBind("alt", options);

            Assert.AreEqual("altClient", options.ClientName);
            Assert.AreEqual("cluster", options.ClusterName);

            Assert.That(options.Networking.Addresses.Count, Is.EqualTo(2));
            Assert.That(options.Networking.Addresses, Does.Contain("127.0.0.1"));
            Assert.That(options.Networking.Addresses, Does.Contain("127.0.0.2"));

            // or, more simply (only in tests):

            stream1 = new MemoryStream(Encoding.UTF8.GetBytes(json1));
            stream2 = new MemoryStream(Encoding.UTF8.GetBytes(json2));

            options = HazelcastOptions.Build(x => x.AddJsonStream(stream1).AddJsonStream(stream2),
                                             null, "alt");

            Assert.AreEqual("altClient", options.ClientName);
            Assert.AreEqual("cluster", options.ClusterName);

            Assert.That(options.Networking.Addresses.Count, Is.EqualTo(2));
            Assert.That(options.Networking.Addresses, Does.Contain("127.0.0.1"));
            Assert.That(options.Networking.Addresses, Does.Contain("127.0.0.2"));
        }
        public async Task SubscriptionIsCollected()
        {
            var address0 = NetworkAddress.Parse("127.0.0.1:11001");
            var address1 = NetworkAddress.Parse("127.0.0.1:11002");

            var memberId0 = Guid.NewGuid();
            var memberId1 = Guid.NewGuid();

            using var __ = HConsoleForTest();

            HConsole.WriteLine(this, "Begin");
            HConsole.WriteLine(this, "Start servers");

            var loggerFactory = new NullLoggerFactory();

            var state0 = new ServerState
            {
                Id        = 0,
                MemberIds = new[] { memberId0, memberId1 },
                Addresses = new[] { address0, address1 },
                MemberId  = memberId0,
                Address   = address0
            };

            await using var server0 = new Server(address0, ServerHandler, loggerFactory, state0, "0")
                        {
                            MemberId = state0.MemberId,
                        };
            await server0.StartAsync();

            var state1 = new ServerState
            {
                Id        = 1,
                MemberIds = new[] { memberId0, memberId1 },
                Addresses = new[] { address0, address1 },
                MemberId  = memberId1,
                Address   = address1
            };

            await using var server1 = new Server(address1, ServerHandler, loggerFactory, state1, "1")
                        {
                            MemberId  = state1.MemberId,
                            ClusterId = server0.ClusterId
                        };
            await server1.StartAsync();

            HConsole.WriteLine(this, "Start client");

            var options = HazelcastOptions.Build(configure: (configuration, options) =>
            {
                options.Networking.Addresses.Add("127.0.0.1:11001");
                options.Networking.Addresses.Add("127.0.0.1:11002");
                options.Events.SubscriptionCollectDelay = TimeSpan.FromSeconds(4); // don't go too fast
            });

            await using var client = (HazelcastClient) await HazelcastClientFactory.StartNewClientAsync(options);

            HConsole.WriteLine(this, "Get dictionary");

            var dictionary = await client.GetMapAsync <string, string>("name");

            var count = 0;

            var clusterEvents = client.Cluster.Events;

            Assert.That(clusterEvents.Subscriptions.Count, Is.EqualTo(0));           // no client subscription yet
            Assert.That(clusterEvents.CorrelatedSubscriptions.Count, Is.EqualTo(1)); // but the cluster events subscription

            HConsole.WriteLine(this, "Subscribe");

            var sid = await dictionary.SubscribeAsync(events => events
                                                      .EntryAdded((sender, args) => Interlocked.Increment(ref count))
                                                      );

            Assert.That(clusterEvents.Subscriptions.Count, Is.EqualTo(1));                   // 1 (our) client subscription
            Assert.That(clusterEvents.Subscriptions.TryGetValue(sid, out var subscription)); // can get our subscription

            await AssertEx.SucceedsEventually(() =>
            {
                Assert.That(clusterEvents.CorrelatedSubscriptions.Count, Is.EqualTo(3)); // 2 more correlated
                Assert.That(subscription.Count, Is.EqualTo(2));                          // has 2 members
                Assert.That(subscription.Active);
            }, 4000, 200);

            HConsole.WriteLine(this, "Set");

            await dictionary.SetAsync("key", "value");

            await AssertEx.SucceedsEventually(() =>
            {
                Assert.That(count, Is.EqualTo(1)); // event triggered
            }, 2000, 100);

            HConsole.WriteLine(this, "Unsubscribe");

            var unsubscribed = await dictionary.UnsubscribeAsync(sid);

            Assert.That(unsubscribed);

            // we have a 4 sec delay before the collect task actually collects

            await AssertEx.SucceedsEventually(() =>
            {
                Assert.That(subscription.Active, Is.False);
                Assert.That(clusterEvents.Subscriptions.Count, Is.EqualTo(0));           // is gone
                Assert.That(clusterEvents.CorrelatedSubscriptions.Count, Is.EqualTo(1)); // are gone
                Assert.That(subscription.Count, Is.EqualTo(1));                          // 1 remains
                Assert.That(clusterEvents.GhostSubscriptions.Count, Is.EqualTo(1));      // is ghost
            }, 4000, 200);

            // get a key that targets server 1 - the one that's going to send the event
            var key = GetKey(1, 2, client.SerializationService);

            HConsole.WriteLine(this, "Set key=" + key);

            await dictionary.SetAsync(key, "value");

            await Task.Delay(100);

            Assert.That(count, Is.EqualTo(1)); // no event

            await AssertEx.SucceedsEventually(() =>
            {
                Assert.That(subscription.Count, Is.EqualTo(0));                     // 0 remains
                Assert.That(clusterEvents.GhostSubscriptions.Count, Is.EqualTo(0)); // is gone
            }, 8000, 200);
        }
Example #24
0
        public async Task CanRetryAndTimeout()
        {
            var address = NetworkAddress.Parse("127.0.0.1:11001");

            HConsole.Configure(x => x.Configure(this).SetIndent(0).SetPrefix("TEST"));
            HConsole.WriteLine(this, "Begin");

            HConsole.WriteLine(this, "Start server");
            await using var server = new Server(address, async(xsvr, xconn, xmsg)
                                                => await HandleAsync(xsvr, xconn, xmsg, async(svr, conn, msg) =>
            {
                async Task ResponseAsync(ClientMessage response)
                {
                    response.CorrelationId = msg.CorrelationId;
                    response.Flags        |= ClientMessageFlags.BeginFragment | ClientMessageFlags.EndFragment;
                    await conn.SendAsync(response).CfAwait();
                }

                async Task EventAsync(ClientMessage eventMessage)
                {
                    eventMessage.CorrelationId = msg.CorrelationId;
                    eventMessage.Flags        |= ClientMessageFlags.BeginFragment | ClientMessageFlags.EndFragment;
                    await conn.SendAsync(eventMessage).CfAwait();
                }

                switch (msg.MessageType)
                {
                // must handle auth
                case ClientAuthenticationServerCodec.RequestMessageType:
                    var authRequest  = ClientAuthenticationServerCodec.DecodeRequest(msg);
                    var authResponse = ClientAuthenticationServerCodec.EncodeResponse(
                        0, address, Guid.NewGuid(), SerializationService.SerializerVersion,
                        "4.0", 1, Guid.NewGuid(), false);
                    await ResponseAsync(authResponse).CfAwait();
                    break;

                // must handle events
                case ClientAddClusterViewListenerServerCodec.RequestMessageType:
                    var addRequest  = ClientAddClusterViewListenerServerCodec.DecodeRequest(msg);
                    var addResponse = ClientAddClusterViewListenerServerCodec.EncodeResponse();
                    await ResponseAsync(addResponse).CfAwait();

                    _ = Task.Run(async() =>
                    {
                        await Task.Delay(500).CfAwait();
                        var eventMessage = ClientAddClusterViewListenerServerCodec.EncodeMembersViewEvent(1, new[]
                        {
                            new MemberInfo(Guid.NewGuid(), address, new MemberVersion(4, 0, 0), false, new Dictionary <string, string>()),
                        });
                        await EventAsync(eventMessage).CfAwait();
                    });

                    break;

                default:
                    HConsole.WriteLine(svr, "Respond with error.");
                    var response = CreateErrorMessage(RemoteError.RetryableHazelcast);
                    await ResponseAsync(response).CfAwait();
                    break;
                }
            }), LoggerFactory);
            await server.StartAsync().CfAwait();

            HConsole.WriteLine(this, "Start client");
            var options = HazelcastOptions.Build(configure: (configuration, options) =>
            {
                options.Networking.Addresses.Add("127.0.0.1:11001");
            });

            await using var client = (HazelcastClient) await HazelcastClientFactory.StartNewClientAsync(options);

            HConsole.WriteLine(this, "Send message");
            var message = ClientPingServerCodec.EncodeRequest();

            var token = new CancellationTokenSource(3_000).Token;
            await AssertEx.ThrowsAsync <TaskCanceledException>(async() => await client.Cluster.Messaging.SendAsync(message, token).CfAwait());

            // TODO dispose the client, the server
            await server.StopAsync().CfAwait();
        }