예제 #1
0
파일: Store.cs 프로젝트: VqSoft/cacheman
        public static byte[] GetValue(string key, Client currentClient)
        {
            //
                // Read a value from the store.  If the value has lived past its TTL, we'll expire it.
                //
                Value value;
                using(TimeLock.Acquire(_values)) {
                    bool foundValue = _values.TryGetValue(key, out value);
                    if (!foundValue || value == null) {
                        return null;
                    }

                    if (value.TTL > 0) {
                        //
                        // Honour expiry TTL on object if any
                        //
                        if (value.TimeAdded.AddSeconds(value.TTL).CompareTo(DateTime.Now) <= 0) {
                            RemoveValue(key);
                            return null;

                        }
                    }

                    //
                    //Do some book-keeping with the value
                    //
                    value.LastAccessed = DateTime.Now;
                    Interlocked.Increment(ref value.NumAccesses);
                    return value.Data;
                }
        }
예제 #2
0
        //
        // Async callback for socket accept event
        //
        public void AcceptCallback(IAsyncResult ar)
        {
            //
            // Free up the listen loop to go churn out more  sockets
            //

            _acceptEvent.Set();

            //
            // Get client request socket and finish accept
            //
            byte[] buffer = new byte[Client.BufferSize];
            Socket listenSocket = (Socket)ar.AsyncState;
            Socket handler = null;
            try {
                handler = listenSocket.EndAccept(ar);
            } catch (SocketException ex) {
                handler.Shutdown(SocketShutdown.Both);
                Log.LogMessage(" AcceptCallback " + ex.ToString());
                return;
            }

            //
            // We have a new client. Create a new client object and kick off the state machine
            //

            ConfigureClientSocket(handler);
            Client currentClient = new Client {
                WorkSocket = handler,
                State = SocketState.ReadCommand,
                UniqueId = DateTime.Now.Ticks.ToString(),
                ClientNetworkHelper = new NetworkHelper(handler, buffer),
                Buffer = buffer
            };

            Log.LogMessage("Connected to client from " + handler.RemoteEndPoint.ToString() + " \n");
            StateMachine(currentClient);
        }
예제 #3
0
        private void StateMachine(Client currentClient)
        {
            try {

                   switch (currentClient.State) {

                            case SocketState.ReadCommand:
                                currentClient.ClientNetworkHelper.BeginReadLine( ReadCommandCallback , currentClient);
                                break;

                            case SocketState.ReadValue:

                                currentClient.ClientNetworkHelper.BeginReadValue(currentClient.ValueTotalBytes,ReadValueCallback, currentClient);
                                break;

                            default:

                                Debug.Assert(false);
                                Log.LogError("Server.StateMachine: Invalid state");

                                break;
                        }

            } catch (Exception ex) {
                //
                // Something bad happened.
                //
                Log.LogError("Exception in state machine (client will be disconnected!: " + ex.ToString());
                currentClient.Dispose();
            }
        }
예제 #4
0
        private void ExecCommand(Client currentClient)
        {
            if (currentClient.CurrentCommand.Action == CommandType.GET) {

                //
                // Read value from the store and send it to the client if found. If we don't,
                // find it, send a NOT_FOUND message to the client. We then clean up the state machine
                // and wait for the next command from the client
                //

                byte[] data = Store.GetValue(currentClient.CurrentCommand.Key, currentClient);

                PerfCounters.LogGet(data != null);

                if (data != null) {
                    currentClient.ClientNetworkHelper.SendValue(data , currentClient.CurrentCommand.Key);
                } else {
                    currentClient.ClientNetworkHelper.SendMessage( "NOT_FOUND");
                }
                return;
            }

            if (currentClient.CurrentCommand.Action == CommandType.DELETE) {
                //
                // Delete the specified value from the store.
                // TODO: Send an error if the value wasnt found in the store
                //
                if (Store.RemoveValue(currentClient.CurrentCommand.Key)) {
                    currentClient.ClientNetworkHelper.SendMessage("DELETED");
                } else {
                    currentClient.ClientNetworkHelper.SendMessage("NOT_FOUND");
                }
                PerfCounters.LogDelete();
                return;

            }

            if (currentClient.CurrentCommand.Action == CommandType.SET) {
                //
                // Read the header for a SET/UPDATE command.
                //
                if (currentClient.CurrentCommand.Size > Global.MAX_CACHE_MEMORY) {

                    currentClient.ClientNetworkHelper.SendError( "Item too large");
                    return;
                }

                currentClient.ValueTotalBytes = currentClient.CurrentCommand.Size;
                currentClient.State = SocketState.ReadValue;
                return;
            }
        }