예제 #1
0
        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);
        }
예제 #2
0
        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);