Skip to main content

libp2p_pubsub_common/service/
service_trait.rs

1#![allow(unused_variables)]
2
3use std::task::{Context, Poll};
4
5use crate::service::context_handles::{OnEventCtx, PollCtx};
6
7pub type InEvent<T> = <T as Service>::InEvent;
8pub type OutEvent<T> = <T as Service>::OutEvent;
9
10/// A service is a stateful object that handle input events and can be polled for events.
11///
12/// The service state can only be mutated by handling input events. The service can emit events
13/// either by enqueueing them into the output mailbox or by returning a `Poll::Ready` event.
14///
15/// Typically a service implementation only needs to implement either the [`Service::on_event`]
16/// method or the [`Service::poll`] method. The [`Service::on_event`] method is useful for services
17/// that are event-driven, while the [`Service::poll`] method is useful for services that are
18/// polling-driven.
19///
20/// See [`on_event`](#method.on_event) and [`poll`](#method.poll) methods for more details.
21pub trait Service: 'static {
22    type InEvent: 'static;
23    type OutEvent: 'static;
24
25    /// Handle an input event.
26    ///
27    /// To emit an event, enqueueing it into the output mailbox, use the [`OnEventCtx::emit`]
28    /// method. To emit a batch of events, use the [`OnEventCtx::emit_batch`] method.
29    ///
30    /// ```ignore
31    /// use libp2p_pubsub_common::service::Service;
32    /// use libp2p_pubsub_common::service::OnEventCtx;
33    ///
34    /// impl Service for MyService {
35    ///     type InEvent = MyInEvent;
36    ///     type OutEvent = MyOutEvent;
37    ///
38    ///     fn on_event(&mut self, scv_cx: &mut OnEventCtx<'_, Self::OutEvent>, ev: Self::InEvent) {
39    ///         // ...
40    ///         scv_cx.emit(event);                  // Emit an event.
41    ///         scv_cx.emit_batch([event1, event2]); // Emit a batch of events.
42    ///         // ...
43    ///     }
44    /// }
45    ///```
46    fn on_event(&mut self, svc_cx: &mut OnEventCtx<'_, Self::OutEvent>, ev: Self::InEvent) {}
47
48    /// Poll the service for events.
49    ///
50    /// There are different ways to access the service context input mailbox events:
51    ///
52    ///  - Using the [`PollCtx::len`] and [`PollCtx::is_empty`] methods to check if there are any
53    ///    events in the input mailbox. This can be useful to apply backpressure to the upstream
54    ///    service.
55    ///  - Using the [`PollCtx::pop_next`] method to pop the next event from the input mailbox.
56    ///
57    /// On the other hand, to emit an event, one can use one of the following methods:
58    ///  - Using the the [`PollCtx::emit`] to enqueue an event to the output mailbox. Or using the
59    ///    [`PollCtx::emit_batch`] method to enqueue a batch of events.
60    ///  - Returning a `Poll::Ready(event)` to skip the output mailbox and return the event
61    ///    directly to the downstream service.
62    ///
63    /// ```ignore
64    /// use libp2p_pubsub_common::service::Service;
65    /// use libp2p_pubsub_common::service::PollCtx;
66    ///
67    /// impl Service for MyService {
68    ///     type InEvent = MyInEvent;
69    ///     type OutEvent = MyOutEvent;
70    ///
71    ///     fn poll(&mut self, scv_cx: &mut PollCtx<'_, Self::InEvent, Self::OutEvent>, cx: &mut Context<'_>) {
72    ///         // ...
73    ///         scv_cx.emit(event);                  // Emit an event.
74    ///         scv_cx.emit_batch([event1, event2]); // Emit a batch of events.
75    ///         // ...
76    ///         Poll::Ready(event);                  // Return an event to the downstream service.
77    ///     }
78    /// }
79    ///```
80    fn poll(
81        &mut self,
82        svc_cx: PollCtx<'_, Self::InEvent, Self::OutEvent>,
83        cx: &mut Context<'_>,
84    ) -> Poll<Self::OutEvent> {
85        let (mut inbox_cx, outbox_cx) = svc_cx.split();
86
87        let mut on_event_cx = outbox_cx.into();
88        while let Some(event) = inbox_cx.pop_next() {
89            self.on_event(&mut on_event_cx, event);
90        }
91
92        Poll::Pending
93    }
94}