コード例 #1
0
        public void SetUp()
        {
            var port = int.Parse(ConfigurationManager.AppSettings["port"]);
            var address = ConfigurationManager.AppSettings["address"];

            IPAddress ipAddress;
            if (!IPAddress.TryParse(address, out ipAddress))
            {
                throw new ArgumentException("endpoint");
            }

            //Use defaults
            var endpoint = new IPEndPoint(ipAddress, port);
            ISocketPoolConfiguration config = new SocketPoolConfiguration();
            _node = new CouchbaseNode(endpoint, config);
        }
コード例 #2
0
        public SocketPool(IMemcachedNode node, ISocketPoolConfiguration config, ISaslAuthenticationProvider provider)
        {
            if (config.MinPoolSize < 0)
                throw new InvalidOperationException("MinPoolSize must be larger >= 0", null);
            if (config.MaxPoolSize < config.MinPoolSize)
                throw new InvalidOperationException("MaxPoolSize must be larger than MinPoolSize", null);
            if (config.QueueTimeout < TimeSpan.Zero)
                throw new InvalidOperationException("queueTimeout must be >= TimeSpan.Zero", null);

            _provider = provider;
            _node = node;
            _config = config;
            _queue = new Queue<IPooledSocket>(config.MaxPoolSize);
            _isAlive = true;
            PreAllocate(config.MinPoolSize);
        }
コード例 #3
0
        void IMemcachedNodeLocator.Initialize(IList<IMemcachedNode> nodes)
        {
            if (this.isInitialized)
                throw new InvalidOperationException("Instance is already initialized.");

            // locking on this is rude but easy
            lock (initLock)
            {
                if (this.isInitialized)
                    throw new InvalidOperationException("Instance is already initialized.");

                if (nodes.Count > 0)
                    node = nodes[0];

                this.isInitialized = true;
            }
        }
コード例 #4
0
        IEnumerable<IMemcachedNode> IMemcachedNodeLocator.GetWorkingNodes()
        {
            var nodes = this.nodes;
            var retval = new IMemcachedNode[nodes.Length];

            Array.Copy(nodes, retval, retval.Length);

            return retval;
        }
コード例 #5
0
        /// <summary>
        /// Get the next available node for the given one. For the last node
        /// the first one is returned. If this list contains only a 
        /// single node, conceptionally there's no next node, so null 
        /// is returned.
        /// </summary>
        private IMemcachedNode FindNextNodeForBackup(IMemcachedNode primaryNode)
        {
            if (primaryNode == null || _allServers.Count == 1)
            {
                return null;
            }

            var idx = _allServers.FindIndex(v => v.EndPoint.Equals(primaryNode.EndPoint));
            var nextIdx = (idx == _allServers.Count - 1) ? 0 : idx + 1;
            var backupNode = _allServers[nextIdx];
            if (backupNode.EndPoint.Equals(primaryNode.EndPoint))
            {
                backupNode = null;
            }

            return backupNode;
        }
コード例 #6
0
 public SocketPool(IMemcachedNode node, ISocketPoolConfiguration config)
     : this(node, config, null)
 {
 }
コード例 #7
0
 public INodeFailurePolicy Create(IMemcachedNode node)
 {
     return PolicyInstance;
 }
コード例 #8
0
		INodeFailurePolicy INodeFailurePolicyFactory.Create(IMemcachedNode node)
		{
			return PolicyInstance;
		}
コード例 #9
0
 INodeFailurePolicy INodeFailurePolicyFactory.Create(IMemcachedNode node)
 {
     return(PolicyInstance);
 }
コード例 #10
0
 private void NodeFailedEvent(IMemcachedNode memcachedNode)
 {
     _logger.Error("Node unavailable");
 }
コード例 #11
0
        private bool ExecuteWithRedirect(IMemcachedNode startNode, ISingleItemOperation op)
        {
            if (startNode.Execute(op)) return true;

            var iows = op as IOperationWithState;

            // different op factory, we do not know how to retry
            if (iows == null)
                return false;

            #if HAS_FORWARD_MAP
            // node responded with invalid vbucket
            // this should happen only when a node is in a transitioning state
            if (iows.State == OpState.InvalidVBucket)
            {
                // check if we have a forward-locator
                // (whihc supposedly reflects the state of the cluster when all vbuckets have been migrated succesfully)
                IMemcachedNodeLocator fl = this.nsPool.ForwardLocator;
                if (fl != null)
                {
                    var nextNode = fl.Locate(op.Key);
                    if (nextNode != null)
                    {
                        // the node accepted the requesta
                        if (nextNode.Execute(op)) return true;
                    }
                }
            }
            #endif
            // still invalid vbucket, try all nodes in sequence
            if (iows.State == OperationState.InvalidVBucket)
            {
                var nodes = this.Pool.GetWorkingNodes();

                foreach (var node in nodes)
                {
                    if (node.Execute(op))
                        return true;

                    // the node accepted our request so quit
                    if (iows.State != OperationState.InvalidVBucket)
                        break;
                }
            }

            return false;
        }
コード例 #12
0
        private void NodeFail(IMemcachedNode node)
        {
            var warnEnabled = log.IsWarnEnabled;

            if (warnEnabled)
            {
                log.WarnFormat("Node {0} is dead.", node.EndPoint);
            }

            // block the rest api listener until we're finished here
            lock (_syncObj)
            {
                var currentState = this.state;

                // the pool has been already reinitialized by the time the node
                // reported its failure, thus it has no connection to the current state
                if (currentState == null || currentState == InternalState.Empty)
                {
                    return;
                }

                var fail = this.nodeFailed;
                if (fail != null)
                {
                    fail(node);
                }

                // we don't know who to reconfigure the pool when vbucket is
                // enabled, so operations targeting the dead servers will fail.
                // when we have a normal config we just reconfigure the locator,
                // so the items will be rehashed to the working servers
                if (!currentState.IsVbucket)
                {
                    if (warnEnabled)
                    {
                        log.Warn("We have a standard config, so we'll recreate the node locator.");
                    }

                    ReinitializeLocator(currentState);
                }

                // the timer is stopped until we encounter the first dead server
                // when we have one, we trigger it and it will run after DeadTimeout has elapsed
                if (!this.isTimerActive)
                {
                    if (warnEnabled)
                    {
                        log.Warn("Starting the recovery timer.");
                    }

                    if (this.resurrectTimer == null)
                    {
                        this.resurrectTimer = new Timer(this.rezCallback, null, this.deadTimeoutMsec, Timeout.Infinite);
                    }
                    else
                    {
                        this.resurrectTimer.Change(this.deadTimeoutMsec, Timeout.Infinite);
                    }

                    this.isTimerActive = true;

                    if (warnEnabled)
                    {
                        log.Warn("Timer started.");
                    }
                }
            }

            if (warnEnabled)
            {
                log.Warn("Fail handler is finished.");
            }
        }
コード例 #13
0
        private void SetNodeDead(IMemcachedNode n1, List<IMemcachedNode> activeNodes)
        {
            // Having to use reflection to set a private field
            var prop = n1.GetType().GetField("internalPoolImpl", BindingFlags.NonPublic | BindingFlags.Instance);
            var internalPoolImpl = prop.GetValue(n1);
            var prop2 = internalPoolImpl.GetType().GetField("isAlive", BindingFlags.NonPublic | BindingFlags.Instance);
            prop2.SetValue(internalPoolImpl, false);

            locator = new SessionNodeLocator();
            locator.Initialize(activeNodes);
        }
コード例 #14
0
 public SocketPool(IMemcachedNode node, ISocketPoolConfiguration config)
     : this(node, config, null)
 {
 }
コード例 #15
0
        private bool NotEqual(IMemcachedNode first, IMemcachedNode second)
        {
            if (first == null && second == null)
            {
                return false;
            }

            if (first == null || second == null)
            {
                return true;
            }

            return !first.EndPoint.Equals(second.EndPoint);
        }
コード例 #16
0
        private void NodeFail(IMemcachedNode node)
        {
            var warnEnabled = log.IsWarnEnabled;
            if (warnEnabled) log.WarnFormat("Node {0} is dead.", node.EndPoint);

            // block the rest api listener until we're finished here
            lock (_syncObj)
            {
                var currentState = this.state;

                // the pool has been already reinitialized by the time the node
                // reported its failure, thus it has no connection to the current state
                if (currentState == null || currentState == InternalState.Empty) return;

                var fail = this.nodeFailed;
                if (fail != null)
                    fail(node);

                // we don't know who to reconfigure the pool when vbucket is
                // enabled, so operations targeting the dead servers will fail.
                // when we have a normal config we just reconfigure the locator,
                // so the items will be rehashed to the working servers
                if (!currentState.IsVbucket)
                {
                    if (warnEnabled) log.Warn("We have a standard config, so we'll recreate the node locator.");

                    ReinitializeLocator(currentState);
                }

                // the timer is stopped until we encounter the first dead server
                // when we have one, we trigger it and it will run after DeadTimeout has elapsed
                if (!this.isTimerActive)
                {
                    if (warnEnabled) log.Warn("Starting the recovery timer.");

                    if (this.resurrectTimer == null)
                        this.resurrectTimer = new Timer(this.rezCallback, null, this.deadTimeoutMsec, Timeout.Infinite);
                    else
                        this.resurrectTimer.Change(this.deadTimeoutMsec, Timeout.Infinite);

                    this.isTimerActive = true;

                    if (warnEnabled) log.Warn("Timer started.");
                }
            }

            if (warnEnabled) log.Warn("Fail handler is finished.");
        }
コード例 #17
0
        IEnumerable<IMemcachedNode> IMemcachedNodeLocator.GetWorkingNodes()
        {
            var ld = this.lookupData;

            if (ld.Servers == null || ld.Servers.Length == 0)
                return Enumerable.Empty<IMemcachedNode>();

            var retval = new IMemcachedNode[ld.Servers.Length];
            Array.Copy(ld.Servers, retval, retval.Length);

            return retval;
        }
コード例 #18
0
        private void NodeFail(IMemcachedNode node)
        {
            var isDebug = log.IsDebugEnabled;

            if (isDebug)
            {
                log.DebugFormat("Node {0} is dead.", node.EndPoint);
            }

            // the timer is stopped until we encounter the first dead server
            // when we have one, we trigger it and it will run after DeadTimeout has elapsed
            lock (this.DeadSync)
            {
                if (this.isDisposed)
                {
                    if (log.IsWarnEnabled)
                    {
                        log.Warn("Got a node fail but the pool is already disposed. Ignoring.");
                    }

                    return;
                }

                // bubble up the fail event to the client
                var fail = this.nodeFailed;
                if (fail != null)
                {
                    fail(node);
                }

                // re-initialize the locator
                var newLocator = this.configuration.CreateNodeLocator();
                newLocator.Initialize(allNodes.Where(n => n.IsAlive).ToArray());
                Interlocked.Exchange(ref this.nodeLocator, newLocator);

                // the timer is stopped until we encounter the first dead server
                // when we have one, we trigger it and it will run after DeadTimeout has elapsed
                if (!this.isTimerActive)
                {
                    if (isDebug)
                    {
                        log.Debug("Starting the recovery timer.");
                    }

                    if (this.resurrectTimer == null)
                    {
                        this.resurrectTimer = new Timer(this.rezCallback, null, this.deadTimeoutMsec, Timeout.Infinite);
                    }
                    else
                    {
                        this.resurrectTimer.Change(this.deadTimeoutMsec, Timeout.Infinite);
                    }

                    this.isTimerActive = true;

                    if (isDebug)
                    {
                        log.Debug("Timer started.");
                    }
                }
            }
        }
コード例 #19
0
		private void NodeFail(IMemcachedNode node)
		{
			var isDebug = log.IsDebugEnabled;
			if (isDebug) log.DebugFormat("Node {0} is dead.", node.EndPoint);

			// block the rest api listener until we're finished here
			lock (this.DeadSync)
			{
				var currentState = this.state;

				// we don't know who to reconfigure the sockIOPool when vbucket is
				// enabled, so operations targeting the dead servers will fail.
				// when we have a normal config we just reconfigure the locator,
				// so the items will be rehashed to the working servers
				if (!currentState.IsVbucket)
				{
					if (isDebug) log.Debug("We have a standard config, so we'll recreate the node locator.");

					ReinitializeLocator(currentState);
				}

				// the timer is stopped until we encounter the first dead server
				// when we have one, we trigger it and it will run after DeadTimeout has elapsed
				if (!this.isTimerActive)
				{
					if (isDebug) log.Debug("Starting the recovery timer.");

					if (this.resurrectTimer == null)
						this.resurrectTimer = new Timer(this.rezCallback, null, this.deadTimeoutMsec, Timeout.Infinite);
					else
						this.resurrectTimer.Change(this.deadTimeoutMsec, Timeout.Infinite);

					this.isTimerActive = true;

					if (isDebug) log.Debug("Timer started.");
				}
			}

			if (isDebug) log.Debug("Fail handler is finished.");
		}
コード例 #20
0
			INodeFailurePolicy INodeFailurePolicyFactory.Create(IMemcachedNode node)
			{
				return new FakePolicy();
			}
コード例 #21
0
        private void NodeFail(IMemcachedNode node)
        {
            var isDebug = log.IsDebugEnabled;
            if (isDebug) log.DebugFormat("Node {0} is dead.", node.EndPoint);

            // the timer is stopped until we encounter the first dead server
            // when we have one, we trigger it and it will run after DeadTimeout has elapsed
            lock (DeadSync)
            {
                // re-initialize the locator
                // TEST
                var newLocator = this.configuration.CreateNodeLocator();
                newLocator.Initialize(allNodes.Where(n => n.IsAlive).ToArray());
                Interlocked.Exchange(ref this.nodeLocator, newLocator);
                // TEST

                // the timer is stopped until we encounter the first dead server
                // when we have one, we trigger it and it will run after DeadTimeout has elapsed
                if (!this.isTimerActive)
                {
                    if (isDebug) log.Debug("Starting the recovery timer.");

                    if (this.resurrectTimer == null)
                        this.resurrectTimer = new Timer(this.rezCallback, null, this.deadTimeoutMsec, Timeout.Infinite);
                    else
                        this.resurrectTimer.Change(this.deadTimeoutMsec, Timeout.Infinite);

                    this.isTimerActive = true;

                    if (isDebug) log.Debug("Timer started.");
                }
            }
        }
コード例 #22
0
 private void _memcachedClient_NodeFailed(IMemcachedNode obj)
 {
     _logger.LogCritical("Memcached Node Failure - {Node} has failed to respond", obj.EndPoint);
 }
コード例 #23
0
		private void NodeFail(IMemcachedNode node)
		{
			var isDebug = log.IsDebugEnabled;
			if (isDebug) log.DebugFormat("Node {0} is dead.", node.EndPoint);

			// the timer is stopped until we encounter the first dead server
			// when we have one, we trigger it and it will run after DeadTimeout has elapsed
			lock (this.DeadSync)
			{
				if (this.isDisposed)
				{
					if (log.IsWarnEnabled) log.Warn("Got a node fail but the pool is already disposed. Ignoring.");

					return;
				}

				// bubble up the fail event to the client
				var fail = this.nodeFailed;
				if (fail != null)
					fail(node);

				// re-initialize the locator
				var newLocator = this.configuration.CreateNodeLocator();
				newLocator.Initialize(allNodes.Where(n => n.IsAlive).ToArray());
				Interlocked.Exchange(ref this.nodeLocator, newLocator);

				// the timer is stopped until we encounter the first dead server
				// when we have one, we trigger it and it will run after DeadTimeout has elapsed
				if (!this.isTimerActive)
				{
					if (isDebug) log.Debug("Starting the recovery timer.");

					if (this.resurrectTimer == null)
						this.resurrectTimer = new Timer(this.rezCallback, null, this.deadTimeoutMsec, Timeout.Infinite);
					else
						this.resurrectTimer.Change(this.deadTimeoutMsec, Timeout.Infinite);

					this.isTimerActive = true;

					if (isDebug) log.Debug("Timer started.");
				}
			}
		}
コード例 #24
0
 INodeFailurePolicy INodeFailurePolicyFactory.Create(IMemcachedNode node)
 {
     return(new ThrottlingFailurePolicy(this.ResetAfter, this.FailureThreshold));
 }
コード例 #25
0
		private static uint[] GenerateKeys(IMemcachedNode node, int numberOfKeys)
		{
			const int KeyLength = 4;
			const int PartCount = 1; // (ModifiedFNV.HashSize / 8) / KeyLength; // HashSize is in bits, uint is 4 byte long

			var k = new uint[PartCount * numberOfKeys];

			// every server is registered numberOfKeys times
			// using UInt32s generated from the different parts of the hash
			// i.e. hash is 64 bit:
			// 00 00 aa bb 00 00 cc dd
			// server will be stored with keys 0x0000aabb & 0x0000ccdd
			// (or a bit differently based on the little/big indianness of the host)
			string address = node.EndPoint.ToString();
			var fnv = new FNV1a();

			for (int i = 0; i < numberOfKeys; i++)
			{
				byte[] data = fnv.ComputeHash(Encoding.ASCII.GetBytes(String.Concat(address, "-", i)));

				for (int h = 0; h < PartCount; h++)
				{
					k[i * PartCount + h] = BitConverter.ToUInt32(data, h * KeyLength);
				}
			}

			return k;
		}
コード例 #26
0
        private IOperationResult ExecuteWithRedirect(IMemcachedNode startNode, ISingleItemOperation op)
        {
            var result = new BinaryOperationResult();

            var opResult = startNode.Execute(op);

            if (opResult.Success)
            {
                return(result.Pass());
            }

            var iows = op as IOperationWithState;

            // different op factory, we do not know how to retry
            if (iows == null)
            {
                result.InnerResult = opResult.InnerResult;
                return(result.Fail("Operation state was invalid"));
            }

#if HAS_FORWARD_MAP
            // node responded with invalid vbucket
            // this should happen only when a node is in a transitioning state
            if (iows.State == OpState.InvalidVBucket)
            {
                // check if we have a forward-locator
                // (whihc supposedly reflects the state of the cluster when all vbuckets have been migrated succesfully)
                IMemcachedNodeLocator fl = this.nsPool.ForwardLocator;
                if (fl != null)
                {
                    var nextNode = fl.Locate(op.Key);
                    if (nextNode != null)
                    {
                        // the node accepted the requesta
                        if (nextNode.Execute(op))
                        {
                            return(true);
                        }
                    }
                }
            }
#endif
            // still invalid vbucket, try all nodes in sequence
            if (iows.State == OperationState.InvalidVBucket)
            {
                var nodes = this.Pool.GetWorkingNodes();

                foreach (var node in nodes)
                {
                    opResult = node.Execute(op);
                    if (opResult.Success)
                    {
                        return(result.Pass());
                    }

                    // the node accepted our request so quit
                    if (iows.State != OperationState.InvalidVBucket)
                    {
                        break;
                    }
                }
            }

            //TODO: why would this happen?
            return(result.Fail("Failed to execute operation"));
        }
コード例 #27
0
 private void MemcachedClient_NodeFailed(IMemcachedNode obj)
 {
     throw new Exception($"ElastiCache endpoint: {obj.EndPoint} failed: {obj}");
 }
コード例 #28
0
 INodeFailurePolicy INodeFailurePolicyFactory.Create(IMemcachedNode node) => PolicyInstance;