def CheckCachedResponse(command_line, cache): cmd, name, text = library.ParseCommand(command_line) # Update the cache for PUT commands but also pass the traffic to the server. ########################## #TODO: Implement section ########################## data = cache.GetValue(name, MAX_CACHE_AGE_SEC) # if that name is already in cache, update the value if cmd == 'PUT': cache.StoreValue(name, text) # GET commands can be cached. ############################ # TODO: Implement section ############################ elif (cmd == 'GET') and data != None: # To test if cache works, wait the max time before # trying GET again on the same name. "Cached: " will not be shown # before the value return "Cached: " + data return None
def ProxyClientCommand(sock, server_addr, server_port, cache): """Receives a command from a client and forwards it to a server:port. A single command is read from `sock`. That command is passed to the specified `server`:`port`. The response from the server is then passed back through `sock`. Args: sock: A TCP socket that connects to the client. server_addr: A string with the name of the server to forward requests to. server_port: An int from 0 to 2^16 with the port the server is listening on. cache: A KeyValueStore object that maintains a temorary cache. max_age_in_sec: float. Cached values older than this are re-retrieved from the server. """ command_line = library.ReadCommand(sock) cmd, name, text = library.ParseCommand(command_line) result = '' # Update the cache for PUT commands but also pass the traffic to the server. # GET commands can be cached. msg_to_server = (command_line, server_addr, server_port) if cmd == 'PUT': result = PutCommand(name, text, cache, msg_to_server) elif cmd == 'GET': result = GetCommand(name, cache, msg_to_server) elif cmd == 'DUMP': result = DumpCommand(msg_to_server) else: result = f'Unknown command {cmd}' SendText(sock, result)
def main(): # Store all key/value pairs in here. database = library.KeyValueStore() # The server socket that will listen on the specified port. If you don't # have permission to listen on the port, try a higher numbered port. server_sock = library.CreateServerSocket(LISTENING_PORT) # It will now handle it completely. while True: # Wait until a client connects and then get a socket that connects to the # client. client_sock, (address, port) = library.ConnectClientToServer( server_sock, LISTENING_PORT) print('Received connection from %s:%d' % (address, port)) # It now reads the command and executes it. command_line = library.ReadCommand(client_sock) command, name, text = library.ParseCommand(command_line) if command == 'PUT': result = PutCommand(name, text, database) elif command == 'GET': result = GetCommand(name, database) elif command == 'DUMP': result = DumpCommand(database) else: SendText(client_sock, 'Unknown command %s' % command) SendText(client_sock, result) # We're done with the client, so clean up the socket. ################################# client_sock.close()
def main(): # Store all key/value pairs in here. database = library.KeyValueStore() # The server socket that will listen on the specified port. If you don't # have permission to listen on the port, try a higher numbered port. server_sock = library.CreateServerSocket(LISTENING_PORT) # Handle commands indefinitely. Use ^C to exit the program. while True: # Wait until a client connects and then get a socket that connects to the # client. client_sock, (address, port) = library.ConnectClientToServer(server_sock) print('Received connection from %s:%d' % (address, port)) # Read a command. command_line = library.ReadCommand(client_sock) command, name, text = library.ParseCommand(command_line) # Execute the command based on the first word in the command line. if command == 'PUT': result = PutCommand(name, text, database) elif command == 'GET': result = GetCommand(name, database) elif command == 'DUMP': result = DumpCommand(database) else: result = 'Unknown command %s' % command SendText(client_sock, result) client_sock.close()
def CheckCachedResponse(command_line, cache, server_addr, server_port): cmd, name, text = library.ParseCommand(command_line) # Update the cache for PUT commands but also pass the traffic to the server. ########################## #TODO: Implement section if cmd == "GET": if cache.GetValue(name, MAX_CACHE_AGE_SEC): return cache.GetValue(name, MAX_CACHE_AGE_SEC) else: get = ForwardCommandToServer(command_line, server_addr, server_port) cache.StoreValue(name, get) return get ########################## # GET commands can be cached. ############################ #TODO: Implement section elif cmd == "PUT": if cache.GetValue(name, MAX_CACHE_AGE_SEC): cache.StoreValue(name, text) return ForwardCommandToServer(command_line, server_addr, server_port) else: return ForwardCommandToServer(command_line, server_addr, server_port)
def ProxyClientCommand(sock, server_addr, server_port, cache): """Receives a command from a client and forwards it to a server:port. A single command is read from `sock`. That command is passed to the specified `server`:`port`. The response from the server is then passed back through `sock`. Args: sock: A TCP socket that connects to the client. server_addr: A string with the name of the server to forward requests to. server_port: An int from 0 to 2^16 with the port the server is listening on. cache: A KeyValueStore object that maintains a temorary cache. max_age_in_sec: float. Cached values older than this are re-retrieved from the server. """ command_line = library.ReadCommand(sock) cmd, name, text = library.ParseCommand(command_line) response = ForwardCommandToServer(command_line,server_addr,server_port) checkedResponse = CheckCachedResponse(command_line, cache): if checkedResponse == None: sock.send(response) else: sock.send(checkedResponse)
def CheckCachedResponse(command_line, cache): cmd, name, text = library.ParseCommand(command_line) # print("cmd => {} name => {} text=> {}".format(cmd, name, text)) # Update the cache for PUT commands but also pass the traffic to the server. ########################## #TODO: Implement section ########################## if (cmd == "PUT"): # Store the key value pair name : text and then return Not in cache so we head to the server cache.StoreValue(name, text) return "Not in cache" # GET commands can be cached. ############################ #TODO: Implement section ############################ if (cmd == "GET"): # Get value of key, where key => name if name in cache.storage: return cache.GetValue(name, MAX_CACHE_AGE_SEC) else: return "Not in cache" if (cmd == "DUMP"): # This is so that when we call the DUMP Command we only get it from the server, since DUMP # shouldn't be cached return "Not in cache"
def ProxyClientCommand(sock, server_addr, server_port, cache, max_age_in_sec): """Receives a command from a client and forwards it to a server:port. A single command is read from `sock`. That command is passed to the specified `server`:`port`. The response from the server is then passed back through `sock`. Args: sock: A TCP socket that connects to the client. server_addr: A string with the name of the server to forward requests to. server_port: An int from 0 to 2^16 with the port the server is listening on. cache: A KeyValueStore object that maintains a temorary cache. max_age_in_sec: float. Cached values older than this are re-retrieved from the server. """ command_line = library.ReadCommand(sock) # obtain command from user command, _, _ = library.ParseCommand(command_line) if command == "GET" or command == "get": # if command involves cache cached_result = cache.GetValue(command_line, max_age_in_sec) if cached_result is not None: # if command was previously utilized print("Cache utilized") result = cached_result else: result = ForwardCommandToServer(command_line, server_addr, server_port) cache.StoreValue(command_line, result) # cache result for future use else: result = ForwardCommandToServer(command_line, server_addr, server_port) MirrorMessage(sock, result) # output message to client
def ProxyClientCommand(client_sock, server_addr, server_port, cache): """Receives a command from a client and forwards it to a server:port. A single command is read from `sock`. That command is passed to the specified `server`:`port`. The response from the server is then passed back through `sock`. Args: sock: A TCP socket that connects to the client. server_addr: A string with the name of the server to forward requests to. server_port: An int from 0 to 2^16 with the port the server is listening on. cache: A KeyValueStore object that maintains a temorary cache. max_age_in_sec: float. Cached values older than this are re-retrieved from the server. """ ########################################### #TODO: Implement ProxyClientCommand ########################################### command_line = library.ReadCommand(client_sock) response = CheckCachedResponse(command_line, cache) cmd, name, text = library.ParseCommand(command_line) if not response: # If there is no response from the proxy, go to main server else get response from cache response = ForwardCommandToServer(command_line, server_addr, server_port) if cmd == "GET": # Only on the GET commands do we store the value in the cache if there was no response from the proxy cache.StoreValue(name, response) client_sock.sendall('%s\n' % response)
def CheckCachedResponse(command_line, cache): cmd, name, text = library.ParseCommand(command_line) if cmd == 'PUT': return cache.StoreValue(name,text) elif cmd == 'GET': return cache.GetValue(name) else: return None
def CheckCachedResponse(command_line, cache): cmd, name, text = library.ParseCommand(command_line) # Update the cache for PUT command if cmd == 'PUT': cache.StoreValue(name, text) result = False # GET commands can be cached. elif cmd == 'GET': result = cache.GetValue(name, MAX_CACHE_AGE_SEC) or False if text: cache.StoreValue(name, text) return result # + "\n"
def ProxyClientCommand(sock, server_addr, server_port, cache): """Receives a command from a client and forwards it to a server:port. A single command is read from `sock`. That command is passed to the specified `server`:`port`. The response from the server is then passed back through `sock`. Args: sock: A TCP socket that connects to the client. server_addr: A string with the name of the server to forward requests to. server_port: An int from 0 to 2^16 with the port the server is listening on. cache: A KeyValueStore object that maintains a temorary cache. max_age_in_sec: float. Cached values older than this are re-retrieved from the server. """ data = '' timeNow = 0 command = sock.recv(1024) cmd, name, text = library.ParseCommand(command.decode()) timeNow=time.time() firstAccessTime = time.time() if cmd == 'PUT': data = ForwardCommandToServer(command, server_addr, server_port) cache.StoreValue(name, (firstAccessTime, data)) elif cmd == 'GET': if CheckCachedResponse(name, cache) is None: data = ForwardCommandToServer(command, server_addr, server_port) cache.StoreValue(name, (firstAccessTime, data)) else: timeAccessed=CheckCachedResponse(name, cache) if timeAccessed[0] is not None: timeDiff= timeNow-timeAccessed[0] if timeAccessed is None or timeDiff > MAX_CACHE_AGE_SEC: data = ForwardCommandToServer(command, server_addr, server_port) cache.StoreValue(name, (firstAccessTime, data)) else: data = CheckCachedResponse(name, cache)[1] elif cmd == 'DUMP': data = ForwardCommandToServer(command, server_addr, server_port) else: data = 'Unknown command %s' % cmd data = data.strip('\n') # if cmd=='GET' and not CheckCachedResponse(name, cache): # data = CheckCachedResponse(name, cache) # else: # data = ForwardCommandToServer(command, server_addr, server_port) # sock.connect((server_addr, server_port)) SendText(sock, data)
def CheckCachedResponse(command_line, cache): cmd, name, text = library.ParseCommand(command_line) out = None if cmd == 'GET': temp = cache.GetValue(name, MAX_CACHE_AGE_SEC) out = (name, temp) if cmd == 'PUT' and cache.GetValue(name, MAX_CACHE_AGE_SEC): cache.StoreValue(name, text) return out
def main(records_file=None): # Store all key/value pairs in here. if records_file: try: database = library.KeyValueStore(fileName=records_file) except library.InvalidRecordFormatException as e: print(e) print("Initializing an empty database") database = library.KeyValueStore() except library.InvalidRecordTypeException as e: print(e) print("Initializing an empty database") database = library.KeyValueStore() else: database = library.KeyValueStore() # The server socket that will listen on the specified port. If you don't # have permission to listen on the port, try a higher numbered port. server_sock = library.CreateServerSocket(LISTENING_PORT) # Handle commands indefinitely. Use ^C to exit the program. try: while True: # Wait until a client connects and then get a socket that connects to the # client. client_sock, (address, port) = library.ConnectClientToServer(server_sock) print('Received connection from %s:%d' % (address, port)) # Read a command. command_line = library.ReadCommand(client_sock) command, name, text = library.ParseCommand(command_line) # Execute the command based on the first word in the command line. if command == 'PUT': result = PutCommand(name, text, database) elif command == 'GET': result = GetCommand(name, database) elif command == 'DUMP': result = DumpCommand(database) else: SendText(client_sock, 'Unknown command %s' % command) SendText(client_sock, result) # We're done with the client, so clean up the socket. client_sock.close() except KeyboardInterrupt: # Write records to a file, which can be restored later. # Close the server socket. server_sock.close() with open("server-records.txt", 'w') as fileHandle: fileHandle.write(str(database))
def CheckCachedResponse(command_line, cache): cmd, name, text = library.ParseCommand(command_line) if cmd == "PUT": cache.StoreValue(name,text) ForwardCommandToServer(command_line, SERVER_ADDRESS, SERVER_PORT) return None elif cmd == "GET": if name in cache: return cache[name] else: ForwardCommandToServer(command_line, SERVER_ADDRESS, SERVER_PORT)
def ProxyClientCommand(sock, server_addr, server_port, cache): command_line = library.ReadCommand(sock) cmd, name, value = library.ParseCommand(command_line) if cmd == 'PUT': server_response = ForwardCommandToServer(command_line, server_addr, server_port) cache.StoreValue(name, server_response) elif (cmd == 'GET'): server_response = cache.GetValue(name) if server_response == None: server_response = ForwardCommandToServer(command_line, server_addr, server_port) else: server_response = ForwardCommandToServer(command_line, server_addr, server_port) sock.send(server_response)
def ProxyClientCommand(sock, server_addr, server_port, cache): command_line = library.ReadCommand(sock) command, name, text = library.ParseCommand(command_line) returning_str = "" if (command == "GET"): #if GET, name might be in cache or not if (name in cache.keyvalue): timeElapsed = time.time() - (cache.keyvalue[name])[1] if ( timeElapsed < MAX_CACHE_AGE_SEC ): #No problem with cached information if last cached time is less than 60 seconds. returning_text = (cache.keyvalue[name])[0].decode( ) + " ( Returned from proxy) " SendText(sock, returning_text) else: data = ForwardCommandToServer( command_line, server_addr, server_port ) #If last cached time is more than 60 seconds, pull the info from main server cache.keyvalue[name] = [data, time.time()] sock.send(data + b"\n") else: #if not found in cache, forward to the server. Server will handle KEY NOT FOUND error data = ForwardCommandToServer(command_line, server_addr, server_port) if (ServerFound(data) == True): cache.keyvalue[name] = [ data, time.time() ] #cache the data only if server found the key sock.send(data + b"\n") elif (command == "PUT"): if (name == None or text == None): returning_str = "Key And Value both needed for PUT operation\n" SendText(sock, returning_str) else: returning_str = name + " = " + text ForwardCommandToServer(command_line, server_addr, server_port) SendText(sock, returning_str) elif (command == "DUMP"): #command = "DUMP" data = ForwardCommandToServer(command_line, server_addr, server_port) sock.send(data + b"\n") else: SendText(sock, 'Unknown command %s' % command) return
def CheckCachedResponse(command_line, cache, server_addr, server_port): cmd, name, text = library.ParseCommand(command_line) if cmd == "GET": if cache.GetValue(name, MAX_CACHE_AGE_SEC): return cache.GetValue(name, MAX_CACHE_AGE_SEC) else: received = ForwardCommandToServer(command_line, server_addr, server_port) cache.StoreValue(name, received) return received elif cmd == "PUT": if cache.GetValue(name, MAX_CACHE_AGE_SEC): cache.StoreValue(name, text) return ForwardCommandToServer(command_line, server_addr, server_port) else: return ForwardCommandToServer(command_line, server_addr, server_port)
def ProxyClientCommand(sock, server_addr, server_port, cache): """Receives a command from a client and forwards it to a server:port. A single command is read from `sock`. That command is passed to the specified `server`:`port`. The response from the server is then passed back through `sock`. Args: sock: A TCP socket that connects to the client. server_addr: A string with the name of the server to forward requests to. server_port: An int from 0 to 2^16 with the port the server is listening on. cache: A KeyValueStore object that maintains a temorary cache. max_age_in_sec: float. Cached values older than this are re-retrieved from the server. """ command_line = library.ReadCommand(sock) cmd, name, text = library.ParseCommand(command_line) if cmd == "GET": if cache.GetValue(name, MAX_CACHE_AGE_SEC): print('Key %s in the cache.' % name) sock.send("Key: {0}, Value: {1}\n".format( name, cache.GetValue(name, MAX_CACHE_AGE_SEC))) return # Get record from the server, and update the cache. serverResponse = ForwardCommandToServer(command_line, server_addr, server_port) cache.StoreValue(name, serverResponse) elif cmd == "PUT": print('Writing %s: %s to the cache' % (name, text)) cache.StoreValue(name, text) serverResponse = ForwardCommandToServer(command_line, server_addr, server_port) elif cmd == "DUMP": serverResponse = ForwardCommandToServer(command_line, server_addr, server_port) else: return # Forward the server response to the client. print("Forwarding the response from the server to the client") sock.send(serverResponse)
def CheckCachedResponse(command_line, cache): cmd, name, text = library.ParseCommand(command_line) # Update the cache for PUT commands but also pass the traffic to the server. if cmd == "PUT": cache.StoreValue(name, text) ForwardCommandToServer(command_line, SERVER_ADDRESS, SERVER_PORT) # GET commands can be cached. if cmd == "GET": if name in cache.Keys(): return cache.GetValue(name) + '\n' else: result = ForwardCommandToServer(command_line, SERVER_ADDRESS, SERVER_PORT) cache.StoreValue(name, text) return result ForwardCommandToServer(command_line, SERVER_ADDRESS, SERVER_PORT)
def ProxyClientCommand(client_socket, server_addr, server_port, cache): """Receives a command from a client and forwards it to a server:port. A single command is read from `sock`. That command is passed to the specified `server`:`port`. The response from the server is then passed back through `sock`. Args: sock: A TCP socket that connects to the client. server_addr: A string with the name of the server to forward requests to. server_port: An int from 0 to 2^16 with the port the server is listening on. cache: A KeyValueStore object that maintains a temorary cache. max_age_in_sec: float. Cached values older than this are re-retrieved from the server. """ # Get the client's request/command request = library.ReadCommand(client_socket) cmd, name, text = library.ParseCommand(request) # Forward the request to the server and retrieve response data = ForwardCommandToServer(request, server_addr, server_port) # print("Data is here : {}".format(data)) if cmd == "PUT": if name not in cache.Names(): cache.StoreValue(name, text) client_socket.sendall('%s\n' % data) else: print("Key", name, "already exists") elif cmd == "GET": if name not in cache.Names(): print("Key ", name, " does not exist") else: cache.GetValue(name, MAX_CACHE_AGE_SEC) client_socket.sendall('%s\n' % data) elif cmd == "DUMP": cache.Keys() client_socket.sendall(data) client_socket.close()
def ProxyClientCommand(sock, server_addr, server_port, cache, max_age_in_sec): """Receives a command from a client and forwards it to a server:port. A single command is read from `sock`. That command is passed to the specified `server`:`port`. The response from the server is then passed back through `sock`. Args: sock: A TCP socket that connects to the client. server_addr: A string with the name of the server to forward requests to. server_port: An int from 0 to 2^16 with the port the server is listening on. cache: A KeyValueStore object that maintains a temorary cache. max_age_in_sec: float. Cached values older than this are re-retrieved from the server. """ ########################################### #TODO: Implement ProxyClientCommand ########################################### command_line = library.ReadCommand(sock) command, name, text = library.ParseCommand(command_line) if command == "GET" or command == "get": #if get cached_result = cache.GetValue(command_line, max_age_in_sec) if cached_result is not None: print("Cache used") result = cached_result #if post else: result = ForwardCommandToServer(command_line, server_addr, server_port) cache.StoreValue(command_line, result) elif (command == "PUT" or command == "put"): #if put if (name == None or text == None): result = "Key and Value needed for PUT operation\n" else: result = ForwardCommandToServer(command_line, server_addr, server_port) elif (command == "DUMP" or command == "dump"): #if dump result = ForwardCommandToServer(command_line, server_addr, server_port) else: result = "Invalid Operation\n" sock.send(result)
def CheckCachedResponse(command_line, cache): cmd, name, text = library.ParseCommand(command_line) # Update the cache for PUT commands but also pass the traffic to the server. if cmd == 'PUT': cache.StoreValue(name, text) cache.StoreValue(name + "TIME", datetime.datetime.now()) return ForwardCommandToServer(command_line, SERVER_ADDRESS, SERVER_PORT) # GET commands can be cached. if cmd == 'GET': if name in cache.Keys() and DataNotStale(name, cache): return cache.GetValue(name) + '\n' else: res = ForwardCommandToServer(command_line, SERVER_ADDRESS, SERVER_PORT) cache.StoreValue(name, res) return res return ForwardCommandToServer(command_line, SERVER_ADDRESS, SERVER_PORT)
def CheckCachedResponse(command_line, cache): cmd, name, text = library.ParseCommand(command_line) in_cache = False if cmd == 'PUT': if name not in cache.Keys(): cache.StoreValue(name, text) print('Not in cache. Fetching from server.') in_cache = True return in_cache else: print('Fetched successfully from cache.') return in_cache elif cmd == 'GET': if name not in cache.Keys(): print('Not in cache. Fetching from server.') return in_cache else: print('Fetched successfully from cache.') in_cache = True return in_cache
def CheckCachedResponse(command_line, cache): cmd, name, text = library.ParseCommand(command_line) # Update the cache for PUT commands but also pass the traffic to the server. response = None ########################## #TODO: Implement section ########################## # If the response is None this means that we should forward the command either PUT, GET or DUMP # We always forward on the PUT and DUMP commands but use cached value for GET if it is in the cache # See the usage in ProxyClientCommand # Note that this implementation would GET stale values from the cache after updating the values in the main server # However Ebele said that this was okay and there would not be a penalty :) # GET commands can be cached. ############################ #TODO: Implement section ############################ if cmd == "GET" and name in cache.Keys(): response = cache.GetValue(name) return response
def ProxyClientCommand(sock, server_addr, server_port, cache): """Receives a command from a client and forwards it to a server:port. A single command is read from `sock`. That command is passed to the specified `server`:`port`. The response from the server is then passed back through `sock`. Args: sock: A TCP socket that connects to the client. server_addr: A string with the name of the server to forward requests to. server_port: An int from 0 to 2^16 with the port the server is listening on. cache: A KeyValueStore object that maintains a temorary cache. max_age_in_sec: float. Cached values older than this are re-retrieved from the server. """ ########################################### #TODO: Implement ProxyClientCommand ########################################### data = sock.recv(library.COMMAND_BUFFER_SIZE).decode() # print("The data received is {}".format(data)) info_from_cache = CheckCachedResponse(data, cache) # print(info_from_cache) if (info_from_cache == "Not in cache"): # Forward the request to the server proxy_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) proxy_socket.connect((server_addr, server_port)) # Forward the data to the server proxy_socket.send(data) new_data = proxy_socket.recv(library.COMMAND_BUFFER_SIZE).decode() # print("This is the data received") print(new_data) if (new_data != "This key is not in the database"): # Update the cache in the proxy # print("The new data is => {}".format(new_data)) my_cmd, my_name, my_text = library.ParseCommand(data) if (my_cmd == "GET"): # print("Key and value are => {} and {}".format(my_name, new_data)) cache.StoreValue(my_name, new_data) if (new_data == None): new_data = "No data was stored in this key\n" sock.send(new_data) sock.close() else: # Sending the data directly from the cache back to the client # print("Sending directly from cache") for debugging purposes if (info_from_cache == None): my_cmd, my_name, my_text = library.ParseCommand(data) possible_cmds = ("GET", "PUT") if (my_cmd in possible_cmds): info_from_cache = "No data was stored in this key" else: info_from_cache = "Error command" info_from_cache += "\n" sock.send(info_from_cache) sock.close()
def CheckCachedResponse(command_line, cache): cmd, name, text = library.ParseCommand(command_line)