Esempio n. 1
0
        /// <summary>
        /// Get the data node that owns this key
        /// </summary>
        /// <remarks>
        /// Virtual nodes are on a 32 bit ring.  Find the location
        /// of the key's hash and the node that owns it is the first node
        /// we find from that point upwards.
        /// </remarks>
        private static Node GetNodeForKey(string key)
        {
            Node returnValue = null;

            int hashCode = CacheBase.GetConsistentHashCode(key);

            var keys = CacheBase.RingNodes.Keys;

            for (int i = 0; i < keys.Count; i++)
            {
                if (keys[i] >= hashCode)
                {
                    if (CacheBase.RingNodes.ContainsKey(keys[i]))
                    {
                        returnValue = CacheBase.RingNodes[keys[i]];
                    }

                    break;
                }
            }

            if (returnValue == null)
            {
                returnValue = CacheBase.RingNodes[keys[0]];
            }

            return(returnValue);
        }
Esempio n. 2
0
        private Response NodeUnreachable(string hostname, int port)
        {
            //  MessageType     byte (2)
            //  DataLength      int
            //  Data            byte[]
            //      HostLen         int
            //      Host            byte[] UTF8 string
            //      Port            int

            byte[] data = null;
            using (MemoryStream ms = new MemoryStream())
            {
                BinaryWriter w = new BinaryWriter(ms);

                byte[] hostBytes = CacheBase.WriteHostName(hostname);
                w.Write(IPAddress.HostToNetworkOrder(hostBytes.Length));
                w.Write(hostBytes);
                w.Write(IPAddress.HostToNetworkOrder(port));

                w.Flush();
                ms.Flush();
                data = ms.ToArray();
            }

            Request request = new Request(Request.Types.NodeUnreachable, data);

            return(this.SendRequest(this.MasterHostName, this.MasterPort, request));
        }
Esempio n. 3
0
        protected Response SendRequest(string hostname, int port, Request request)
        {
            IPEndPoint ipep = CacheBase.GetIPEndPoint(hostname, port);

            if (ipep != null)
            {
                using (TcpClient client = new TcpClient())
                {
                    try
                    {
                        //client.ReceiveTimeout = 5000;
                        client.SendTimeout = 5000;

                        client.Connect(ipep);

                        using (NetworkStream stream = client.GetStream())
                        {
                            this.WriteRequest(stream, request);
                            return(this.ReadResponse(stream));
                        }
                    }
                    catch (SocketException)
                    {
                    }
                }
            }

            return(null);
        }
Esempio n. 4
0
        /// <summary>
        /// Removes an item from the Cache.
        /// </summary>
        public bool Remove(string key)
        {
            Request request  = new Request(Request.Types.DeleteObject, key, CacheBase.ToByteArray(key));
            var     response = base.SendOrQueueNodeRequest(request);

            if (response == null)
            {
                return(false);
            }

            return(response.Type == Response.Types.ObjectOk);
        }
Esempio n. 5
0
        /// <summary>
        /// Retrieves an item from the cache.
        /// </summary>
        public T Get <T>(string key)
        {
            T returnValue = default(T);

            Request request = new Request(Request.Types.GetObject, key, CacheBase.WriteHostName(key));

            var response = base.SendOrQueueNodeRequest(request);

            if (response != null)
            {
                if (response.Type == Response.Types.ObjectOk)
                {
                    returnValue = CacheBase.FromByteArray <T>(response.Data);
                }
            }

            return(returnValue);
        }
Esempio n. 6
0
        private void ReadConfigBytes(byte[] data)
        {
            try
            {
                CacheBase.RingNodes = new SortedList <int, Node>();
                CacheBase.Nodes     = new SortedList <string, Node>();

                if (data.Length > 0)
                {
                    using (MemoryStream ms = new MemoryStream(data))
                    {
                        using (BinaryReader reader = new BinaryReader(ms))
                        {
                            Node node;
                            int  numNodes = CacheBase.Read(reader.ReadInt32());
                            for (int n = 0; n < numNodes; n++)
                            {
                                int    hostLen  = CacheBase.Read(reader.ReadInt32());
                                byte[] hostData = new byte[hostLen];
                                if (reader.Read(hostData, 0, hostLen) != hostLen)
                                {
                                    throw new Exception("Invalid GetConfig hostData");
                                }

                                string hostname    = CacheBase.ReadHostName(hostData);
                                int    port        = CacheBase.Read(reader.ReadInt32());
                                long   maxNumBytes = CacheBase.Read(reader.ReadInt64());

                                node = new Node(
                                    hostname,
                                    port,
                                    maxNumBytes,
                                    (Node.StatusType)reader.ReadByte()
                                    );

                                CacheBase.Nodes[node.Name] = node;

                                bool parseLocations = reader.ReadBoolean();

                                if (parseLocations)
                                {
                                    try
                                    {
                                        int numLocations = CacheBase.Read(reader.ReadInt32());
                                        int location;

                                        for (int i = 0; i < numLocations; i++)
                                        {
                                            location = CacheBase.Read(reader.ReadInt32());
                                            CacheBase.RingNodes[location] = node;
                                        }
                                    }
                                    catch
                                    {
                                        string message = "Error reading location Data.";
                                        throw new Exception(message);
                                    }
                                }
                            }
                        }
                    }
                }
            }
            catch (Exception exo)
            {
                string message = string.Format(
                    "Error reading config Data. {0}",
                    exo.Message
                    );

                throw new Exception(message);
            }
        }
Esempio n. 7
0
        private Response SendNodeRequest(Request request)
        {
            Response response = null;
            //
            //  We'll try 3 times to get our data.
            //  Each node can respond with "im not the right node".
            //  If this happens the node responds with new configuration.
            //  Retry with the new configuration.
            //
            Node node = CacheBase.GetNodeForKey(request.Key);

            for (int i = 0; i < 3; i++)
            {
                response = this.SendRequest(node.HostName, node.Port, request);

                if (response == null)
                {
                    //
                    //  Distination unreachable.
                    //      Ask the master if the node is really down.
                    //response = this.NodeUnreachable(node.HostName, node.Port);

                    //if (response == null)
                    //    throw new Exception("No response from Master");

                    //switch (response.Type)
                    //{
                    //    case Response.Types.Accepted:
                    //        //
                    //        //  The node is in fact gone. BOOM!
                    //        //
                    //        break;

                    //    case Response.Types.NodeExists:
                    //
                    //  Master says the node is fine.
                    //  Wait a tick and try again.
                    //
                    System.Threading.Thread.Sleep(5000);
                    //        continue;

                    //    default:
                    //        this.UnexpectedResponse(response.Type, request.Type);
                    //        break;
                    //}
                }
                else
                {
                    switch (response.Type)
                    {
                    case Response.Types.ObjectOk:
                    case Response.Types.ObjectMissing:
                        break;

                    case Response.Types.ReConfigure:
                        this.ReadConfigBytes(response.Data);
                        node = CacheBase.GetNodeForKey(request.Key);
                        continue;

                    case Response.Types.DataNodeNotReady:
                        //
                        //  Node isn't ready.
                        //  Wait a tick and try again.
                        //
                        System.Threading.Thread.Sleep(50);
                        continue;

                    default:
                        this.UnexpectedResponse(response.Type, request.Type);
                        break;
                    }
                }

                break;
            }

            return(response);
        }