I think the issue was by ths following , How do I best handle exceptions when calling a service that returns a CompletionStage from inside a Netty handler. , Yes what you have shown in your code should cover both correctly.
I hope this helps you . This is a classic slow consumer problem and the first step to resolving it is to determine what the appropriate action is when a slow consumer is detected. If it is acceptable that the slow consumer misses messages then the solution is some variation on dropping messages or unsubscribing them from the feed. For example, if it's acceptable that the client misses messages then, when one is received from JMS, check if the channel is writable. If it isn't, drop the message. If you want to give yourself a bit more of a buffer (although OS buffers are quite large) you can track the number of write completion future's that haven't completed (ie the messages haven't been written to the OS send buffer) and drop messages if there are too many outstanding write requests. If the client may not miss messages, and is consistently slow, then the problem is more difficult. One option might be to divert messages to a JMS queue with a specific header value, then open a new consumer that reads messages from that queue using a JMS selector. This will put more load on the JMS server but might be appropriate for temporary slowness and hopefully it won't interfere with you main topic feeds. Alternatively you might want to stash the messages in a different store, such as a database, so you can poll for messages when they can be sent. If you do this right a single polling thread can cope with many clients (query for clients which have outstanding messages, then for each client, load a bunch of messages). However this isn't as convenient as using JMS.
Accessing an instance of Netty server from inside a Netty Handler
help you fix your problem If you have more than one eventLoop you are going to have concurrent access to the static ArrayList across multiple eventLoops. So YES you should take care of synchronizing the access to the ArrayList.
Vert.x 3, request handler POST, async CompletionStage or CompletableFuture
This might help you There nothing special with CompletableFuture. It's like any async api. Simple example, that follows vertx thread model. Computation happens on some computational context, and result writes on vertx event loop: