Incorrect test for Replication #TU8

I’m stuck on Replication 17.

I’ve tried Real Redis MASTER and 1 my Redis As SLAVE.

When I sent WAIT 10 300 to the MASTER without any WRITEs before I’ve got:
[‘REPLCONF’, ‘GETACK’, ‘*’]
on SLAVE and everything works fine.

Then I’ve tried my Redis as MASTER and 1 Real Redis SLAVE.
When I sent WAIT 10 300 to the MASTER without any WRITEs before I’ve got
the additional [‘REPLCONF’, ‘ACK’, ‘185’] from SLAVE
and everything works fine.

But on tests I’ve sent:
[‘REPLCONF’, ‘GETACK’, ‘*’] to all test replicas and did not get any ACK answer

Here are my logs:

remote: [replication-17] client: $ redis-cli WAIT 3 500
remote: [your_program]      ['WAIT', '3', '500']
remote: [your_program] R <- b'*3\r\n$8\r\nREPLCONF\r\n$6\r\nGETACK\r\n$1\r\n*\r\n'
remote: [your_program] R <- b'*3\r\n$8\r\nREPLCONF\r\n$6\r\nGETACK\r\n$1\r\n*\r\n'
remote: [your_program] R <- b'*3\r\n$8\r\nREPLCONF\r\n$6\r\nGETACK\r\n$1\r\n*\r\n'
remote: [your_program] R <- b'*3\r\n$8\r\nREPLCONF\r\n$6\r\nGETACK\r\n$1\r\n*\r\n'
remote: [your_program] R <- b'*3\r\n$8\r\nREPLCONF\r\n$6\r\nGETACK\r\n$1\r\n*\r\n'
remote: [your_program] R <- b'*3\r\n$8\r\nREPLCONF\r\n$6\r\nGETACK\r\n$1\r\n*\r\n'
remote: [your_program]   [Start WAIT] at 1712997390.1653676
remote: [your_program]   [STOP WAIT] at 1712997390.6666832
remote: [your_program]   <- b':0\r\n'

Hey @gnomeby,

Can you try setting debug: true in your codecrafters.yml? I think you should see more helpful logs in that case. We should be logging out the reciept of GETACK *, and the ACKs that were sent back.

More on debug mode here: How do I debug test failures? - CodeCrafters

With debug:

remote: [replication-17] client: $ redis-cli WAIT 3 500
remote: [replication-17] client: Sent bytes: "*3\r\n$4\r\nWAIT\r\n$1\r\n3\r\n$3\r\n500\r\n"
remote: [your_program]      ['WAIT', '3', '500']
remote: [your_program] R <- b'*3\r\n$8\r\nREPLCONF\r\n$6\r\nGETACK\r\n$1\r\n*\r\n'
remote: [your_program] R <- b'*3\r\n$8\r\nREPLCONF\r\n$6\r\nGETACK\r\n$1\r\n*\r\n'
remote: [your_program] R <- b'*3\r\n$8\r\nREPLCONF\r\n$6\r\nGETACK\r\n$1\r\n*\r\n'
remote: [your_program] R <- b'*3\r\n$8\r\nREPLCONF\r\n$6\r\nGETACK\r\n$1\r\n*\r\n'
remote: [your_program] R <- b'*3\r\n$8\r\nREPLCONF\r\n$6\r\nGETACK\r\n$1\r\n*\r\n'
remote: [your_program] R <- b'*3\r\n$8\r\nREPLCONF\r\n$6\r\nGETACK\r\n$1\r\n*\r\n'
remote: [your_program] R <- b'*3\r\n$8\r\nREPLCONF\r\n$6\r\nGETACK\r\n$1\r\n*\r\n'
remote: [your_program] R <- b'*3\r\n$8\r\nREPLCONF\r\n$6\r\nGETACK\r\n$1\r\n*\r\n'
remote: [your_program]   [Start WAIT] at 1713278386.1287766
remote: [your_program]   [STOP WAIT] at 1713278386.6303675
remote: [your_program]   <- b':0\r\n'
remote: [replication-17] client: Received bytes: ":0\r\n"
remote: [replication-17] client: Received RESP value: 0
remote: [replication-17] Expected 8, got 0
remote: [replication-17] Test failed
remote: [replication-17] Terminating program

I am also running into the same issue. Setting debug: true in the config file shows that the test replica does not respond to the getack commands that I send as the connection is reset. Are there any solutions on my end to this problem?

We’ve got to improve logs here to convey when replicas received GETACKs, and when they send ACKs back (or not). Will keep open until we’ve done this!

Here are full logs:

remote: [replication-17] client: $ redis-cli WAIT 3 500
remote: [replication-17] client: Sent bytes: "*3\r\n$4\r\nWAIT\r\n$1\r\n3\r\n$3\r\n500\r\n"
remote: [your_program]      ['WAIT', '3', '500']
remote: [your_program] R <- b'*3\r\n$8\r\nREPLCONF\r\n$6\r\nGETACK\r\n$1\r\n*\r\n'
remote: [your_program] R <- b'*3\r\n$8\r\nREPLCONF\r\n$6\r\nGETACK\r\n$1\r\n*\r\n'
remote: [your_program] R <- b'*3\r\n$8\r\nREPLCONF\r\n$6\r\nGETACK\r\n$1\r\n*\r\n'
remote: [your_program] R <- b'*3\r\n$8\r\nREPLCONF\r\n$6\r\nGETACK\r\n$1\r\n*\r\n'
remote: [your_program]   [Start WAIT] at 1714849205.191998
remote: [your_program]   [STOP WAIT] at 1714849205.6934195
remote: [your_program]   <- b':0\r\n'
remote: [replication-17] client: Received bytes: ":0\r\n"
remote: [replication-17] client: Received RESP value: 0
remote: [replication-17] Expected 4, got 0
remote: [replication-17] Test failed
remote: [replication-17] Terminating program

and in the same time test for Replication-18 has been passed:

remote: [replication-18] client: $ redis-cli WAIT 3 2000
remote: [replication-18] client: Sent bytes: "*3\r\n$4\r\nWAIT\r\n$1\r\n3\r\n$4\r\n2000\r\n"
remote: [replication-18] Testing Replica : 1
remote: [replication-18] replica-1: Received bytes: "*3\r\n$3\r\nSET\r\n$3\r\nbaz\r\n$3\r\n789\r\n"
remote: [replication-18] replica-1: Received RESP value: ["SET", "baz", "789"]
remote: [replication-18] Received ["SET", "baz", "789"]
remote: [your_program]      ['WAIT', '3', '2000']
remote: [your_program] R <- b'*3\r\n$8\r\nREPLCONF\r\n$6\r\nGETACK\r\n$1\r\n*\r\n'
remote: [your_program] R <- b'*3\r\n$8\r\nREPLCONF\r\n$6\r\nGETACK\r\n$1\r\n*\r\n'
remote: [your_program] R <- b'*3\r\n$8\r\nREPLCONF\r\n$6\r\nGETACK\r\n$1\r\n*\r\n'
remote: [your_program]   [Start WAIT] at 1714849201.0465517
remote: [replication-18] replica-1: Received bytes: "*3\r\n$8\r\nREPLCONF\r\n$6\r\nGETACK\r\n$1\r\n*\r\n"
remote: [replication-18] replica-1: Received RESP value: ["REPLCONF", "GETACK", "*"]
remote: [replication-18] Received ["REPLCONF", "GETACK", "*"]
remote: [replication-18] replica-1: $ redis-cli REPLCONF ACK 99
remote: [replication-18] replica-1: Sent bytes: "*3\r\n$8\r\nREPLCONF\r\n$3\r\nACK\r\n$2\r\n99\r\n"
remote: [replication-18] Testing Replica : 2
remote: [replication-18] replica-2: Received bytes: "*3\r\n$3\r\nSET\r\n$3\r\nbaz\r\n$3\r\n789\r\n"
remote: [replication-18] replica-2: Received RESP value: ["SET", "baz", "789"]
remote: [replication-18] Received ["SET", "baz", "789"]
remote: [your_program]      ['REPLCONF', 'ACK', '99']
remote: [replication-18] replica-2: Received bytes: "*3\r\n$8\r\nREPLCONF\r\n$6\r\nGETACK\r\n$1\r\n*\r\n"
remote: [replication-18] replica-2: Received RESP value: ["REPLCONF", "GETACK", "*"]
remote: [replication-18] Received ["REPLCONF", "GETACK", "*"]
remote: [replication-18] replica-2: $ redis-cli REPLCONF ACK 99
remote: [replication-18] replica-2: Sent bytes: "*3\r\n$8\r\nREPLCONF\r\n$3\r\nACK\r\n$2\r\n99\r\n"
remote: [replication-18] Testing Replica : 3
remote: [replication-18] replica-3: Received bytes: "*3\r\n$3\r\nSET\r\n$3\r\nbaz\r\n$3\r\n789\r\n"
remote: [replication-18] replica-3: Received RESP value: ["SET", "baz", "789"]
remote: [replication-18] Received ["SET", "baz", "789"]
remote: [your_program]      ['REPLCONF', 'ACK', '99']
remote: [replication-18] replica-3: Received bytes: "*3\r\n$8\r\nREPLCONF\r\n$6\r\nGETACK\r\n$1\r\n*\r\n"
remote: [replication-18] replica-3: Received RESP value: ["REPLCONF", "GETACK", "*"]
remote: [replication-18] Received ["REPLCONF", "GETACK", "*"]
remote: [your_program]   [STOP WAIT] at 1714849203.0527372
remote: [your_program]   <- b':2\r\n'
remote: [replication-18] client: Received bytes: ":2\r\n"
remote: [replication-18] client: Received RESP value: 2
remote: [replication-18] WAIT command returned after 2013 ms
remote: [replication-18] Test passed.

and it looks like your replication clients from Replication-17 tests just doesn’t reply after receiving RDB file.

Confirming this. I’m having the same problem with stage 17 and being incompatible: Redis Replication 18: Timeout Issue - #5 by malshoff

We’ve now added logs that convey when a replica decides to respond vs. not:

Going to close this out for now, please let us know if you still need help!

In test for the Replication-17 step your replicas are not going to get:
REPLCONF GETACK *
when master get WAIT cmd.
and this is described in Replication-17 step.

It is clear and there would not be a problem if real REDIS behaves in the same way. But it is not. Real REDIS sends REPLCONF GETACK * in all cases, even if it empty.

@gnomeby our behaviour should match what Redis does. We verify our tester against an official Redis server for this very purpose. Can you share more details on the differences you’re seeing? Are you able to observe this locally?

Yes, I observed this locally when I connect my official Redis 7.2.4 (MASTER) to my python Redis (SLAVE). And I described this in the initial comment.

I’ve rechecked behavior and found the following:

Case 1:
Official empty Redis as MASTER
and 1 my redis as slave

if I send WAIT 1 1 to master then MASTER responses immediately without sending REPLCONF GETACK * to SLAVE.
if I send WAIT 2 1 (more replicas then exists) to master then MASTER sends REPLCONF GETACK * to SLAVEs.

So it looks like my mistake.

Ah, yep!

For anyone else who lands here, you can confirm this with wireshark. Spawn a Redis master and connect as a replica, you’ll see that it doesn’t request ACKs if no commands are sent and the replica count is lesser than / equal to the connected count:

(Note that when I use WAIT 2, a GETACK is sent, but it isn’t when doing WAIT 1)

This topic was automatically closed 5 days after the last reply. New replies are no longer allowed.

Note: I’ve updated the title of this post to include the stage ID (#TU8). You can learn about the stages rename here: Upcoming change: Stages overhaul.