示例#1
0
        private NodeEndPoints?TryDetermineBestNode(IEnumerable <ClusterMessages.MemberInfoDto> members,
                                                   NodePreference nodePreference)
        {
            var notAllowedStates = new[] {
                ClusterMessages.VNodeState.Manager,
                ClusterMessages.VNodeState.ShuttingDown,
                ClusterMessages.VNodeState.Manager,
                ClusterMessages.VNodeState.Shutdown,
                ClusterMessages.VNodeState.Unknown,
                ClusterMessages.VNodeState.Initializing,
                ClusterMessages.VNodeState.CatchingUp,
                ClusterMessages.VNodeState.ShuttingDown,
                ClusterMessages.VNodeState.PreLeader,
                ClusterMessages.VNodeState.PreReplica,
                ClusterMessages.VNodeState.PreReadOnlyReplica,
                ClusterMessages.VNodeState.Clone
            };

            var nodes = members.Where(x => x.IsAlive)
                        .Where(x => !notAllowedStates.Contains(x.State))
                        .OrderByDescending(x => x.State)
                        .ToArray();

            switch (nodePreference)
            {
            case NodePreference.Random:
                RandomShuffle(nodes, 0, nodes.Length - 1);
                break;

            case NodePreference.Leader:
                nodes = nodes.OrderBy(nodeEntry => nodeEntry.State != ClusterMessages.VNodeState.Leader)
                        .ToArray();                         // OrderBy is a stable sort and only affects order of matching entries
                break;

            case NodePreference.Follower:
                nodes = nodes.OrderBy(nodeEntry =>
                                      nodeEntry.State != ClusterMessages.VNodeState.Follower &&
                                      nodeEntry.State != ClusterMessages.VNodeState.Slave)
                        .ToArray();                         // OrderBy is a stable sort and only affects order of matching entries
                RandomShuffle(nodes, 0,
                              nodes.Count(nodeEntry => nodeEntry.State == ClusterMessages.VNodeState.Follower ||
                                          nodeEntry.State == ClusterMessages.VNodeState.Slave) - 1);
                break;

            case NodePreference.ReadOnlyReplica:
                nodes = nodes.OrderBy(nodeEntry => !IsReadOnlyReplicaState(nodeEntry.State))
                        .ToArray();                         // OrderBy is a stable sort and only affects order of matching entries
                RandomShuffle(nodes, 0,
                              nodes.Count(nodeEntry => IsReadOnlyReplicaState(nodeEntry.State)) - 1);
                break;
            }

            var node = nodes.FirstOrDefault();

            if (node == default(ClusterMessages.MemberInfoDto))
            {
                //_log.Info("Unable to locate suitable node. Gossip info:\n{0}.", string.Join("\n", members.Select(x => x.ToString())));
                return(null);
            }

            var normTcp = new DnsEndPoint(node.ExternalTcpIp, node.ExternalTcpPort);
            var secTcp  = node.ExternalSecureTcpPort > 0
                                ? new DnsEndPoint(node.ExternalTcpIp, node.ExternalSecureTcpPort)
                                : null;

            _log.Info("Discovering: found best choice [{0},{1}] ({2}).", normTcp,
                      secTcp == null ? "n/a" : secTcp.ToString(), node.State);
            return(new NodeEndPoints(normTcp, secTcp));
        }
示例#2
0
        internal ConnectionSettings(ILogger log,
                                    bool verboseLogging,
                                    int maxQueueSize,
                                    int maxConcurrentItems,
                                    int maxRetries,
                                    int maxReconnections,
                                    bool requireLeader,
                                    TimeSpan reconnectionDelay,
                                    TimeSpan queueTimeout,
                                    TimeSpan operationTimeout,
                                    TimeSpan operationTimeoutCheckPeriod,
                                    UserCredentials defaultUserCredentials,
                                    bool useSslConnection,
                                    bool validateServer,
                                    bool failOnNoServerResponse,
                                    TimeSpan heartbeatInterval,
                                    TimeSpan heartbeatTimeout,
                                    TimeSpan clientConnectionTimeout,
                                    string clusterDns,
                                    GossipSeed[] gossipSeeds,
                                    int maxDiscoverAttempts,
                                    int gossipPort,
                                    TimeSpan gossipTimeout,
                                    NodePreference nodePreference,
                                    string compatibilityMode,
                                    HttpMessageHandler customHttpMessageHandler)
        {
            Ensure.NotNull(log, "log");
            Ensure.Positive(maxQueueSize, "maxQueueSize");
            Ensure.Positive(maxConcurrentItems, "maxConcurrentItems");
            if (maxRetries < -1)
            {
                throw new ArgumentOutOfRangeException("maxRetries",
                                                      string.Format("maxRetries value is out of range: {0}. Allowed range: [-1, infinity].", maxRetries));
            }
            if (maxReconnections < -1)
            {
                throw new ArgumentOutOfRangeException("maxReconnections",
                                                      string.Format("maxReconnections value is out of range: {0}. Allowed range: [-1, infinity].",
                                                                    maxRetries));
            }

            if (nodePreference == NodePreference.ReadOnlyReplica && requireLeader)
            {
                throw new ArgumentException($"Having the Node Preference set to {nodePreference} and Requires Leader" +
                                            $" to {requireLeader} will reconnect the client to a leader node once" +
                                            " an operation is performed.");
            }

            Log                         = log;
            VerboseLogging              = verboseLogging;
            MaxQueueSize                = maxQueueSize;
            MaxConcurrentItems          = maxConcurrentItems;
            MaxRetries                  = maxRetries;
            MaxReconnections            = maxReconnections;
            RequireLeader               = requireLeader;
            ReconnectionDelay           = reconnectionDelay;
            QueueTimeout                = queueTimeout;
            OperationTimeout            = operationTimeout;
            OperationTimeoutCheckPeriod = operationTimeoutCheckPeriod;
            ClientConnectionTimeout     = clientConnectionTimeout;
            DefaultUserCredentials      = defaultUserCredentials;
            UseSslConnection            = useSslConnection;
            ValidateServer              = validateServer;

            FailOnNoServerResponse   = failOnNoServerResponse;
            HeartbeatInterval        = heartbeatInterval;
            HeartbeatTimeout         = heartbeatTimeout;
            ClusterDns               = clusterDns;
            GossipSeeds              = gossipSeeds;
            MaxDiscoverAttempts      = maxDiscoverAttempts;
            GossipPort               = gossipPort;
            GossipTimeout            = gossipTimeout;
            NodePreference           = nodePreference;
            CompatibilityMode        = compatibilityMode;
            CustomHttpMessageHandler = customHttpMessageHandler;
        }
示例#3
0
 /// <summary>
 /// Used if connecting with gossip seeds.
 /// </summary>
 /// <param name="gossipSeeds">Endpoints for seeding gossip</param>.
 /// <param name="maxDiscoverAttempts">Maximum number of attempts to discover the cluster</param>.
 /// <param name="gossipTimeout">Timeout for cluster gossip</param>.
 /// <param name="nodePreference">Whether to prefer slave, random, or master node selection</param>.
 internal ClusterSettings(GossipSeed[] gossipSeeds, int maxDiscoverAttempts, TimeSpan gossipTimeout, NodePreference nodePreference)
 {
     ClusterDns          = "";
     MaxDiscoverAttempts = maxDiscoverAttempts;
     ExternalGossipPort  = 0;
     GossipTimeout       = gossipTimeout;
     GossipSeeds         = gossipSeeds;
     NodePreference      = nodePreference;
 }
示例#4
0
        /// <summary>
        /// Used if discovering via DNS.
        /// </summary>
        /// <param name="clusterDns">The DNS name to use for discovering endpoints</param>.
        /// <param name="maxDiscoverAttempts">The maximum number of attempts for discovering endpoints</param>.
        /// <param name="externalGossipPort">The well-known endpoint on which cluster managers are running</param>.
        /// <param name="gossipTimeout">Timeout for cluster gossip</param>.
        /// <param name="nodePreference">Whether to prefer slave, random, or master node selection</param>.
        internal ClusterSettings(string clusterDns, int maxDiscoverAttempts, int externalGossipPort, TimeSpan gossipTimeout, NodePreference nodePreference)
        {
            Ensure.NotNullOrEmpty(clusterDns, "clusterDns");
            if (maxDiscoverAttempts < -1)
            {
                throw new ArgumentOutOfRangeException("maxDiscoverAttempts", string.Format("maxDiscoverAttempts value is out of range: {0}. Allowed range: [-1, infinity].", maxDiscoverAttempts));
            }
            Ensure.Positive(externalGossipPort, "externalGossipPort");

            ClusterDns          = clusterDns;
            MaxDiscoverAttempts = maxDiscoverAttempts;
            ExternalGossipPort  = externalGossipPort;
            GossipTimeout       = gossipTimeout;
            GossipSeeds         = new GossipSeed[0];
            NodePreference      = nodePreference;
        }
示例#5
0
 /// <summary>
 /// Whether to prioritize choosing a follower node that's alive from the known nodes.
 /// </summary>
 /// <returns>A <see cref="DnsClusterSettingsBuilder"/> for further configuration.</returns>
 public DnsClusterSettingsBuilder PreferFollowerNode()
 {
     _nodePreference = NodePreference.Follower;
     return(this);
 }
示例#6
0
 /// <summary>
 /// Whether to prioritize choosing a read only replica that's alive from the known nodes.
 /// </summary>
 /// <returns>A <see cref="DnsClusterSettingsBuilder"/> for further configuration.</returns>
 public DnsClusterSettingsBuilder PreferReadOnlyReplica()
 {
     _nodePreference = NodePreference.ReadOnlyReplica;
     return(this);
 }
 /// <summary>
 /// hether to prioritize choosing a slave node that's alive from the known nodes.
 /// </summary>
 /// <returns>A <see cref="GossipSeedClusterSettingsBuilder"/> for further configuration.</returns>
 public GossipSeedClusterSettingsBuilder PreferSlaveNode()
 {
     _nodePreference = NodePreference.Slave;
     return(this);
 }
示例#8
0
 /// <summary>
 /// Whether to randomly choose a node that's alive from the known nodes.
 /// </summary>
 /// <returns>A <see cref="DnsClusterSettingsBuilder"/> for further configuration.</returns>
 public DnsClusterSettingsBuilder PreferRandomNode()
 {
     _nodePreference = NodePreference.Random;
     return(this);
 }
示例#9
0
 /// <summary>
 /// Whether to prioritize choosing a follower node that's alive from the known nodes.
 /// </summary>
 /// <returns>A <see cref="ConnectionSettingsBuilder"/> for further configuration.</returns>
 public ConnectionSettingsBuilder PreferFollowerNode()
 {
     _nodePreference = NodePreference.Follower;
     _requireLeader  = false;
     return(this);
 }
示例#10
0
 /// <summary>
 /// Whether to prioritize choosing a read only replica that's alive from the known nodes.
 /// </summary>
 /// <returns>A <see cref="ConnectionSettingsBuilder"/> for further configuration.</returns>
 public ConnectionSettingsBuilder PreferReadOnlyReplica()
 {
     _nodePreference = NodePreference.ReadOnlyReplica;
     _requireLeader  = false;
     return(this);
 }
示例#11
0
 /// <summary>
 /// Whether to randomly choose a node that's alive from the known nodes.
 /// </summary>
 /// <returns>A <see cref="ConnectionSettingsBuilder"/> for further configuration.</returns>
 public ConnectionSettingsBuilder PreferRandomNode()
 {
     _nodePreference = NodePreference.Random;
     return(this);
 }
 /// <summary>
 /// Whether to prioritize choosing a follower node that's alive from the known nodes.
 /// </summary>
 /// <returns>A <see cref="ConnectionSettingsBuilder"/> for further configuration.</returns>
 public ConnectionSettingsBuilder PreferFollowerNode()
 {
     _nodePreference = NodePreference.Follower;
     return(this);
 }
 /// <summary>
 /// Whether to prioritize choosing a slave node that's alive from the known nodes.
 /// </summary>
 /// <returns>A <see cref="DnsClusterSettingsBuilder"/> for further configuration.</returns>
 public ConnectionSettingsBuilder PreferSlaveNode()
 {
     _nodePreference = NodePreference.Slave;
     return(this);
 }
示例#14
0
 internal SimpleNodeDrawing(TNode element, NodePreference preferences, SimpleNodeSizesPreCalc cache, IElementSelectionChecker selectionChecker, ISelectableElementRegister selectableElementRegister) : base(element, preferences, cache, selectableElementRegister, selectionChecker)
 {
     _preferences = preferences;
     _cache       = cache;
 }
示例#15
0
        internal ConnectionSettings(ILogger log,
                                    bool verboseLogging,
                                    int maxQueueSize,
                                    int maxConcurrentItems,
                                    int maxRetries,
                                    int maxReconnections,
                                    bool requireMaster,
                                    TimeSpan reconnectionDelay,
                                    TimeSpan queueTimeout,
                                    TimeSpan operationTimeout,
                                    TimeSpan operationTimeoutCheckPeriod,
                                    UserCredentials defaultUserCredentials,
                                    bool useSslConnection,
                                    string targetHost,
                                    bool validateServer,
                                    bool failOnNoServerResponse,
                                    TimeSpan heartbeatInterval,
                                    TimeSpan heartbeatTimeout,
                                    TimeSpan clientConnectionTimeout,
                                    string clusterDns,
                                    GossipSeed[] gossipSeeds,
                                    int maxDiscoverAttempts,
                                    int externalGossipPort,
                                    TimeSpan gossipTimeout,
                                    NodePreference nodePreference)
        {
            Ensure.NotNull(log, "log");
            Ensure.Positive(maxQueueSize, "maxQueueSize");
            Ensure.Positive(maxConcurrentItems, "maxConcurrentItems");
            if (maxRetries < -1)
            {
                throw new ArgumentOutOfRangeException("maxRetries",
                                                      string.Format("maxRetries value is out of range: {0}. Allowed range: [-1, infinity].", maxRetries));
            }
            if (maxReconnections < -1)
            {
                throw new ArgumentOutOfRangeException("maxReconnections",
                                                      string.Format("maxReconnections value is out of range: {0}. Allowed range: [-1, infinity].",
                                                                    maxRetries));
            }
            if (useSslConnection)
            {
                Ensure.NotNullOrEmpty(targetHost, "targetHost");
            }
            Log                         = log;
            VerboseLogging              = verboseLogging;
            MaxQueueSize                = maxQueueSize;
            MaxConcurrentItems          = maxConcurrentItems;
            MaxRetries                  = maxRetries;
            MaxReconnections            = maxReconnections;
            RequireMaster               = requireMaster;
            ReconnectionDelay           = reconnectionDelay;
            QueueTimeout                = queueTimeout;
            OperationTimeout            = operationTimeout;
            OperationTimeoutCheckPeriod = operationTimeoutCheckPeriod;
            ClientConnectionTimeout     = clientConnectionTimeout;
            DefaultUserCredentials      = defaultUserCredentials;
            UseSslConnection            = useSslConnection;
            TargetHost                  = targetHost;
            ValidateServer              = validateServer;

            FailOnNoServerResponse = failOnNoServerResponse;
            HeartbeatInterval      = heartbeatInterval;
            HeartbeatTimeout       = heartbeatTimeout;
            ClusterDns             = clusterDns;
            GossipSeeds            = gossipSeeds;
            MaxDiscoverAttempts    = maxDiscoverAttempts;
            ExternalGossipPort     = externalGossipPort;
            GossipTimeout          = gossipTimeout;
            NodePreference         = nodePreference;
        }