blob: 837f8c69082b5e6005f383565d3d3452cab826aa [file] [log] [blame] [view]
## Event bus
`EventBus` is a bare-bones messaging mechanism, to decouple components from each other, and
broadcast messages to more than one component at a time.
Producers fire events on the bus; consumers register to be notified for a particular event class.
For example, `DefaultDriverConfigLoader` reloads the config periodically, and fires an event if it
detects a change:
```java
boolean changed = driverConfig.reload(configSupplier.get());
if (changed) {
LOG.info("[{}] Detected a configuration change", logPrefix);
eventBus.fire(ConfigChangeEvent.INSTANCE);
}
```
This allows other components, such as `ChannelPool`, to react to config changes dynamically:
```java
eventBus.register(
ConfigChangeEvent.class, RunOrSchedule.on(adminExecutor, this::onConfigChanged));
private void onConfigChanged(ConfigChangeEvent event) {
assert adminExecutor.inEventLoop();
// resize re-reads the pool size from the configuration and does nothing if it hasn't changed,
// which is exactly what we want.
resize(distance);
}
```
For simplicity, the implementation makes the following assumptions:
* events are propagated synchronously: if their processing needs to be delayed or rescheduled to
another thread, it's the consumer's responsibility (see how the pool uses `RunOrSchedule` in the
example above);
* callbacks are not polymorphic: you must register for the exact event class. For example, if you
have `eventBus.register(B.class, callback)` and fire an `A extends B`, the callback won't catch
it (internally, this allows direct lookups instead of traversing all registered callbacks with an
`instanceof` check).
Those choices have been good enough for the needs of the driver. That's why we use a custom
implementation rather than something more sophisticated like Guava's event bus.