# Duplicate "+OK/r/n" Responses sent to Client and Replica from Master Server

**URL:** <https://forum.codecrafters.io/t/duplicate-ok-r-n-responses-sent-to-client-and-replica-from-master-server/1021>\
**Category:** Challenges\
**Tags:** challenge:redis\
**Created:** [July 13, 2024, 5:40pm UTC](https://forum.codecrafters.io/t/duplicate-ok-r-n-responses-sent-to-client-and-replica-from-master-server/1021 "2024-07-13T17:40:59Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![nwokejij](https://yyz1.discourse-cdn.com/flex003/user_avatar/forum.codecrafters.io/nwokejij/32/803_2.png) [@nwokejij](https://forum.codecrafters.io/u/nwokejij)\
**Post date:** [July 13, 2024, 5:40pm UTC](https://forum.codecrafters.io/t/duplicate-ok-r-n-responses-sent-to-client-and-replica-from-master-server/1021/1 "2024-07-13T17:40:59Z")

</div>

Hello, I am stuck on Stage 25, WAIT with multiple commands. I was able to pass the first test for the WAIT command, but the problem that I am having occurs when the tester switches from the client to the replicas. For instance, after the first WAIT test is passed, the tester switches to the client and sends a “SET” command, which my server receives and sends a “+OK\r\n” response to. However, when the tester switches to replica-1, the replica-1 also receives the same “+OK\r\n” response, even though it expects to receive the propagated SET command. What confuses me is that I had no problems with this in the first WAIT test (I was able to propagate the command to the replicas), but in the second WAIT test I am receiving this issue. I suspect my issue may deal with the possibility that my server is sharing the same connection with the client and the replicas, so I tried tagging each connection with a type to signify the difference (connection.client vs connection.replica), but I still face the same issue. I also tried to store the repl1 socket connection in a variable (repl1Connect) and using an asynchrounous function to wait for all the data to be loaded. Here is my code:

```auto
const server = net.createServer((connection) => {
  // Handle connection
    connection.type = 'client';
    connection.on('data', async (data) => {
        const command = await readData(data);
        let commands = command.slice(3).split('\r\n');
        commands.pop();
        console.log("Commands", commands);
        if (commands.includes("INFO")){
                if (isSlave != -1){
                    connection.write(getBulkString("role:slave"));
                }
                connection.write(getBulkString("role:master\nmaster_replid:8371b4fb1155b71f4a04d3e1bc3e18c4a990aeeb\nmaster_repl_offset:0"));
            } else if (commands.includes("REPLCONF")){
                connection.write("+OK\r\n");
            } else if (commands.includes("ECHO")){
                index = commands.indexOf("ECHO");
                connection.write(commands.slice(index+1).join("\r\n"));
            } else if (commands.includes("PING")){
                connection.write("+PONG\r\n");
            } else if (commands.includes("SET")){
                index = commands.indexOf("SET");
                dictionary[commands[index + 2]] = dictionary[commands[index + 4]];
                    if (commands.includes("px")){
                        let px = commands.indexOf("px");
                        setTimeout(() => {
                            delete dictionary[commands[index + 2]];
                            }, parseInt(commands[px + 2])
                        )
                    }
                        if (commands.includes("baz")){
                            repl1Connect.write("*3\r\n" + getBulkString("REPLCONF") + getBulkString("GETACK") + getBulkString("*"));
                            connection.write("+OK\r\n");
                            repl1Connect.write("*3\r\n" + getBulkString("REPLCONF") + getBulkString("GETACK") + getBulkString("*"));
                            connection.write("*3\r\n" + getBulkString("REPLCONF") + getBulkString("GETACK") + getBulkString("*"));
                            
                        } else {
                            connection.write("+OK\r\n");
                        }
                        propagateToReplicas(command);
                    }else if (commands.includes("GET")){
                   index = commands.indexOf("GET");
                if (!(commands[index + 2] in dictionary) && !(commands[index + 2] in replicaDict)) {
                    connection.write(getBulkString(null));
                } else if (commands[index + 2] in replicaDict) {
                    connection.write(getBulkString(replicaDict[commands[index + 2]]));
                } else{
                    connection.write(getBulkString(dictionary[commands[index + 2]]));
                } 
                
            } else if (commands.includes("WAIT")){
                index = commands.indexOf("WAIT");
                noOfReps = parseInt(commands[index + 2])
                time = parseInt(commands[index+4]);
                waitCommand(noOfReps, time, connection);
            }
            if (commands.includes("PSYNC")){
            connection.write("+FULLRESYNC 8371b4fb1155b71f4a04d3e1bc3e18c4a990aeeb 0\r\n");
            const hex = "524544495330303131fa0972656469732d76657205372e322e30fa0a72656469732d62697473c040fa056374696d65c26d08bc65fa08757365642d6d656dc2b0c41000fa08616f662d62617365c000fff06e3bfec0ff5aa2";
            const buffer = Buffer.from(hex, 'hex');

// Calculate the length of the file in bytes
const bytes = buffer.length;

// Create the RDB file header with the length of the file
let rdbFileHeader = `$${bytes}\r\n`;

// Combine the header and the buffer into a single buffer
const rdbFileBuffer = Buffer.concat([Buffer.from(rdbFileHeader, 'ascii'), buffer]);
            connection.write(rdbFileBuffer);
            connection.type = 'replica'; // Set type as replica
            replicas.push(connection);
            if (replicas.length == 1){
                repl1Connect = connection;
            }
            numOfReplicas += 1;
            
            } 
            
        })

function waitCommand(howMany, time, connection){
    numOfAcks = 0;
    console.log("Propagated Commands", propagatedCommands);
    if (propagatedCommands > 0){
        propagateToReplicas("*3\r\n" + getBulkString("REPLCONF") + getBulkString("GETACK") + getBulkString("*"));
        setTimeout(() => {

            connection.write(`:${numOfAcks > howMany ? howMany : numOfAcks}\r\n`);
        }, time);
    }
    

    }
const propagateToReplicas = (command) => {
    if (replicas.length == 0){
        return
    }
    replicas.forEach((replica) => {
        console.log("Command to be Propagated", command);
        replica.write(command);
        replica.on("data", (data) => {
            const commands = data.toString().split('\r\n');
            if (commands.includes("ACK")){
                numOfAcks += 1;
            }
        })

    })
    propagatedCommands += 1;
}

```

Here are the logs that I am receiving. Notice that I did not have this issue in the first WAIT test:

 ![Screenshot (54)](https://canada1.discourse-cdn.com/flex003/uploads/codecrafters/original/1X/9e7239b570765bc12c241b746d1798b45fd12089.png)  
 ![Screenshot (55)](https://canada1.discourse-cdn.com/flex003/uploads/codecrafters/original/1X/143887dc02e39f2cfe1994e3980241ace8dad78c.png)  
 ![Screenshot (56)](https://canada1.discourse-cdn.com/flex003/uploads/codecrafters/original/1X/af80f53cf04a33f1905ce318bce45fc341d07111.png)  
 ![Screenshot (57)](https://canada1.discourse-cdn.com/flex003/uploads/codecrafters/original/1X/c773871a136467d8ab1968b81bbc98b7762dd234.png)  
 ![Screenshot (58)](https://canada1.discourse-cdn.com/flex003/uploads/codecrafters/original/1X/bf49f759e2ab5127f5babac1f40c08f4dd6998ef.png)  
 ![Screenshot (59)](https://canada1.discourse-cdn.com/flex003/uploads/codecrafters/original/1X/7a2b1827a40c0f0085400cfa1f93f81cde0f53f5.png)  
 ![Screenshot (60)](https://canada1.discourse-cdn.com/flex003/uploads/codecrafters/original/1X/b9db7b73d2ea40d163bbd82cd107f1088d977bc1.png)  
 ![Screenshot (61)](https://canada1.discourse-cdn.com/flex003/uploads/codecrafters/original/1X/2f9e34bdcf3c32d1957ba573507029ab3bdbf051.png)

---

<div class="post-metadata">

**Author:** ![andy1li](https://yyz1.discourse-cdn.com/flex003/user_avatar/forum.codecrafters.io/andy1li/32/10_2.png) [@andy1li](https://forum.codecrafters.io/u/andy1li)\
**Post date:** [October 4, 2024, 3:05am UTC](https://forum.codecrafters.io/t/duplicate-ok-r-n-responses-sent-to-client-and-replica-from-master-server/1021/3 "2024-10-04T03:05:00Z")

</div>

Closing this thread due to inactivity. If you still need assistance, feel free to start a new discussion!

---

<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:** [October 9, 2024, 3:05am UTC](https://forum.codecrafters.io/t/duplicate-ok-r-n-responses-sent-to-client-and-replica-from-master-server/1021/4 "2024-10-09T03:05:33Z")

</div>

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