Replication and Event Loop

Hey!

I am a bit stuck on handling replication for Redis at stage #gl7. I\m trying to use an event loop with Java NIO but I am struggling with figuring out how the replica can both handle messages and connect to the master without spawning a new thread and creating a separate event loop there.

My EventLoop looks like this:

package core;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

class EventLoop {

private final RedisCommandHandler commandHandler;
    public EventLoop(RedisCommandHandler commandHandler) {
        this.commandHandler = commandHandler;
    }
    private boolean stop = false;



    protected void run(int port) throws IOException {
        try (ServerSocketChannel ssc = ServerSocketChannel.open()) {
            ssc.bind(new InetSocketAddress("localhost", port));
            ssc.configureBlocking(false);
            Selector selector = Selector.open();
            ssc.register(selector, SelectionKey.OP_ACCEPT);

            while (!stop) {
                selector.select();
                Set<SelectionKey> selectedKeys = selector.selectedKeys();
                Iterator<SelectionKey> keyIterator = selectedKeys.iterator();
                while (keyIterator.hasNext()) {
                    SelectionKey key = keyIterator.next();
                    if (key.isAcceptable()) {
                        // accpets a new client and say that we're interested in reading from that client
                        ServerSocketChannel server = (ServerSocketChannel) key.channel();
                        SocketChannel client = server.accept();
                        client.configureBlocking(false);
                        client.register(selector, SelectionKey.OP_READ);
                        System.out.println("redis: registered client " + client.getRemoteAddress());
                    } else if (key.isReadable()) {
                        // we got some data from a client that we are interested in and now we read
                        SocketChannel client = (SocketChannel) key.channel();
                        ByteBuffer buffer = ByteBuffer.allocate(256);
                        int bytesRead = client.read(buffer);
                        System.out.printf("redis: recv %s bytes from client " + client.getRemoteAddress() + "%n", bytesRead);
                        if (bytesRead == -1) {
                            client.close();
                        } else {
                            buffer.flip();
                           List<String> rawCommands  = RespParser.read(buffer);
                           byte[] res = commandHandler.process(rawCommands);
                            client.write(ByteBuffer.wrap(res));
                        }

                    }
                    keyIterator.remove();
                }
            }
        }
    }
}

How would you suggest handling connecting to the master as a replica while still running the event loop to handle messages?

Here is my GitHub link: GitHub - TobiasKrok/redis: redis challenge from Codecrafters
Thank you!

How would you suggest handling connecting to the master as a replica while still running the event loop to handle messages?

To pass this stage, try to complete the handshake before starting the event loop.

I am struggling with figuring out how the replica can both handle messages and connect to the master without spawning a new thread and creating a separate event loop there.

Yes, you’ll eventually need to juggle both, but you’ll in a better position to tackle the problem once you have more completed stages under your belt.

Fair enough, I will try that before worrying about the rest!

Do you happen to know how Redis handles it in its event loop? Does it handle replication in a separate process?

Thank you for your help!

1 Like

TBH, I haven’t delved into how the official Redis works in this particular area. But we do have a code walkthrough about How the Redis event loop is implemented.

My implementation in Python used a non-blocking Task (coroutine). I believe Java has something similar too.

I see, I’ll have to investigate the event loop implementation a bit more! Might just have to spawn a separate thread.

Thank you!

1 Like

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