/// <summary> /// Removes a member from the cluster. /// </summary> /// <param name="memberId">The identifier of the member to remove.</param> /// <returns>A task that will complete when the member has been removed.</returns> protected async Task RemoveMember(Guid memberId) { if (RcMembers.TryRemove(memberId, out var member)) { await RcClient.StopMemberAsync(RcCluster, member); } }
// this creates members & connect to the cluster, then removes all but 1 member, // all while using the client - things should go smoothly private async Task Run() { var totalStopwatch = Stopwatch.StartNew(); var stopwatch = new Stopwatch(); HConsole.WriteLine(this, $"Begin run on cluster {RcCluster.Id.Substring(0, 7)}"); // add all members for (var i = 0; i < MembersTotal; i++) { HConsole.WriteLine(this, $"Add member #{i}..."); stopwatch.Restart(); var member = await AddMember(); HConsole.WriteLine(this, $"Added {member.Uuid.Substring(0, 7)} at {member.Host}:{member.Port} ({(int)stopwatch.Elapsed.TotalSeconds}s)"); } // prepare options var options = new HazelcastOptionsBuilder() .WithHConsoleLogger() .Build(); options.Networking.Addresses.Clear(); options.Networking.Addresses.Add("127.0.0.1:5701"); options.ClusterName = RcCluster.Id; options.Messaging.RetryTimeoutSeconds = InvocationTimeoutMinutes * 60; // subscribe to members updated var membersCount = 0; var createdObject = false; options.AddSubscriber(events => events .MembersUpdated((sender, args) => { HConsole.WriteLine(this, $"Handle MembersUpdated ({args.Members.Count} members)"); membersCount = args.Members.Count; }) .ObjectCreated((sender, args) => { HConsole.WriteLine(this, $"Object {args.ServiceName}:{args.Name} created"); createdObject = true; })); // start client HConsole.WriteLine(this, "Start client..."); await using var client = await HazelcastClientFactory.StartNewClientAsync(options); await((HazelcastClient)client).DestroyAsync(ServiceNames.Map, "test-map").CfAwait(); // immediately begin using the client - while connections to all members are established HConsole.WriteLine(this, "Get map..."); await using var map = await client.GetMapAsync <string, string>("test-map-" + RandomProvider.Random.Next(1000)); await AssertEx.SucceedsEventually(() => { Assert.That(createdObject); }, 2000, 200); HConsole.WriteLine(this, "Use map..."); await UseClient(map, 2000, 200); // all members are here await AssertEx.SucceedsEventually(() => { Assert.That(membersCount, Is.EqualTo(MembersTotal)); }, 2000, 200); // keep using the client, but remove members down to 1 last member HConsole.WriteLine(this, "Remove members..."); while (RcMembers.Count > 1) { var(memberId, member) = RcMembers.First(); HConsole.WriteLine(this, $"Remove member {member.Uuid.Substring(0, 7)} at {member.Host}:{member.Port}..."); stopwatch.Restart(); await RemoveMember(memberId); HConsole.WriteLine(this, $"Removed member {member.Uuid.Substring(0, 7)} ({(int)stopwatch.Elapsed.TotalSeconds}s)"); await Task.Delay(500); await UseClientOnce(map); } // take time for things to stabilize // keep using the client HConsole.WriteLine(this, "Use map..."); await UseClient(map, 2000, 200); // all members but one are gone await AssertEx.SucceedsEventually(() => { Assert.That(membersCount, Is.EqualTo(1)); }, 8000, 200); // now terminate the client HConsole.WriteLine(this, "Dispose client..."); await client.DisposeAsync(); HConsole.WriteLine(this, $"End ({(int)totalStopwatch.Elapsed.TotalSeconds}s)"); }