Beispiel #1
0
        public void Setup()
        {
#if !NET_CORE
            CallContext.LogicalSetData(CallContextKey, "Fail");
#endif

            var dummyExecutionContext = ExecutionContext.Capture();

#if !NET_CORE
            CallContext.FreeNamedDataSlot(CallContextKey);
#endif

            var nodeMock = new Mock <IMemcacheNode>();
            nodeMock.Setup(n => n.EndPoint).Returns(new IPEndPoint(new IPAddress(new byte[] { 127, 0, 0, 1 }), 11211));
            nodeMock.Setup(n => n.IsDead).Returns(false);
            nodeMock.Setup(n => n.TrySend(It.IsAny <IMemcacheRequest>(), It.IsAny <int>()))
            .Callback((IMemcacheRequest req, int timeout) => ExecutionContext.Run(dummyExecutionContext, _ => req.HandleResponse(_responseHeader, _key, _extra, _message), null))
            .Returns(true);
            _nodeMock = nodeMock.Object;

            var locatorMoq = new Mock <INodeLocator>();
            locatorMoq.Setup(l => l.Locate(It.IsAny <IMemcacheRequest>())).Returns(Enumerable.Repeat(_nodeMock, 1));
            _locatorMock = locatorMoq.Object;

            var clusterMoq = new Mock <IMemcacheCluster>();
            clusterMoq.Setup(c => c.Locator).Returns(_locatorMock);
            clusterMoq.Setup(c => c.Nodes).Returns(Enumerable.Repeat(_nodeMock, 1));
            _clusterMock = clusterMoq.Object;

            _key            = null;
            _extra          = null;
            _message        = null;
            _responseHeader = default(MemcacheResponseHeader);
        }
        public void TransportDeadThenAliveTest()
        {
            IMemcacheNode theNode   = null;
            FakeTransport transport = new FakeTransport();

            transport.Kill();

            // Memcache client config
            var config = new MemcacheClientConfiguration
            {
                DeadTimeout      = TimeSpan.FromSeconds(1),
                TransportFactory = transport.Factory,
                NodeFactory      = (e, c) => MemcacheClientConfiguration.DefaultNodeFactory(e, c),
                PoolSize         = 1,
            };

            theNode = config.NodeFactory(null, config);
            Assert.IsFalse(theNode.IsDead, "The node should be alive before any failure");

            Assert.IsFalse(theNode.TrySend(null, 1), "The TrySend should fail with a broken transport");
            Assert.IsTrue(theNode.IsDead, "The node should be dead after the first send failed");

            transport.Resurect();
            Assert.IsFalse(theNode.IsDead, "The node should be alive after the transport resurected");
            Assert.IsTrue(theNode.TrySend(null, 1), "The TrySend should be able to send a request after the transport is up again");

            transport.Kill();
            Assert.IsFalse(theNode.TrySend(null, 1), "The TrySend should fail with a killed transport");
            Assert.IsTrue(theNode.IsDead, "The node should be dead after the a send failed");
        }
 private void OnNodeError(IMemcacheNode node)
 {
     if (NodeError != null)
     {
         NodeError(node);
     }
 }
Beispiel #4
0
        /// <summary>
        /// This function gets rid of successive keys that reference the same node.
        /// This is a slight performance improvement for the LocateNode function.
        /// </summary>
        /// <returns></returns>
        public static uint[] CleanRepeatedNodes(List <uint> sortedKeys, Dictionary <uint, IMemcacheNode> keyToServer)
        {
            int Length = sortedKeys.Count;

            if (Length == 0)
            {
                return(new uint[0]);
            }

            Stack <uint>  keyStack     = new Stack <uint>(Length);
            uint          previousKey  = sortedKeys[0];
            IMemcacheNode previousNode = keyToServer[previousKey];

            // Traverse the list of keys backwards
            for (int idx = Length - 1; idx >= 0; idx--)
            {
                uint          currentKey  = sortedKeys[idx];
                IMemcacheNode currentNode = keyToServer[currentKey];
                if (currentNode != previousNode)
                {
                    keyStack.Push(currentKey);
                    previousNode = currentNode;
                }
                previousKey = currentKey;
            }

            // Treat the case where all keys point to the same node
            if (keyStack.Count == 0)
            {
                keyStack.Push(sortedKeys[0]);
            }

            return(keyStack.ToArray());
        }
Beispiel #5
0
        public void Setup()
        {
            var nodeMock = new Mock <IMemcacheNode>();

            nodeMock.Setup(n => n.EndPoint).Returns(new IPEndPoint(new IPAddress(new byte[] { 127, 0, 0, 1 }), 11211));
            nodeMock.Setup(n => n.IsDead).Returns(false);
            nodeMock.Setup(n => n.TrySend(It.IsAny <IMemcacheRequest>(), It.IsAny <int>()))
            .Callback((IMemcacheRequest req, int timeout) => req.HandleResponse(_responseHeader, _key, _extra, _message))
            .Returns(true);
            _nodeMock = nodeMock.Object;

            var locatorMoq = new Mock <INodeLocator>();

            locatorMoq.Setup(l => l.Locate(It.IsAny <IMemcacheRequest>())).Returns(Enumerable.Repeat(_nodeMock, 1));
            _locatorMock = locatorMoq.Object;

            var clusterMoq = new Mock <IMemcacheCluster>();

            clusterMoq.Setup(c => c.Locator).Returns(_locatorMock);
            clusterMoq.Setup(c => c.Nodes).Returns(Enumerable.Repeat(_nodeMock, 1));
            _clusterMock = clusterMoq.Object;

            _key            = null;
            _extra          = null;
            _message        = null;
            _responseHeader = default(MemcacheResponseHeader);
        }
 private void UnregisterEvents(IMemcacheNode node)
 {
     node.MemcacheError  -= OnMemcacheError;
     node.TransportError -= OnTransportError;
     node.NodeDead       -= OnNodeError;
 }
 private void RegisterEvents(IMemcacheNode node)
 {
     node.MemcacheError  += OnMemcacheError;
     node.TransportError += OnTransportError;
     node.NodeDead       += NodeError;
 }
Beispiel #8
0
        /// <summary>
        /// Enumerate server nodes in the order they appear in the consistent hashing table.
        /// </summary>
        /// <param name="ld">Consistent hashing lookup table</param>
        /// <param name="itemKeyHash">Hash key used to identify the first server node to be returned by the function</param>
        /// <returns></returns>
        private static IEnumerable <IMemcacheNode> LocateNode(LookupData ld, uint itemKeyHash)
        {
            // get the index of the server assigned to this hash
            int                     foundIndex = Array.BinarySearch <uint>(ld.sortedKeys, itemKeyHash);
            IMemcacheNode           node1      = null;
            IMemcacheNode           node2      = null;
            HashSet <IMemcacheNode> usedNodes  = null;

            // no exact match
            if (foundIndex < 0)
            {
                // this is the next greater index in the list
                foundIndex = ~foundIndex;

                if (foundIndex >= ld.sortedKeys.Length)
                {
                    // the key was larger than all server keys, so return the first server
                    foundIndex = 0;
                }
            }

            // Paranoid check
            if (foundIndex < 0 || foundIndex >= ld.sortedKeys.Length)
            {
                yield break;
            }

            // Return distinct nodes. Exit after a complete loop over the keys.
            int startingIndex = foundIndex;

            do
            {
                IMemcacheNode node = ld.keyToServer[ld.sortedKeys[foundIndex]];
                if (node1 == null)
                {
                    node1 = node;
                    yield return(node1);
                }
                else if (node2 == null)
                {
                    // Because the list of keys is filtered with function CleanRepeatedNodes, we have node2 != node1
                    node2 = node;
                    yield return(node2);
                }
                else
                {
                    if (usedNodes == null)
                    {
                        usedNodes = new HashSet <IMemcacheNode>()
                        {
                            node1, node2
                        };
                    }
                    if (!usedNodes.Contains(node))
                    {
                        usedNodes.Add(node);
                        yield return(node);
                    }
                }

                foundIndex++;
                if (foundIndex >= ld.sortedKeys.Length)
                {
                    foundIndex = 0;
                }
            } while (foundIndex != startingIndex);
        }
Beispiel #9
0
        public void Setup()
        {
            var nodeMock = new Mock<IMemcacheNode>();
            nodeMock.Setup(n => n.EndPoint).Returns(new IPEndPoint(new IPAddress(new byte[] { 127, 0, 0, 1 }), 11211));
            nodeMock.Setup(n => n.IsDead).Returns(false);
            nodeMock.Setup(n => n.TrySend(It.IsAny<IMemcacheRequest>(), It.IsAny<int>()))
                .Callback((IMemcacheRequest req, int timeout) => req.HandleResponse(_responseHeader, _key, _extra, _message))
                .Returns(true);
            _nodeMock = nodeMock.Object;

            var locatorMoq = new Mock<INodeLocator>();
            locatorMoq.Setup(l => l.Locate(It.IsAny<IMemcacheRequest>())).Returns(Enumerable.Repeat(_nodeMock, 1));
            _locatorMock = locatorMoq.Object;

            var clusterMoq = new Mock<IMemcacheCluster>();
            clusterMoq.Setup(c => c.Locator).Returns(_locatorMock);
            clusterMoq.Setup(c => c.Nodes).Returns(Enumerable.Repeat(_nodeMock, 1));
            _clusterMock = clusterMoq.Object;

            _key = null;
            _extra = null;
            _message = null;
            _responseHeader = default(MemcacheResponseHeader);
        }