# Redis Stage #ZU2 in Zig. I don't know why the test fails

**URL:** <https://forum.codecrafters.io/t/redis-stage-zu2-in-zig-i-dont-know-why-the-test-fails/2913>\
**Category:** Challenges\
**Tags:** challenge:redis\
**Created:** [November 12, 2024, 6:08pm UTC](https://forum.codecrafters.io/t/redis-stage-zu2-in-zig-i-dont-know-why-the-test-fails/2913 "2024-11-12T18:08:10Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![brodo](https://yyz1.discourse-cdn.com/flex003/user_avatar/forum.codecrafters.io/brodo/32/2902_2.png) [@brodo](https://forum.codecrafters.io/u/brodo)\
**Post date:** [November 12, 2024, 6:08pm UTC](https://forum.codecrafters.io/t/redis-stage-zu2-in-zig-i-dont-know-why-the-test-fails/2913/1 "2024-11-12T18:08:10Z")

</div>

I’m stuck on Stage #ZU2.

Here are my logs:

```auto
[tester::#ZU2] Running tests for Stage #ZU2 (Handle concurrent clients)
[tester::#ZU2] $ ./your_program.sh
[your_program] Added new connection with index 0
[tester::#ZU2] client-1: $ redis-cli PING
[tester::#ZU2] client-1: Sent bytes: "*1\r\n$4\r\nPING\r\n"
[your_program] Read from connection 0:
[your_program] *1
[your_program] Read from connection 0:
[your_program] $4
[your_program] Read from connection 0:
[your_program] PING
[your_program] Sending PONG
[tester::#ZU2] client-1: Received bytes: "+PONG\r\n"
[tester::#ZU2] client-1: Received RESP simple string: "PONG"
[tester::#ZU2] Received "PONG"
[tester::#ZU2] client-2: $ redis-cli PING
[tester::#ZU2] client-2: Sent bytes: "*1\r\n$4\r\nPING\r\n"
[tester::#ZU2] Received: "" (no content received)
[tester::#ZU2] ^ error
[tester::#ZU2] Error: Expected start of a new RESP2 value (either +, -, :, $ or *)
[tester::#ZU2] Test failed
[tester::#ZU2] Terminating program
[tester::#ZU2] Program terminated successfully

```

However, when I connect with several `redis-cli` instances to my server locally, everything works. I tested this by connecting manually in different terminal sessions and by using GNU parallel:

```zsh
parallel -j 6 redis-cli -e "PING" ::: {1..6}
PONG
PONG
PONG
PONG
PONG
PONG

```

Here is my code:

```zig
const std = @import("std");
const net = std.net;

pub fn main() !void {
    const address = try net.Address.resolveIp("0.0.0.0", 6379);

    var listener = try address.listen(.{
        .reuse_address = true,
        .force_nonblocking = true,
    });
    defer listener.deinit();

    var list: [255]net.Server.Connection = undefined;
    var active: [255]bool = [_]bool{false} ** 255;
    var buf: [256]u8 = undefined;
    while (true) {
        if (std.mem.indexOfScalar(bool, &active, false)) |idx| { // if we can accept new connections
            if (listener.accept()) |conn| {
                list[idx] = conn;
                active[idx] = true;
                std.debug.print("Added new connection with index {d}\n", .{idx});
            } else |err| {
                if (err != error.WouldBlock) {
                    std.debug.print("Could not accept new connecion. Error: {any}\n", .{err});
                }
            }
        } else {
            std.debug.print("Could not accept new connection, all 256 slots are in use!\n", .{});
        }
        for (active, 0..) |a, i| {
            if (!a) continue;
            const conn = &list[i];
            const reader = conn.stream.reader();
            if (reader.readUntilDelimiter(&buf, 0x0a)) |slice| {
                std.debug.print("Read from connection {d}:\n{s}\n", .{ i, slice });
                if (std.mem.eql(u8, slice, "PING\r")) {
                    std.debug.print("Sending PONG\n", .{});
                    _ = try conn.stream.write("+PONG\r\n");
                }
                if (std.mem.eql(u8, slice, "DOCS\r")) {
                    std.debug.print("Sending DOCS\n", .{});
                    _ = try conn.stream.write("%0\r\n");
                }
            } else |err| {
                switch (err) {
                    error.WouldBlock => {},
                    error.EndOfStream => {
                        std.debug.print("Client closed connection {d}\n", .{i});
                        active[i] = false;
                        list[i] = undefined;
                    },
                    else => {
                        std.debug.print("Cannot read from connection {d}, error: {any}\n", .{ i, err });
                        active[i] = false;
                        list[i] = undefined;
                    },
                }
            }
        }
    }
}

```

Any help is greatly appreciated.

---

<div class="post-metadata">

**Author:** ![shreyasganesh0](https://yyz1.discourse-cdn.com/flex003/user_avatar/forum.codecrafters.io/shreyasganesh0/32/2559_2.png) [@shreyasganesh0](https://forum.codecrafters.io/u/shreyasganesh0)\
**Post date:** [November 12, 2024, 10:44pm UTC](https://forum.codecrafters.io/t/redis-stage-zu2-in-zig-i-dont-know-why-the-test-fails/2913/2 "2024-11-12T22:44:51Z")

</div>

> [@brodo](#):
>
> `Sending`

you will need to handle the listening and responding asynchronously eihter via a seperate thread for the client or throught handing the task to the event loop. Since its zig I think threading will be easier not sure exactly how to implement it but hope this helps.

---

<div class="post-metadata">

**Author:** ![brodo](https://yyz1.discourse-cdn.com/flex003/user_avatar/forum.codecrafters.io/brodo/32/2902_2.png) [@brodo](https://forum.codecrafters.io/u/brodo)\
**Post date:** [November 12, 2024, 11:26pm UTC](https://forum.codecrafters.io/t/redis-stage-zu2-in-zig-i-dont-know-why-the-test-fails/2913/3 "2024-11-12T23:26:00Z")

</div>

Thanks for the response. However, I’m using a non-blocking TCP listener, so I can already accept multiple connections concurrently.

---

<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:** [November 13, 2024, 2:04am UTC](https://forum.codecrafters.io/t/redis-stage-zu2-in-zig-i-dont-know-why-the-test-fails/2913/4 "2024-11-13T02:04:19Z")

</div>

Hi @brodo, does Zig support a native event loop? Manually handling everything inside a `while` loop could be the cause of the issue.

Currently, the code didn’t accept a second connection:

 ![image](https://canada1.discourse-cdn.com/flex003/uploads/codecrafters/original/2X/2/2e0b8731a193fd838668af8c44a7d890007dbefc.png)

I tried adding a 10 ms sleep interval within the `while` loop:

```auto
    while (true) {
        std.time.sleep(std.time.ns_per_ms * 10);

```

This allowed a second connection, but it still wasn’t enough:

 ![image](https://canada1.discourse-cdn.com/flex003/uploads/codecrafters/original/2X/1/138d963eaf526417fc967edba80596931eecec06.png)

Adjusting the sleep interval doesn’t seem like a right solution. A native event loop (if available in Zig) would likely handle multiple non-blocking connections more gracefully.

---

<div class="post-metadata">

**Author:** ![shreyasganesh0](https://yyz1.discourse-cdn.com/flex003/user_avatar/forum.codecrafters.io/shreyasganesh0/32/2559_2.png) [@shreyasganesh0](https://forum.codecrafters.io/u/shreyasganesh0)\
**Post date:** [November 13, 2024, 4:07am UTC](https://forum.codecrafters.io/t/redis-stage-zu2-in-zig-i-dont-know-why-the-test-fails/2913/5 "2024-11-13T04:07:17Z")

</div>

Yes I was referring more about the response part where you could hand off the response to a new thread per client request not sure about the zig libraries for this but you might want to put the entire recv write block onto the event loop which might need you to write it as a seperate function. I might be way off base though.

---

<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:** [November 23, 2024, 2:31pm UTC](https://forum.codecrafters.io/t/redis-stage-zu2-in-zig-i-dont-know-why-the-test-fails/2913/6 "2024-11-23T14:31:21Z")

</div>

Closing this thread due to inactivity. If you still need assistance, feel free to reopen or 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:** [November 28, 2024, 2:31pm UTC](https://forum.codecrafters.io/t/redis-stage-zu2-in-zig-i-dont-know-why-the-test-fails/2913/7 "2024-11-28T14:31:53Z")

</div>

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