lighthouse/beacon_node/beacon_chain/src/events.rs
realbigsean fdfb81a74a Server sent events (#1920)
## Issue Addressed

Resolves #1434 (this is the last major feature in the standard spec. There are only a couple of places we may be off-spec due to recent spec changes or ongoing discussion)
Partly addresses #1669
 
## Proposed Changes

- remove the websocket server
- remove the `TeeEventHandler` and `NullEventHandler` 
- add server sent events according to the eth2 API spec

## Additional Info

This is according to the currently unmerged PR here: https://github.com/ethereum/eth2.0-APIs/pull/117


Co-authored-by: realbigsean <seananderson33@gmail.com>
2020-12-04 00:18:58 +00:00

114 lines
4.0 KiB
Rust

pub use eth2::types::{EventKind, SseBlock, SseFinalizedCheckpoint, SseHead};
use slog::{trace, Logger};
use tokio::sync::broadcast;
use tokio::sync::broadcast::{error::SendError, Receiver, Sender};
use types::EthSpec;
const DEFAULT_CHANNEL_CAPACITY: usize = 16;
pub struct ServerSentEventHandler<T: EthSpec> {
attestation_tx: Sender<EventKind<T>>,
block_tx: Sender<EventKind<T>>,
finalized_tx: Sender<EventKind<T>>,
head_tx: Sender<EventKind<T>>,
exit_tx: Sender<EventKind<T>>,
log: Logger,
}
impl<T: EthSpec> ServerSentEventHandler<T> {
pub fn new(log: Logger) -> Self {
let (attestation_tx, _) = broadcast::channel(DEFAULT_CHANNEL_CAPACITY);
let (block_tx, _) = broadcast::channel(DEFAULT_CHANNEL_CAPACITY);
let (finalized_tx, _) = broadcast::channel(DEFAULT_CHANNEL_CAPACITY);
let (head_tx, _) = broadcast::channel(DEFAULT_CHANNEL_CAPACITY);
let (exit_tx, _) = broadcast::channel(DEFAULT_CHANNEL_CAPACITY);
Self {
attestation_tx,
block_tx,
finalized_tx,
head_tx,
exit_tx,
log,
}
}
pub fn new_with_capacity(log: Logger, capacity: usize) -> Self {
let (attestation_tx, _) = broadcast::channel(capacity);
let (block_tx, _) = broadcast::channel(capacity);
let (finalized_tx, _) = broadcast::channel(capacity);
let (head_tx, _) = broadcast::channel(capacity);
let (exit_tx, _) = broadcast::channel(capacity);
Self {
attestation_tx,
block_tx,
finalized_tx,
head_tx,
exit_tx,
log,
}
}
pub fn register(&self, kind: EventKind<T>) {
let result = match kind {
EventKind::Attestation(attestation) => self
.attestation_tx
.send(EventKind::Attestation(attestation))
.map(|count| trace!(self.log, "Registering server-sent attestation event"; "receiver_count" => count)),
EventKind::Block(block) => self.block_tx.send(EventKind::Block(block))
.map(|count| trace!(self.log, "Registering server-sent block event"; "receiver_count" => count)),
EventKind::FinalizedCheckpoint(checkpoint) => self.finalized_tx
.send(EventKind::FinalizedCheckpoint(checkpoint))
.map(|count| trace!(self.log, "Registering server-sent finalized checkpoint event"; "receiver_count" => count)),
EventKind::Head(head) => self.head_tx.send(EventKind::Head(head))
.map(|count| trace!(self.log, "Registering server-sent head event"; "receiver_count" => count)),
EventKind::VoluntaryExit(exit) => self.exit_tx.send(EventKind::VoluntaryExit(exit))
.map(|count| trace!(self.log, "Registering server-sent voluntary exit event"; "receiver_count" => count)),
};
if let Err(SendError(event)) = result {
trace!(self.log, "No receivers registered to listen for event"; "event" => ?event);
}
}
pub fn subscribe_attestation(&self) -> Receiver<EventKind<T>> {
self.attestation_tx.subscribe()
}
pub fn subscribe_block(&self) -> Receiver<EventKind<T>> {
self.block_tx.subscribe()
}
pub fn subscribe_finalized(&self) -> Receiver<EventKind<T>> {
self.finalized_tx.subscribe()
}
pub fn subscribe_head(&self) -> Receiver<EventKind<T>> {
self.head_tx.subscribe()
}
pub fn subscribe_exit(&self) -> Receiver<EventKind<T>> {
self.exit_tx.subscribe()
}
pub fn has_attestation_subscribers(&self) -> bool {
self.attestation_tx.receiver_count() > 0
}
pub fn has_block_subscribers(&self) -> bool {
self.block_tx.receiver_count() > 0
}
pub fn has_finalized_subscribers(&self) -> bool {
self.finalized_tx.receiver_count() > 0
}
pub fn has_head_subscribers(&self) -> bool {
self.head_tx.receiver_count() > 0
}
pub fn has_exit_subscribers(&self) -> bool {
self.exit_tx.receiver_count() > 0
}
}