private RaftHttpCluster(RaftClusterMemberConfiguration config, IServiceProvider dependencies, out MemberCollectionBuilder members, Func <Action <RaftClusterMemberConfiguration, string>, IDisposable> configTracker) : base(config, out members) { openConnectionForEachRequest = config.OpenConnectionForEachRequest; allowedNetworks = config.AllowedNetworks; metadata = new MemberMetadata(config.Metadata); requestTimeout = TimeSpan.FromMilliseconds(config.UpperElectionTimeout); 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>(); //track changes in configuration configurationTracker = configTracker(ConfigurationChanged); }
private async void ConfigurationChanged(RaftClusterMemberConfiguration configuration, string name) { metadata = new MemberMetadata(configuration.Metadata); allowedNetworks = configuration.AllowedNetworks; await ChangeMembersAsync(members => { var existingMembers = new HashSet <Uri>(); // remove members foreach (var holder in members) { if (configuration.Members.Contains(holder.Member.BaseAddress)) { existingMembers.Add(holder.Member.BaseAddress); } else { 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); }