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:
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:
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 anA extends B
, the callback won’t catch it (internally, this allows direct lookups instead of traversing all registered callbacks with aninstanceof
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.