private RaftHttpCluster(HttpClusterMemberConfiguration config, IServiceProvider dependencies, out MemberCollectionBuilder members, Func <Action <HttpClusterMemberConfiguration, string>, IDisposable> configTracker) : base(config, out members) { openConnectionForEachRequest = config.OpenConnectionForEachRequest; allowedNetworks = config.AllowedNetworks.ToImmutableHashSet(); metadata = new MemberMetadata(config.Metadata); requestTimeout = config.RequestTimeout; raftRpcTimeout = config.RpcTimeout; connectTimeout = TimeSpan.FromMilliseconds(config.LowerElectionTimeout); duplicationDetector = new DuplicateRequestDetector(config.RequestJournal); clientHandlerName = config.ClientHandlerName; protocolVersion = config.ProtocolVersion; // dependencies configurator = dependencies.GetService <IClusterMemberLifetime>(); messageHandlers = ImmutableList.CreateRange(dependencies.GetServices <IInputChannel>()); AuditTrail = dependencies.GetService <IPersistentState>() ?? new ConsensusOnlyState(); httpHandlerFactory = dependencies.GetService <IHttpMessageHandlerFactory>(); Logger = dependencies.GetRequiredService <ILoggerFactory>().CreateLogger(GetType()); Metrics = dependencies.GetService <MetricsCollector>(); bufferingOptions = dependencies.GetBufferingOptions(); discoveryService = dependencies.GetService <IMemberDiscoveryService>(); // track changes in configuration, do not track membership if discovery service is enabled configurationTracker = configTracker(discoveryService is null ? ConfigurationAndMembershipChanged : ConfigurationChanged); }
private async void ConfigurationChanged(HttpClusterMemberConfiguration configuration, string name) { metadata = new MemberMetadata(configuration.Metadata); allowedNetworks = configuration.AllowedNetworks.ToImmutableHashSet(); await ChangeMembersAsync((in MemberCollectionBuilder members) => { var existingMembers = new HashSet <Uri>(); // remove members foreach (var holder in members) { Debug.Assert(holder.Member.BaseAddress is not null); if (configuration.Members.Contains(holder.Member.BaseAddress)) { existingMembers.Add(holder.Member.BaseAddress); } else { using var member = holder.Remove(); MemberRemoved?.Invoke(this, member); member.CancelPendingRequests(); } } // add new members foreach (var memberUri in configuration.Members) { if (!existingMembers.Contains(memberUri)) { var member = CreateMember(memberUri); members.Add(member); MemberAdded?.Invoke(this, member); } } existingMembers.Clear(); }).ConfigureAwait(false);