If you send to an address and there are multiple handlers listening on that address, a
round-robin selector is used to decide which handler receives your message. This means
that you need to be a bit careful when registering addresses.
Message Passing Architectures
What I've been describing here is a message passing-based architecture that I've implemen-
ted using a simple chat client. The details of the chat client are much less important than the
overall pattern, so let's talk about message passing itself.
The first thing to note is that this is a no-shared-state design. All communication between our
verticles is done by sending messages over our event bus. This means that we don't need to
protect any shared state, so we don't need any kind of locks or use of the synchronized
keyword in our code base at all. Concurrency is much simpler.
In order to ensure that we aren't sharing any state between verticles, we've actually imposed
a few constraints on the types of messages being sent over the event bus. The example mes-
sages that we passed over the event bus in this case were plain old Java strings. These are im-
mutable by design, which means that we can safely send them between verticles. Because the
receiving handler can't modify the state of the String , it can't interfere with the behavior of
Vert.x doesn't restrict us to sending strings as messages, though; we can use more complex
JSON objects or even build our own binary messages using the Buffer class. These aren't
immutable messages, which means that if we just naively passed them around, our message
senders and message handlers could share state by writing or reading through these mes-
The Vert.x framework avoids this problem by copying any mutable message the moment that
you send it. That way the receiver gets the correct value, but you still aren't sharing state.
Regardless of whether you're using the Vert.x framework, it's really important that you don't
let your messages be an accidental source of shared state. Completely immutable messages
are the simplest way of doing this, but copying the message also solves the problem.
The verticle model of development also lets us implement a concurrent system that is easy to
test. This is because each verticle can be tested in isolation by sending messages in and ex-
pecting results to be returned. We can then compose a complex system out of individually