/*
 * Copyright (c) 2011-2017 Contributors to the Eclipse Foundation
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
 * which is available at https://www.apache.org/licenses/LICENSE-2.0.
 *
 * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
 */

/**
 * == The Event Bus
 * :toc: left
 *
 * The {@link io.vertx.core.eventbus.EventBus event bus} is the *nervous system* of Vert.x.
 *
 * There is a single event bus instance for every Vert.x instance and it is obtained using the method {@link io.vertx.core.Vertx#eventBus}.
 *
 * The event bus allows different parts of your application to communicate with each other irrespective of what language they are written in,
 * and whether they're in the same Vert.x instance, or in a different Vert.x instance.
 *
 * It can even be bridged to allow client side JavaScript running in a browser to communicate on the same event bus.
 *
 * The event bus forms a distributed peer-to-peer messaging system spanning multiple server nodes and multiple browsers.
 *
 * The event bus supports publish/subscribe, point to point, and request-response messaging.
 *
 * The event bus API is very simple. It basically involves registering handlers, unregistering handlers and
 * sending and publishing messages.
 *
 * First some theory:
 *
 * === The Theory
 *
 * ==== Addressing
 *
 * Messages are sent on the event bus to an *address*.
 *
 * Vert.x doesn't bother with any fancy addressing schemes. In Vert.x an address is simply a string.
 * Any string is valid. However it is wise to use some kind of scheme, e.g. using periods to demarcate a namespace.
 *
 * Some examples of valid addresses are +europe.news.feed1+, +acme.games.pacman+, +sausages+, and +X+.
 *
 * ==== Handlers
 *
 * Messages are received in handlers. You register a handler at an address.
 *
 * Many different handlers can be registered at the same address.
 *
 * A single handler can be registered at many different addresses.
 *
 * ==== Publish / subscribe messaging
 *
 * The event bus supports *publishing* messages.
 *
 * Messages are published to an address. Publishing means delivering the message
 * to all handlers that are registered at that address.
 *
 * This is the familiar *publish/subscribe* messaging pattern.
 *
 * ==== Point to point and Request-Response messaging
 *
 * The event bus also supports *point to point* messaging.
 *
 * Messages are sent to an address. Vert.x will then route it to just one of the handlers registered at that address.
 *
 * If there is more than one handler registered at the address,
 * one will be chosen using a non-strict round-robin algorithm.
 *
 * With point to point messaging, an optional reply handler can be specified when sending the message.
 *
 * When a message is received by a recipient, and has been handled, the recipient can optionally decide to reply to
 * the message. If they do so the reply handler will be called.
 *
 * When the reply is received back at the sender, it too can be replied to. This can be repeated ad-infinitum,
 * and allows a dialog to be set-up between two different verticles.
 *
 * This is a common messaging pattern called the *request-response* pattern.
 *
 * ==== Best-effort delivery
 *
 * Vert.x does it's best to deliver messages and won't consciously throw them away. This is called *best-effort* delivery.
 *
 * However, in case of failure of all or parts of the event bus, there is a possibility messages will be lost.
 *
 * If your application cares about lost messages, you should code your handlers to be idempotent, and your senders
 * to retry after recovery.
 *
 * ==== Types of messages
 *
 * Out of the box Vert.x allows any primitive/simple type, String, or {@link io.vertx.core.buffer.Buffer buffers} to
 * be sent as messages.
 *
 * However it's a convention and common practice in Vert.x to send messages as http://json.org/[JSON]
 *
 * JSON is very easy to create, read and parse in all the languages that Vert.x supports so it has become a kind of
 * _lingua franca_ for Vert.x.
 *
 * However you are not forced to use JSON if you don't want to.
 *
 * The event bus is very flexible and also supports sending arbitrary objects over the event bus.
 * You do this by defining a {@link io.vertx.core.eventbus.MessageCodec codec} for the objects you want to send.
 *
 * === The Event Bus API
 *
 * Let's jump into the API
 *
 * ==== Getting the event bus
 *
 * You get a reference to the event bus as follows:
 *
 * [source,$lang]
 * ----
 * {@link examples.EventBusExamples#example0_5}
 * ----
 *
 * There is a single instance of the event bus per Vert.x instance.
 *
 * ==== Registering Handlers
 *
 * This simplest way to register a handler is using {@link io.vertx.core.eventbus.EventBus#consumer(String, io.vertx.core.Handler)}.
 * Here's an example:
 *
 * [source,$lang]
 * ----
 * {@link examples.EventBusExamples#example1}
 * ----
 *
 * When a message arrives for your handler, your handler will be called, passing in the {@link io.vertx.core.eventbus.Message message}.
 *
 * The object returned from call to +consumer()+ is an instance of {@link io.vertx.core.eventbus.MessageConsumer}
 *
 * This object can subsequently be used to unregister the handler, or use the handler as a stream.
 *
 * Alternatively you can use {@link io.vertx.core.eventbus.EventBus#consumer(String, io.vertx.core.Handler)} to
 * to return a +MessageConsumer+ with no handler set, and then set the handler on that. For example:
 *
 * [source,$lang]
 * ----
 * {@link examples.EventBusExamples#example2}
 * ----
 *
 * When registering a handler on a clustered event bus, it can take some time for the registration to reach all
 * nodes of the cluster.
 *
 * If you want to be notified when this has completed, you can register a {@link io.vertx.core.eventbus.MessageConsumer#completionHandler completion handler}
 * on the +MessageConsumer+ object.
 *
 * [source,$lang]
 * ----
 * {@link examples.EventBusExamples#example3}
 * ----
 *
 * ==== Un-registering Handlers
 *
 * To unregister a handler, call {@link io.vertx.core.eventbus.MessageConsumer#unregister}.
 *
 * If you are on a clustered event bus, un-registering can take some time to propagate across the nodes, if you want to
 * be notified when this is complete use {@link io.vertx.core.eventbus.MessageConsumer#unregister(io.vertx.core.Handler)}.
 *
 * [source,$lang]
 * ----
 * {@link examples.EventBusExamples#example4}
 * ----
 *
 * ==== Publishing messages
 *
 * Publishing a message is simple. Just use {@link io.vertx.core.eventbus.EventBus#publish} specifying the
 * address to publish it to.
 *
 * [source,$lang]
 * ----
 * {@link examples.EventBusExamples#example5}
 * ----
 *
 * That message will then be delivered to all handlers registered against the address +news.uk.sport+.
 *
 * ==== Sending messages
 *
 * Sending a message will result in only one handler registered at the address receiving the message.
 * This is the point to point messaging pattern. The handler is chosen in a non-strict round-robin fashion.
 *
 * You can send a message with {@link io.vertx.core.eventbus.EventBus#send}
 *
 * [source,$lang]
 * ----
 * {@link examples.EventBusExamples#example6}
 * ----
 *
 * include::override/eventbus_headers.adoc[]
 *
 * ==== Message ordering
 *
 * Vert.x will deliver messages to any particular handler in the same order they were sent from any particular sender.
 *
 * ==== The Message object
 *
 * The object you receive in a message handler is a {@link io.vertx.core.eventbus.Message}.
 *
 * The {@link io.vertx.core.eventbus.Message#body} of the message corresponds to the object that was sent or published.
 *
 * The headers of the message are available with {@link io.vertx.core.eventbus.Message#headers}.
 *
 * ==== Acknowledging messages / sending replies
 *
 * When using {@link io.vertx.core.eventbus.EventBus#send} the event bus attempts to deliver the message to a
 * {@link io.vertx.core.eventbus.MessageConsumer} registered with the event bus.
 *
 * In some cases it's useful for the sender to know when the consumer has received the message and "processed" it.
 *
 * To acknowledge that the message has been processed the consumer can reply to the message by calling {@link io.vertx.core.eventbus.Message#reply}.
 *
 * When this happens it causes a reply to be sent back to the sender and the reply handler is invoked with the reply.
 *
 * An example will make this clear:
 *
 * The receiver:
 *
 * [source,$lang]
 * ----
 * {@link examples.EventBusExamples#example8}
 * ----
 *
 * The sender:
 *
 * [source,$lang]
 * ----
 * {@link examples.EventBusExamples#example9}
 * ----
 *
 * The reply can contain a message body which can contain useful information.
 *
 * What the "processing" actually means is application defined and depends entirely on what the message consumer does
 * and is not something that the Vert.x event bus itself knows or cares about.
 *
 * Some examples:
 *
 * * A simple message consumer which implements a service which returns the time of the day would acknowledge with a message
 * containing the time of day in the reply body
 * * A message consumer which implements a persistent queue, might acknowledge with `true` if the message was successfully
 * persisted in storage, or `false` if not.
 * * A message consumer which processes an order might acknowledge with `true` when the order has been successfully processed
 * so it can be deleted from the database
 *
 * ==== Sending with timeouts
 *
 * When sending a message with a reply handler you can specify a timeout in the {@link io.vertx.core.eventbus.DeliveryOptions}.
 *
 * If a reply is not received within that time, the reply handler will be called with a failure.
 *
 * The default timeout is 30 seconds.
 *
 * ==== Send Failures
 *
 * Message sends can fail for other reasons, including:
 *
 * * There are no handlers available to send the message to
 * * The recipient has explicitly failed the message using {@link io.vertx.core.eventbus.Message#fail}
 *
 * In all cases the reply handler will be called with the specific failure.
 *
 * include::override/eventbus.adoc[]
 *
 * ==== Clustered Event Bus
 *
 * The event bus doesn't just exist in a single Vert.x instance. By clustering different Vert.x instances together on
 * your network they can form a single, distributed, event bus.
 *
 * ==== Clustering programmatically
 *
 * If you're creating your Vert.x instance programmatically you get a clustered event bus by configuring the Vert.x
 * instance as clustered;
 *
 * [source,$lang]
 * ----
 * {@link examples.EventBusExamples#example12}
 * ----
 *
 * You should also make sure you have a {@link io.vertx.core.spi.cluster.ClusterManager} implementation on your classpath,
 * for example the default {@code HazelcastClusterManager}.
 *
 * ==== Clustering on the command line
 *
 * You can run Vert.x clustered on the command line with
 *
 *  vertx run my-verticle.js -cluster
 *
 * === Automatic clean-up in verticles
 *
 * If you're registering event bus handlers from inside verticles, those handlers will be automatically unregistered
 * when the verticle is undeployed.
 *
 * == Configuring the event bus
 *
 * The event bus can be configured. It is particularly useful when the event bus is clustered. Under the hood
 * the event bus uses TCP connections to send and receive message, so the
 * {@link io.vertx.core.eventbus.EventBusOptions} let you configure all aspects of these TCP connections. As
 * the event bus acts as a server and client, the configuration is close to
 * {@link io.vertx.core.net.NetClientOptions} and {@link io.vertx.core.net.NetServerOptions}.
 *
 * [source,$lang]
 * ----
 * {@link examples.EventBusExamples#example13}
 * ----
 *
 * The previous snippet depicts how you can use SSL connections for the event bus, instead of plain TCP
 * connections.
 *
 * **WARNING**: to enforce the security in clustered mode, you **must** configure the
 * cluster manager to use encryption or enforce security. Refer to the documentation of the cluster
 * manager for further details.
 *
 * The event bus configuration needs to be consistent in all the cluster nodes.
 *
 * The {@link io.vertx.core.eventbus.EventBusOptions} also lets you specify whether or not the event bus is
 * clustered, the port and host, as you would do with {@link io.vertx.core.VertxOptions#setClustered(boolean)},
 *  {@link io.vertx.core.VertxOptions#getClusterHost()} and {@link io.vertx.core.VertxOptions#getClusterPort()}.
 *
 * When used in containers, you can also configure the public host and port:
 *
 * [source,$lang]
 * ----
 * {@link examples.EventBusExamples#example14}
 * ----
 */
package io.vertx.core.eventbus;

