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; } }
// // 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); }
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(); } }
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; } }