Search code examples
kotlinvert.xvertx-verticlevertxoptions

How do I launch clients on different event loops?


I am creating a testing application that suppose to have many connections to a server. When I create a client from my Verticle it is always processing the connection and messages on the same tread.

When I created my verticle I set

options.setEventLoopPoolSize(4)

So I would it expect it to round robin to the 4 event loops because I want to have millions of connections.

I'm doing

        launch {
            val socket = netClient.connectAwait(port, host)
            log.info().log("connected on - {} {}", Thread.currentThread(), Vertx.currentContext())
            socket.handler {
                log.info().log("{}", it)
            }
        }

2019-06-04 17:30:06,479 INFO [vert.x-eventloop-thread-0] MainVerticle: connected on - Thread[vert.x-eventloop-thread-0,5,main] io.vertx.core.impl.EventLoopContext@150049b3

Always on same thread.... How do I launch the connection on different event-loops


Solution

  • First and foremost, creating many connections from a single host is a mistake. You'll get into a bottleneck on your client machine probably long before you overload your server.

    Second, creating your own load test tool is a mistake. There are excellent tools available for that already, like wrk, which solved many problems you'll have.

    Now, to the question at hand. Connections are launched on different threads of the event loop. You can see it running the following code:

    private const val port = 8443
    
    fun main() {
        val counter = AtomicLong(0)
        val vertx = Vertx.vertx()
        val client = vertx.createNetClient()
        var timestamp = System.currentTimeMillis()
        vertx.createNetServer().connectHandler { ctx ->
            counter.getAndIncrement()
            if (System.currentTimeMillis() - timestamp > 1000) {
                println(counter.get())
                counter.set(0)
                timestamp = System.currentTimeMillis()
            }
            ctx.end()
        }.listen(port)
    
        println("Server started")
    
        ddos(client)
    }
    
    fun ddos(client: NetClient) {
        for (i in 0..999999) {
            client.connect(port, "localhost") {
                println(Thread.currentThread().name)
            }
        }
    }
    

    Note that you'll also get much more threads:

    vert.x-eventloop-thread-14
    vert.x-eventloop-thread-12
    vert.x-eventloop-thread-10
    vert.x-eventloop-thread-14
    vert.x-eventloop-thread-14
    vert.x-eventloop-thread-10
    

    Also note that you don't actually need to use coroutines for that.