Instructions
In this stage of this project I’m making, I need to add support for the ECHO command.
ECHO is a command like PING that’s used for testing and debugging. It accepts a single argument and returns it back as a RESP bulk string.
$ redis-cli PING # The command I implemented in previous stages
PONG
$ redis-cli ECHO hey # The command I will implement in this stage
hey
Tests
The tester will execute the program like this:
$ ./your_program.sh
It’ll then send an ECHO command with an argument to your server:
$ redis-cli ECHO hey
The tester will expect to receive $3\r\nhey\r\n
as a response (that’s the string hey encoded as a RESP bulk string.
This is my solution:
import socket
import threading
def handle_client(conn, addr):
print(f'Connected to {addr}')
while True:
data = conn.recv(1024) # Read data as bytes
if not data: # If no data is received, exit the loop
break
request = data.decode()
pong = b"+PONGrn"
if request.lower().startswith("echo"):
# Parse the message for the ECHO command
parts = request.split("rn")
if len(parts) >= 4:
res_data = parts[3] # Extract the actual argument for ECHO (the string after ECHO)
content_len = len(res_data) # Get the length of the argument
# Correctly format the response as a bulk string
response = f"${content_len}rn{res_data}rn"
conn.send(response.encode()) # Send the response back
else:
# Default response for PING
conn.send(b"+PONGrn")
print(f"Connection to {addr} closed")
conn.close() # Close the connection with the client
def main():
print("Logs from your program will appear here!")
# Set up the server socket and start listening for connections
server_socket = socket.create_server(("localhost", 6379), reuse_port=True)
server_socket.listen()
while True:
# Accept a new client connection
conn, addr = server_socket.accept()
# Create and start a new thread to handle the client
client_thread = threading.Thread(target=handle_client, args=(conn, addr))
client_thread.start()
if __name__ == "__main__":
main()
Error:
Initiating test run...
⚡ This is a turbo test run. https://codecrafters.io/turbo
Running tests. Logs should appear shortly...
[compile] Moved ./.codecrafters/run.sh → ./your_program.sh
[compile] Compilation successful.
[tester::#QQ0] Running tests for Stage #QQ0 (Implement the ECHO command)
[tester::#QQ0] $ ./your_program.sh
[your_program] Logs from your program will appear here!
[tester::#QQ0] $ redis-cli ECHO pineapple
[your_program] Connected to ('127.0.0.1', 39346)
[tester::#QQ0] Expected "pineapple", got "PONG"
[tester::#QQ0] Test failed (try setting 'debug: true' in your codecrafters.yml to see more details)
I think that the parser is unable to read the ECHO command, but I don’t know how to fix it. Any help would be appreciated.
2
Answers
The following is the answer to the question:
Define a function for each command and then split the input data on the first space character and call the appropriate function for the command passing the remaining data to the function.