public Heartbeat(ClusterState clusterState, ClusterMembers clusterMembers, ClusterMessaging clusterMessaging, HeartbeatOptions options, ILoggerFactory loggerFactory)
        {
            _clusterState     = clusterState ?? throw new ArgumentNullException(nameof(clusterState));
            _clusterMembers   = clusterMembers ?? throw new ArgumentNullException(nameof(clusterMembers));
            _clusterMessaging = clusterMessaging ?? throw new ArgumentNullException(nameof(clusterMessaging));
            if (options == null)
            {
                throw new ArgumentNullException(nameof(options));
            }
            _logger = loggerFactory?.CreateLogger <Heartbeat>() ?? throw new ArgumentNullException(nameof(loggerFactory));

            _period  = TimeSpan.FromMilliseconds(options.PeriodMilliseconds);
            _timeout = TimeSpan.FromMilliseconds(options.TimeoutMilliseconds);

            // sanity checks
            if (_timeout <= _period)
            {
                var timeout = TimeSpan.FromMilliseconds(2 * _period.TotalMilliseconds);
                _logger.LogWarning("Heartbeat timeout {Timeout}ms is <= period {Period}ms, falling back to a {Value}ms timeout.",
                                   _timeout, _period.TotalMilliseconds, timeout);
                _timeout = timeout;
            }

            _cancellation = new CancellationTokenSource();
            _heartbeating ??= LoopAsync(_cancellation.Token);
        }
Exemple #2
0
        /// <summary>
        /// Initializes a new instance of the <see cref="ClusterMessaging"/> class.
        /// </summary>
        /// <param name="clusterState">The cluster state.</param>
        /// <param name="clusterMembers">The cluster members.</param>
        public ClusterMessaging(ClusterState clusterState, ClusterMembers clusterMembers)
        {
            _clusterState   = clusterState;
            _clusterMembers = clusterMembers;

            HConsole.Configure(x => x.Configure <ClusterMessaging>().SetPrefix("MSGING"));
        }
        public Heartbeat(ClusterState clusterState, ClusterMembers clusterMembers, ClusterMessaging clusterMessaging, HeartbeatOptions options, ILoggerFactory loggerFactory)
        {
            _clusterState     = clusterState ?? throw new ArgumentNullException(nameof(clusterState));
            _clusterMembers   = clusterMembers ?? throw new ArgumentNullException(nameof(clusterMembers));
            _clusterMessaging = clusterMessaging ?? throw new ArgumentNullException(nameof(clusterMessaging));
            if (options == null)
            {
                throw new ArgumentNullException(nameof(options));
            }
            _logger = loggerFactory?.CreateLogger <Heartbeat>() ?? throw new ArgumentNullException(nameof(loggerFactory));

            _period      = TimeSpan.FromMilliseconds(options.PeriodMilliseconds);
            _timeout     = TimeSpan.FromMilliseconds(options.TimeoutMilliseconds);
            _pingTimeout = options.PingTimeoutMilliseconds;

            // sanity checks
            if (_timeout <= _period)
            {
                var timeout = TimeSpan.FromMilliseconds(2 * _period.TotalMilliseconds);
                _logger.LogWarning("Heartbeat timeout {Timeout}ms is <= period {Period}ms, falling back to a {Value}ms timeout.",
                                   _timeout, _period.TotalMilliseconds, timeout);
                _timeout = timeout;
            }

            if (_pingTimeout >= _period.TotalMilliseconds)
            {
                var pingTimeout = (int)_period.TotalMilliseconds / 2;
                _logger.LogWarning("Ping timeout {Timeout}ms is >= period {Period}ms, falling back to a {Value}ms timeout.",
                                   _pingTimeout, _period.TotalMilliseconds, pingTimeout);
                _pingTimeout = pingTimeout;
            }
        }
Exemple #4
0
        public ClusterEvents(ClusterState clusterState, ClusterMessaging clusterMessaging, ClusterMembers clusterMembers)
        {
            _clusterState     = clusterState;
            _clusterMessaging = clusterMessaging;
            _clusterMembers   = clusterMembers;

            _logger    = _clusterState.LoggerFactory.CreateLogger <ClusterEvents>();
            _scheduler = new DistributedEventScheduler(_clusterState.LoggerFactory);
        }
Exemple #5
0
        public ClusterConnections(ClusterState clusterState, ClusterClusterEvents clusterClusterEvents, ClusterEvents clusterEvents, ClusterMembers clusterMembers, ISerializationService serializationService, Func <ValueTask> terminateAsync)
        {
            _clusterState         = clusterState;
            _clusterClusterEvents = clusterClusterEvents;
            _clusterEvents        = clusterEvents;
            _clusterMembers       = clusterMembers;
            _serializationService = serializationService;
            _terminateAsync       = terminateAsync;

            _logger = _clusterState.LoggerFactory.CreateLogger <ClusterConnections>();

            _authenticator = _clusterState.Options.Authentication.Authenticator.Service ??
                             new Authenticator(_clusterState.Options.Authentication);
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="ClusterClusterEvents"/> class.
        /// </summary>
        /// <param name="clusterState">The cluster state.</param>
        /// <param name="clusterMembers">The cluster members.</param>
        /// <param name="clusterEvents">The cluster events.</param>
        public ClusterClusterEvents(ClusterState clusterState, ClusterMembers clusterMembers, ClusterEvents clusterEvents)
        {
            _clusterState = clusterState;

            _objectLifecycleEventSubscription = new ObjectLifecycleEventSubscription(_clusterState, clusterEvents)
            {
                ObjectCreated   = args => _objectCreated.AwaitEach(args),
                ObjectDestroyed = args => _objectDestroyed.AwaitEach(args)
            };

            _partitionLostEventSubscription = new PartitionLostEventSubscription(_clusterState, clusterEvents, clusterMembers)
            {
                PartitionLost = args => _partitionLost.AwaitEach(args)
            };
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="ClusterClusterEvents"/> class.
        /// </summary>
        /// <param name="clusterState">The cluster state.</param>
        /// <param name="clusterMembers">The cluster members.</param>
        /// <param name="clusterEvents">The cluster events.</param>
        public ClusterClusterEvents(ClusterState clusterState, ClusterMembers clusterMembers, ClusterEvents clusterEvents)
        {
            _clusterState  = clusterState;
            _clusterEvents = clusterEvents;

            _objectLifecycleEventSubscription = new ObjectLifecycleEventSubscription(_clusterState, clusterEvents)
            {
                Handle = (eventType, args) => _onObjectLifeCycleEvent(eventType, args)
            };

            _partitionLostEventSubscription = new PartitionLostEventSubscription(_clusterState, clusterEvents, clusterMembers)
            {
                Handle = args => _onPartitionLost(args)
            };
        }
Exemple #8
0
        private volatile int _disposed; // disposed flag

        /// <summary>
        /// Initializes a new instance of the <see cref="ClusterConnections"/> class.
        /// </summary>
        public ClusterConnections(ClusterState clusterState, ClusterMembers clusterMembers, SerializationService serializationService)
        {
            _clusterState   = clusterState;
            _clusterMembers = clusterMembers;

            _logger               = _clusterState.LoggerFactory.CreateLogger <ClusterConnections>();
            _authenticator        = new Authenticator(_clusterState.Options.Authentication, serializationService);
            _addressProvider      = new AddressProvider(_clusterState.Options.Networking, _clusterState.LoggerFactory);
            _connectRetryStrategy = new RetryStrategy("connect to cluster", _clusterState.Options.Networking.ConnectionRetry, _clusterState.LoggerFactory);

            if (_clusterState.IsSmartRouting)
            {
                _smartRouting     = true;
                _connectAddresses = new ConnectAddresses(GetOrConnectAsync, _clusterState.LoggerFactory);
            }

            HConsole.Configure(options => options.Set(this, x => x.SetPrefix("CCNX")));
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="ClusterMembers"/> class.
        /// </summary>
        /// <param name="clusterState">The cluster state.</param>
        /// <param name="terminateConnections">The terminate connections task.</param>
        public ClusterMembers(ClusterState clusterState, TerminateConnections terminateConnections)
        {
            HConsole.Configure(x => x.Configure <ClusterMembers>().SetPrefix("CLUST.MBRS"));

            _clusterState         = clusterState;
            _terminateConnections = terminateConnections;
            _loadBalancer         = clusterState.Options.LoadBalancer.Service ?? new RandomLoadBalancer();

            _logger = _clusterState.LoggerFactory.CreateLogger <ClusterMembers>();

            _members = new MemberTable();

            // members to connect
            if (clusterState.IsSmartRouting)
            {
                _memberConnectionQueue = new MemberConnectionQueue(clusterState.LoggerFactory);
            }
        }
        private volatile int _disposed; // disposed flag

        /// <summary>
        /// Initializes a new instance of the <see cref="ClusterConnections"/> class.
        /// </summary>
        public ClusterConnections(ClusterState clusterState, ClusterMembers clusterMembers, SerializationService serializationService)
        {
            _clusterState   = clusterState;
            _clusterMembers = clusterMembers;

            _logger               = _clusterState.LoggerFactory.CreateLogger <ClusterConnections>();
            _authenticator        = new Authenticator(_clusterState.Options.Authentication, serializationService, _clusterState.LoggerFactory);
            _addressProvider      = new AddressProvider(_clusterState.Options.Networking, _clusterState.LoggerFactory);
            _connectRetryStrategy = new RetryStrategy("connect to cluster", _clusterState.Options.Networking.ConnectionRetry, _clusterState.LoggerFactory);

            if (_clusterState.IsSmartRouting)
            {
                _connectMembers = ConnectMembers(_cancel.Token);
            }

            _clusterState.StateChanged += OnStateChanged;

            HConsole.Configure(x => x.Configure <ClusterConnections>().SetPrefix("CCNX"));
        }
        private volatile int _disposed; // disposed flag

        /// <summary>
        /// Initializes a new instance of the <see cref="Cluster"/> class.
        /// </summary>
        /// <param name="options">The cluster configuration.</param>
        /// <param name="serializationService">The serialization service.</param>
        /// <param name="loggerFactory">A logger factory.</param>
        public Cluster(IClusterOptions options, SerializationService serializationService, ILoggerFactory loggerFactory)
        {
            if (options == null)
            {
                throw new ArgumentNullException(nameof(options));
            }
            if (serializationService == null)
            {
                throw new ArgumentNullException(nameof(serializationService));
            }
            if (loggerFactory is null)
            {
                throw new ArgumentNullException(nameof(loggerFactory));
            }

            var clientName = string.IsNullOrWhiteSpace(options.ClientName)
                ? options.ClientNamePrefix + ClusterIdSequence.GetNext()
                : options.ClientName;

            var clusterName = string.IsNullOrWhiteSpace(options.ClusterName) ? "dev" : options.ClusterName;

            State = new ClusterState(options, clusterName, clientName, new Partitioner(), loggerFactory);
            State.ShutdownRequested += () =>
            {
                // yes, we are starting a fire-and-forget task
                // but, DisposeAsync should never throw
                // yet we add a CfAwaitNoThrow() for more safety
                DisposeAsync().CfAwaitNoThrow();
            };

            // create components
            _terminateConnections = new TerminateConnections(loggerFactory);
            Members     = new ClusterMembers(State, _terminateConnections);
            Messaging   = new ClusterMessaging(State, Members);
            Events      = new ClusterEvents(State, Messaging, _terminateConnections, Members);
            Connections = new ClusterConnections(State, Members, serializationService);
            _heartbeat  = new Heartbeat(State, Messaging, options.Heartbeat, _terminateConnections);

            // wire components
            WireComponents();

            HConsole.Configure(x => x.Configure <Cluster>().SetIndent(2).SetPrefix("CLUSTER"));
        }
Exemple #12
0
        private volatile int _disposed; // disposed flag

        /// <summary>
        /// Initializes a new instance of the <see cref="Cluster"/> class.
        /// </summary>
        /// <param name="options">The cluster configuration.</param>
        /// <param name="serializationService">The serialization service.</param>
        /// <param name="loggerFactory">A logger factory.</param>
        public Cluster(
            IClusterOptions options,
            ISerializationService serializationService,
            ILoggerFactory loggerFactory)
        {
            _options = options ?? throw new ArgumentNullException(nameof(options));

            if (serializationService == null)
            {
                throw new ArgumentNullException(nameof(serializationService));
            }
            if (loggerFactory is null)
            {
                throw new ArgumentNullException(nameof(loggerFactory));
            }

            _logger = loggerFactory.CreateLogger <Cluster>();

            DefaultOperationTimeoutMilliseconds = options.Messaging.DefaultOperationTimeoutMilliseconds;
            Partitioner = new Partitioner();

            var loadBalancer = options.LoadBalancing.LoadBalancer.Service ?? new RoundRobinLoadBalancer();

            var clientName = string.IsNullOrWhiteSpace(options.ClientName)
                ? options.ClientNamePrefix + ClusterIdSequence.GetNext()
                : options.ClientName;

            var clusterName = string.IsNullOrWhiteSpace(options.ClusterName) ? "dev" : options.ClusterName;

            _clusterState = new ClusterState(options, clusterName, clientName, Partitioner, loadBalancer, loggerFactory);

            Members       = new ClusterMembers(_clusterState);
            Messaging     = new ClusterMessaging(_clusterState, Members);
            Events        = new ClusterEvents(_clusterState, Messaging, Members);
            ClusterEvents = new ClusterClusterEvents(_clusterState, Members, Events);
            Connections   = new ClusterConnections(_clusterState, ClusterEvents, Events, Members, serializationService, TerminateAsync);

            _heartbeat = new Heartbeat(_clusterState, Members, Messaging, options.Heartbeat, loggerFactory);
            _heartbeat.Start();

            HConsole.Configure(this, config => config.SetIndent(2).SetPrefix("CLUSTER"));
        }
Exemple #13
0
        public ClusterEvents(ClusterState clusterState, ClusterMessaging clusterMessaging, TerminateConnections terminateConnections, ClusterMembers clusterMembers)
        {
            _clusterState     = clusterState;
            _clusterMessaging = clusterMessaging;
            _clusterMembers   = clusterMembers;

            _logger               = _clusterState.LoggerFactory.CreateLogger <ClusterEvents>();
            _scheduler            = new DistributedEventScheduler(_clusterState.LoggerFactory);
            _terminateConnections = terminateConnections;

            _objectLifecycleEventSubscription = new ObjectLifecycleEventSubscription(_clusterState, this)
            {
                ObjectCreated   = args => _objectCreated.AwaitEach(args),
                ObjectDestroyed = args => _objectDestroyed.AwaitEach(args)
            };

            _partitionLostEventSubscription = new PartitionLostEventSubscription(_clusterState, this, clusterMembers)
            {
                PartitionLost = args => _partitionLost.AwaitEach(args)
            };
        }
Exemple #14
0
        public Heartbeat(ClusterState clusterState, ClusterMessaging clusterMessaging, HeartbeatOptions options, TerminateConnections terminateConnections)
        {
            _clusterState         = clusterState ?? throw new ArgumentNullException(nameof(clusterState));
            _clusterMessaging     = clusterMessaging ?? throw new ArgumentNullException(nameof(clusterMessaging));
            _terminateConnections = terminateConnections;
            if (options == null)
            {
                throw new ArgumentNullException(nameof(options));
            }

            _logger  = clusterState.LoggerFactory.CreateLogger <Heartbeat>(); // FIXME with client ID?
            _period  = TimeSpan.FromMilliseconds(options.PeriodMilliseconds);
            _timeout = TimeSpan.FromMilliseconds(options.TimeoutMilliseconds);

            if (options.PeriodMilliseconds < 0)
            {
                _logger.LogInformation("Heartbeat is disabled (period < 0)");
                return;
            }

            // sanity checks
            if (_timeout <= _period)
            {
                var timeout = TimeSpan.FromMilliseconds(2 * _period.TotalMilliseconds);
                _logger.LogWarning("Heartbeat timeout {Timeout}ms is <= period {Period}ms, falling back to a {Value}ms timeout.",
                                   _timeout, _period.TotalMilliseconds, timeout);
                _timeout = timeout;
            }

            _logger.LogInformation("Heartbeat with {Period}ms period and {Timeout}ms timeout",
                                   _period.ToString("hh\\:mm\\:ss", CultureInfo.InvariantCulture),
                                   _timeout.ToString("hh\\:mm\\:ss", CultureInfo.InvariantCulture));

            HConsole.Configure(x => x.Configure <Heartbeat>().SetPrefix("HEARTBEAT")); // FIXME with client ID?

            _cancel       = new CancellationTokenSource();
            _heartbeating = BeatAsync(_cancel.Token);
            _active       = 1;
        }
        private volatile int _disposed; // disposed flag

        /// <summary>
        /// Initializes a new instance of the <see cref="Cluster"/> class.
        /// </summary>
        /// <param name="options">The cluster configuration.</param>
        /// <param name="serializationService">The serialization service.</param>
        /// <param name="loggerFactory">A logger factory.</param>
        public Cluster(
            IClusterOptions options,
            SerializationService serializationService,
            ILoggerFactory loggerFactory)
        {
            if (options == null)
            {
                throw new ArgumentNullException(nameof(options));
            }
            if (serializationService == null)
            {
                throw new ArgumentNullException(nameof(serializationService));
            }
            if (loggerFactory is null)
            {
                throw new ArgumentNullException(nameof(loggerFactory));
            }

            _logger = loggerFactory.CreateLogger <Cluster>();

            var clientName = string.IsNullOrWhiteSpace(options.ClientName)
                ? options.ClientNamePrefix + ClusterIdSequence.GetNext()
                : options.ClientName;

            var clusterName = string.IsNullOrWhiteSpace(options.ClusterName) ? "dev" : options.ClusterName;

            State = new ClusterState(options, clusterName, clientName, new Partitioner(), loggerFactory);

            Members       = new ClusterMembers(State);
            Messaging     = new ClusterMessaging(State, Members);
            Events        = new ClusterEvents(State, Messaging, Members);
            ClusterEvents = new ClusterClusterEvents(State, Members, Events);
            Connections   = new ClusterConnections(State, Members, serializationService);

            _heartbeat = new Heartbeat(State, Members, Messaging, options.Heartbeat, loggerFactory);

            HConsole.Configure(x => x.Set(this, config => config.SetIndent(2).SetPrefix("CLUSTER")));
        }
 /// <summary>
 /// Initializes a new instance of the <see cref="ClusterMembers"/> class.
 /// </summary>
 /// <param name="clusterState">The cluster state.</param>
 public ClusterMembers(ClusterState clusterState)
 {
     _clusterState    = clusterState;
     _addressProvider = new AddressProvider(clusterState.Options.Networking, clusterState.LoggerFactory);
 }
Exemple #17
0
 /// <summary>
 /// Initializes a new instance of the <see cref="ClusterMessaging"/> class.
 /// </summary>
 /// <param name="clusterState">The cluster state.</param>
 /// <param name="clusterMembers">The cluster members.</param>
 public ClusterMessaging(ClusterState clusterState, ClusterMembers clusterMembers)
 {
     _clusterState   = clusterState;
     _clusterMembers = clusterMembers;
 }
 public ObjectLifecycleEventSubscription(ClusterState clusterState, ClusterEvents clusterEvents)
     : base(clusterState, clusterEvents)
 {
     _isSmart = clusterState.Options.Networking.SmartRouting;
 }
Exemple #19
0
 protected EventSubscriptionBase(ClusterState clusterState, ClusterEvents clusterEvents)
 {
     LoggerFactory = clusterState.LoggerFactory;
     ClusterEvents = clusterEvents;
 }
Exemple #20
0
 /// <summary>
 /// Initializes a new instance of the <see cref="ClusterMembers"/> class.
 /// </summary>
 /// <param name="clusterState">The cluster state.</param>
 public ClusterMembers(ClusterState clusterState)
 {
     _clusterState = clusterState;
     _loadBalancer = clusterState.Options.LoadBalancer.Service ?? new RandomLoadBalancer();
 }
 public PartitionLostEventSubscription(ClusterState clusterState, ClusterEvents clusterEvents, ClusterMembers clusterMembers)
     : base(clusterState, clusterEvents)
 {
     _clusterMembers = clusterMembers;
     _isSmart        = clusterState.Options.Networking.SmartRouting;
 }