# Redis Replication #NA2: Timeout Issue

**URL:** <https://forum.codecrafters.io/t/redis-replication-na2-timeout-issue/208>\
**Category:** Challenges\
**Tags:** challenge:redis\
**Created:** [April 28, 2024, 7:33am UTC](https://forum.codecrafters.io/t/redis-replication-na2-timeout-issue/208 "2024-04-28T07:33:41Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![JayeshBaldawa](https://yyz1.discourse-cdn.com/flex003/user_avatar/forum.codecrafters.io/jayeshbaldawa/32/138_2.png) [@JayeshBaldawa](https://forum.codecrafters.io/u/JayeshBaldawa)\
**Post date:** [April 28, 2024, 7:33am UTC](https://forum.codecrafters.io/t/redis-replication-na2-timeout-issue/208/1 "2024-04-28T07:33:41Z")

</div>

I’m stuck on this [stage](https://app.codecrafters.io/courses/redis/stages/replication:18).

So, I received the command as:

```auto
*3\r\n$4\r\nWAIT\r\n$1\r\n3\r\n$3\r\n500

```

which expects a timeout of 500 ms. However, it’s getting a timeout in 500 ms, resulting in 0 responses during that time, causing the test to fail. I tried adding a readTimeout for the duration, but it still fails, so I removed that.

Please let me know what I am doing wrong.

Here are my logs:

```auto
[replication-17] client: $ redis-cli WAIT 3 500
[replication-17] client: Sent bytes: "*3\r\n$4\r\nWAIT\r\n$1\r\n3\r\n$3\r\n500\r\n"
[your_program] 2024-04-28T07:22:34.579Z INFO master:6379: "Connection received from \"[::1]:36720\""
[your_program] 2024-04-28T07:22:34.579Z INFO master:6379: "Received command: \"*3\\r\\n$4\\r\\nWAIT\\r\\n$1\\r\\n3\\r\\n$3\\r\\n500\""
[your_program] 2024-04-28T07:22:34.579Z INFO master:6379: "Splitted Commands: [*3\r\n$4\r\nWAIT\r\n$1\r\n3\r\n$3\r\n500\r\n]"
[your_program] 2024-04-28T07:22:34.579Z INFO master:6379: "Waiting for 500 milliseconds"
[your_program] 2024-04-28T07:22:34.579Z INFO master:6379: "ACK request sent to replica server \"[::1]:36658\""
[your_program] 2024-04-28T07:22:34.579Z INFO master:6379: "ACK request sent to replica server \"[::1]:36670\""
[your_program] 2024-04-28T07:22:34.579Z INFO master:6379: "ACK request sent to replica server \"[::1]:36698\""
[your_program] 2024-04-28T07:22:34.579Z INFO master:6379: "ACK request sent to replica server \"[::1]:36712\""
[your_program] 2024-04-28T07:22:34.579Z INFO master:6379: "ACK request sent to replica server \"[::1]:36650\""
[your_program] 2024-04-28T07:22:34.579Z INFO master:6379: "ACK request sent to replica server \"[::1]:36686\""
[your_program] 2024-04-28T07:22:35.180Z INFO master:6379: "Timeout reached as per the WAIT command"
[your_program] 2024-04-28T07:22:35.180Z INFO master:6379: "Command is \"wait\" --> Response is \":0\\r\\n\""
[replication-17] client: Received bytes: ":0\r\n"
[replication-17] client: Received RESP value: 0
[replication-17] Expected 6, got 0
[replication-17] Test failed
[replication-17] Terminating program
[your_program] 2024-04-28T07:22:35.188Z INFO master:6379: "Connection closed by \"[::1]:36720\""
[replication-17] Program terminated successfully

```

And here’s a snippet of my code:

```GO

	for {
				select {
				case ack := <-respChan:
					log.LogInfo(fmt.Sprintf("ACK received: %t", ack))
					totalAcks++
					if ack {
						ackReceived++
					}
					if totalAcks == replicaServersCount {
						return ackReceived, nil
					}
				case <-ctx.Done():
					log.LogInfo("Timeout reached as per the WAIT command")
					return ackReceived, nil
				case <-defaultTimeout.C:
					log.LogInfo("No response received from replica servers in default timeout")
					return ackReceived, nil
				}
			}

```

---

<div class="post-metadata">

**Author:** ![mtfcd](https://yyz1.discourse-cdn.com/flex003/user_avatar/forum.codecrafters.io/mtfcd/32/187_2.png) [@mtfcd](https://forum.codecrafters.io/u/mtfcd)\
**Post date:** [April 28, 2024, 11:13am UTC](https://forum.codecrafters.io/t/redis-replication-na2-timeout-issue/208/2 "2024-04-28T11:13:10Z")

</div>

it seems to be in stage 17 when there is not previous write command you don’t actually need to send the ack command, just return the number of the connected replicas. i don’t know if the the intention of the challenge of not. but it seems to work in my code.

---

<div class="post-metadata">

**Author:** ![JayeshBaldawa](https://yyz1.discourse-cdn.com/flex003/user_avatar/forum.codecrafters.io/jayeshbaldawa/32/138_2.png) [@JayeshBaldawa](https://forum.codecrafters.io/u/JayeshBaldawa)\
**Post date:** [May 1, 2024, 4:38pm UTC](https://forum.codecrafters.io/t/redis-replication-na2-timeout-issue/208/3 "2024-05-01T16:38:07Z")

</div>

Yes, that was the case. Spent at least a week for this!  
Thank you 🙂

---

<div class="post-metadata">

**Author:** ![rohitpaulk](https://yyz1.discourse-cdn.com/flex003/user_avatar/forum.codecrafters.io/rohitpaulk/32/6_2.png) [@rohitpaulk](https://forum.codecrafters.io/u/rohitpaulk)\
**Post date:** [May 4, 2024, 1:25pm UTC](https://forum.codecrafters.io/t/redis-replication-na2-timeout-issue/208/4 "2024-05-04T13:25:38Z")

</div>

Yep! We’ll make this more clear when we work on instructions for this stage, sorry it’s taken so long

---

<div class="post-metadata">

**Author:** ![malshoff](https://yyz1.discourse-cdn.com/flex003/user_avatar/forum.codecrafters.io/malshoff/32/1961_2.png) [@malshoff](https://forum.codecrafters.io/u/malshoff)\
**Post date:** [May 8, 2024, 5:16am UTC](https://forum.codecrafters.io/t/redis-replication-na2-timeout-issue/208/5 "2024-05-08T05:16:30Z")

</div>

Does this not make stage 17 incompatible with stage 18? My code passes stage 18 when I default to returning the number of acknowledged replicas on timeout, but it only passes stage 17 if I default to returning the total connected replicas. Can you update the stage 17 test so that the replicas will respond to all “REPLCONF GETACK \*” requests?

Relevant code that’s working for stage 18:

```auto
scope.launch {
            val numReplicas = args[0].toInt()
            val timeout = args[1].toLong()
            val connectedReplicaCount = replicaManager.getReplicaCount()
            if (connectedReplicaCount == 0) {
                println("No replicas connected")
                socket.write(Buffer.buffer(RespSerializer().createInteger(0)))
                return@launch
            }

            val result =
                withTimeoutOrNull(timeout) {
                    while (replicaManager.getAcknowledgmentCount() < connectedReplicaCount && replicaManager.getAcknowledgmentCount() < numReplicas) {
                        delay(10) // Check every 100ms
                        println(
                            "Waiting for $numReplicas replicas to acknowledge. Current count: ${replicaManager.getAcknowledgmentCount()}",
                        )
                    }
                    replicaManager.getAcknowledgmentCount()
                } ?: replicaManager.getAcknowledgmentCount().also {
                    println("Timeout waiting for replicas to acknowledge")
                }

            socket.write(Buffer.buffer(RespSerializer().createInteger(result)))
        }

```

---

<div class="post-metadata">

**Author:** ![rohitpaulk](https://yyz1.discourse-cdn.com/flex003/user_avatar/forum.codecrafters.io/rohitpaulk/32/6_2.png) [@rohitpaulk](https://forum.codecrafters.io/u/rohitpaulk)\
**Post date:** [May 8, 2024, 9:58am UTC](https://forum.codecrafters.io/t/redis-replication-na2-timeout-issue/208/6 "2024-05-08T09:58:23Z")

</div>

Ah, I can see how this’d be confusing.

Here’s what an actual Redis server does (we test against official Redis binaries 100s of times on each release to make sure our tester isn’t faulty):

- A master keeps track of the current replication offset, and the replication offset of every connected replica.
  - The current replication offset incremented every time a new write command is sent to the replication stream
  - The master’s view of each replica’s replication offset is updated whenever a response to GETACK is received.

- When a WAIT command is received
  - A master first checks its replication offset against the offset it has for connected replicas - if all values are equal, it can safely return the number of connected replicas without having to issue GETACK requests.
  - If the current replication offset is ahead of what the master has recorded for connected replicas, the master issues GETACK requests to all replicas and waits for responses before responding.

---

<div class="post-metadata">

**Author:** ![malshoff](https://yyz1.discourse-cdn.com/flex003/user_avatar/forum.codecrafters.io/malshoff/32/1961_2.png) [@malshoff](https://forum.codecrafters.io/u/malshoff)\
**Post date:** [May 8, 2024, 2:34pm UTC](https://forum.codecrafters.io/t/redis-replication-na2-timeout-issue/208/7 "2024-05-08T14:34:16Z")

</div>

That was very helpful, thanks! I definitely overlooked that when reading the docs. I got it working now with a small change.

---

<div class="post-metadata">

**Author:** ![system](https://canada1.discourse-cdn.com/flex003/uploads/codecrafters/original/3X/7/0/700657133935c15703e22c7c8870394f6e6dc27d.svg) [@system](https://forum.codecrafters.io/u/system)\
**Post date:** [May 13, 2024, 2:34pm UTC](https://forum.codecrafters.io/t/redis-replication-na2-timeout-issue/208/8 "2024-05-13T14:34:42Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![system](https://canada1.discourse-cdn.com/flex003/uploads/codecrafters/original/3X/7/0/700657133935c15703e22c7c8870394f6e6dc27d.svg) [@system](https://forum.codecrafters.io/u/system)\
**Post date:** [June 4, 2024, 2:33am UTC](https://forum.codecrafters.io/t/redis-replication-na2-timeout-issue/208/9 "2024-06-04T02:33:04Z")

</div>

Note: I’ve updated the title of this post to include the stage ID (#NA2). You can learn about the stages rename here: [Upcoming change: Stages overhaul](https://forum.codecrafters.io/t/upcoming-change-stages-overhaul/375).
