Skip to main content

agave_event_system/
event_system.rs

1use {
2    crate::{
3        Event, PublisherFactory,
4        backend::{self},
5        stream_name::StreamName,
6        stream_policy::StreamPolicy,
7    },
8    std::path::Path,
9    thiserror::Error,
10};
11
12/// Owns an event-system directory and creates typed event streams within it.
13#[derive(Clone)]
14pub struct EventSystem {
15    backend: Backend,
16}
17
18#[derive(Clone)]
19enum Backend {
20    Platform(backend::EventSystem),
21    Stub(backend::stub::EventSystem),
22}
23
24impl EventSystem {
25    /// Creates an event system directory in the given path, `event_system_directory`.
26    ///
27    /// ### Note:
28    /// - If the directory path already exists, it must be empty.
29    /// - This functions creates the given directory and any missing parents.
30    /// - The given path is canonicalized.
31    /// - The directory is emptied once this [`EventSystem`], its clones, and
32    ///   all of its streams (including their [`PublisherFactory`]s and
33    ///   publishers) are dropped. The directory itself is left in place, and
34    ///   can be reused by a later call to [`EventSystem::new`].
35    pub fn new(event_system_directory: impl AsRef<Path>) -> Result<Self, CreateEventSystemError> {
36        Ok(Self {
37            backend: Backend::Platform(backend::EventSystem::new(event_system_directory)?),
38        })
39    }
40
41    /// Creates a no-op event system on any platform, including Linux.
42    ///
43    /// No filesystem access is performed. Streams ignore their configuration
44    /// and policy, and their factories always return publishers that discard
45    /// events without serializing them.
46    pub fn stub() -> Self {
47        Self {
48            backend: Backend::Stub(backend::stub::EventSystem),
49        }
50    }
51
52    /// Creates a stream named `stream_name` for event type `E`
53    /// and returns its [`PublisherFactory`].
54    pub fn create_stream<E: Event>(
55        &self,
56        stream_name: StreamName,
57        stream_config: StreamConfig,
58    ) -> Result<PublisherFactory<E>, CreateStreamError> {
59        match &self.backend {
60            Backend::Platform(backend) => backend
61                .create_stream::<E>(stream_name, stream_config)
62                .map(PublisherFactory::new),
63            Backend::Stub(backend) => backend
64                .create_stream::<E>(stream_name, stream_config)
65                .map(PublisherFactory::stub),
66        }
67    }
68
69    /// Applies the given [`StreamPolicy`] on the streams created by this
70    /// [`EventSystem`].
71    ///
72    /// The applied stream policy will also be applied to future stream creations
73    /// of this event system.
74    pub fn set_stream_policy(&self, stream_policy: StreamPolicy) {
75        match &self.backend {
76            Backend::Platform(backend) => backend.set_stream_policy(stream_policy),
77            Backend::Stub(backend) => backend.set_stream_policy(stream_policy),
78        }
79    }
80}
81
82impl std::fmt::Debug for EventSystem {
83    fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
84        match &self.backend {
85            Backend::Platform(backend) => backend.fmt(formatter),
86            Backend::Stub(backend) => backend.fmt(formatter),
87        }
88    }
89}
90
91/// Capacity and participant limits for an event stream.
92#[derive(Debug, Clone, Copy, PartialEq, Eq)]
93pub struct StreamConfig {
94    /// Number of events retained in each lane.
95    pub capacity: usize,
96    /// Maximum number of concurrent publishers that can be created for the stream.
97    pub publisher_slots: usize,
98    /// Maximum number of concurrent subscribers.
99    pub subscriber_slots: usize,
100}
101
102#[derive(Debug, Error)]
103#[error("failed to create the event-system directory")]
104pub struct CreateEventSystemError(#[from] std::io::Error);
105
106/// An error reported by the platform event-queue implementation.
107#[derive(Debug, Error)]
108#[error("{0}")]
109pub struct EventQueueError(#[source] pub(crate) backend::EventQueueError);
110
111#[derive(Debug, Error)]
112pub enum CreateStreamError {
113    #[error("failed to serialize the event-stream schema")]
114    FailedToSerializeSchema(#[source] wincode::WriteError),
115    #[error("failed to create the event-stream files")]
116    FileSystem(#[from] std::io::Error),
117    #[error("the stream name is already in use")]
118    StreamNameAlreadyInUse,
119    #[error("failed to create the event-stream queue")]
120    Queue(#[source] EventQueueError),
121    #[error("failed to produce a random number for the queue identifier")]
122    OsRngFailure(std::io::Error),
123}