Replication stage 15

I’m stuck on Replication stage 15.

I’ve addded the feature to respond to REPLCONF GETACK. but i guess somehow the replica isnt able to get that command

Here are my logs:

remote: [tester::#XV6] Running tests for Stage #XV6 (Replication - ACKs with no commands)
remote: [tester::#XV6] Master is running on port 6379
remote: [tester::#XV6] $ ./spawn_redis_server.sh --port 6380 --replicaof "localhost 6379"
remote: [tester::#XV6] master: Waiting for replica to initiate handshake with "PING" command
remote: [tester::#XV6] master: Received bytes: "*1\r\n$4\r\nping\r\n"
remote: [tester::#XV6] master: Received RESP value: ["ping"]
remote: [tester::#XV6] Received ["ping"]
remote: [tester::#XV6] master: Sent "PONG"
remote: [tester::#XV6] master: Sent bytes: "+PONG\r\n"
remote: [tester::#XV6] master: Waiting for replica to send "REPLCONF listening-port 6380" command
remote: [tester::#XV6] master: Received bytes: "*3\r\n$8\r\nREPLCONF\r\n$14\r\nlistening-port\r\n$4\r\n6380\r\n"
remote: [tester::#XV6] master: Received RESP value: ["REPLCONF", "listening-port", "6380"]
remote: [tester::#XV6] Received ["REPLCONF", "listening-port", "6380"]
remote: [tester::#XV6] master: Sent "OK"
remote: [your_program] Logs from your program will appear here!
remote: [your_program] Received: +PONG
remote: [your_program]
remote: [tester::#XV6] master: Sent bytes: "+OK\r\n"
remote: [tester::#XV6] master: Waiting for replica to send "REPLCONF capa" command
remote: [tester::#XV6] master: Received bytes: "*3\r\n$8\r\nREPLCONF\r\n$4\r\ncapa\r\n$6\r\npsync2\r\n"
remote: [tester::#XV6] master: Received RESP value: ["REPLCONF", "capa", "psync2"]
remote: [tester::#XV6] Received ["REPLCONF", "capa", "psync2"]
remote: [your_program] Received: +OK
remote: [your_program]
remote: [your_program]
remote: [tester::#XV6] master: Sent "OK"
remote: [tester::#XV6] master: Sent bytes: "+OK\r\n"
remote: [tester::#XV6] master: Waiting for replica to send "PSYNC" command
remote: [tester::#XV6] master: Received bytes: "*3\r\n$5\r\nPSYNC\r\n$1\r\n?\r\n$2\r\n-1\r\n"
remote: [tester::#XV6] master: Received RESP value: ["PSYNC", "?", "-1"]
remote: [your_program] Received: +OK
remote: [your_program]
remote: [tester::#XV6] Received ["PSYNC", "?", "-1"]
remote: [your_program]
remote: [tester::#XV6] master: Sent "FULLRESYNC 75cd7bc10c49047e0d163660f3b90625b1af31dc 0"
remote: [tester::#XV6] master: Sent bytes: "+FULLRESYNC 75cd7bc10c49047e0d163660f3b90625b1af31dc 0\r\n"
remote: [tester::#XV6] Sending RDB file...
remote: [tester::#XV6] master: Sent bytes: "$88\r\nREDIS0011\xfa\tredis-ver\x057.2.0\xfa\nredis-bits\xc0@\xfa\x05ctime\xc2m\b\xbce\xfa\bused-mem°\xc4\x10\x00\xfa\baof-base\xc0\x00\xff\xf0n;\xfe\xc0\xffZ\xa2"
remote: [tester::#XV6] Sent RDB file.
remote: [tester::#XV6] master: $ redis-cli REPLCONF GETACK *
remote: [tester::#XV6] master: Sent bytes: "*3\r\n$8\r\nREPLCONF\r\n$6\r\nGETACK\r\n$1\r\n*\r\n"
remote: [your_program] Received: +FULLRESYNC 75cd7bc10c49047e0d163660f3b90625b1af31dc 0
remote: [your_program] $88
remote: [your_program] REDIS0011ú       redis-ver♣7.2.0ú
remote: [your_program] redis-bitsÀ@ú♣ctime¼eused-mem°Ä►
remote: [tester::#XV6] Received: "" (no content received)
remote: [tester::#XV6]            ^ error
remote: [tester::#XV6] Error: Expected start of a new RESP2 value (either +, -, :, $ or *)
remote: [tester::#XV6] Test failed

And here’s a snippet of my code:

std::vector<std::vector<std::string>> parseResp(char *buffer) {
    std::vector<std::vector<std::string>> commands;
    std::string raw_message(buffer);
    int i = 0;

    while (i < raw_message.size()) {
        if (raw_message[i] == '+') {
            std::string simple_string;
            while (i < raw_message.size()) {
                simple_string.push_back(raw_message[i]);
                if (raw_message.substr(i, 2) == "\r\n") {
                    simple_string.push_back(raw_message[++i]);
                    break;
                }
                i++;
            }
            commands.push_back(parseSimpleString(simple_string));
        } else if (raw_message[i] == '$') {
            std::string bulk_string;
            int cnt = 0;
            while (i < raw_message.size()) {
                bulk_string.push_back(raw_message[i]);
                if (raw_message.substr(i, 2) == "\r\n") {
                    bulk_string.push_back(raw_message[++i]);
                    if (++cnt == 2) break;
                }
                i++;
            }
            commands.push_back(parseBulkString(bulk_string));
        } else if (raw_message[i] == '*') {
            std::string arr;
            while (i < raw_message.size()) {
                if (raw_message.substr(i, 2) == "\r\n") break;
                arr.push_back(raw_message[i++]);
            }
            int num_elements = std::stoi(arr.substr(1)) * 2;
            arr.push_back(raw_message[i++]);
            arr.push_back(raw_message[i++]);
            while (i < raw_message.size() && num_elements) {
                if (raw_message.substr(i, 2) == "\r\n") num_elements--;
                arr.push_back(raw_message[i++]);
            }
            arr.push_back(raw_message[i]);
            commands.push_back(parseArray(arr));
        }
        i++;
    }

    // std::cout << "Parsed " << commands.size() << " commands" << std::endl;
    for (int i = 0; i < commands.size(); i++) {
        std::cout << "Command " << i << ", has size of " << commands[i].size() << ": ";
        for (int j = 0; j < commands[i].size(); j++) {
            std::cout << commands[i][j] << ' ';
        }
        std::cout << std::endl;
    }
    return commands;
}

i guess the error is that the data sent by the master is in parts which my program isn’t able to handle , Unable to understand how do i handle such cases ?
Or am i wrong with the guess and it is completely different issue?
incase anyone need the whole code
here it is

update
i added a command reader to handle partial commands but still doesnt work
@rohitpaulk any suggestions?

@aryan-011 I’d recommend logging out the bytes you receive soon after every recv to understand exactly what you’re being sent (before any parsing or pre-processing). That could help narrow down the issue here.

The logs say that the value is being sent, so this most likely has something with do with how the bytes returned from recv are parsed and processed by the program.

Closing due to inactivity, please feel free to reopen with logs!

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