dnet_rpc/lib.rs
1#![warn(missing_docs)]
2
3//! RPC over `dnet` transports.
4
5pub mod consumer;
6pub use consumer::{Consume, StreamRequest, ValueRequest};
7
8pub mod producer;
9
10pub mod parts;
11
12use std::fmt::{Debug, Display};
13use std::future::Future;
14
15use dportable::create_non_sync_send_variant_for_wasm;
16
17pub use dportable::time::{sleep, Instant, Sleep, Timeout};
18pub use dportable::{spawn, JoinHandle};
19
20pub use dnet_base;
21
22pub use atomic_counter;
23pub use futures;
24
25/// Macro for marking traits defining api's interface.
26///
27/// It will generate the following:
28/// - `Consumer` struct implementing [Consume] trait - which can be used to make requests,
29/// - `Request` enum - serializable structure representing request type with its arguments,
30/// - `Response` enum - serializable structure representing response to a request,
31/// - `impl_produce` macro which is used by [Produce] derive macro to implement
32/// [producer::Produce] trait.
33///
34/// [Consume]: self::Consume
35pub use dnet_macros::api;
36
37/// Used together with [api] macro, disables attachment of [serde] `Serialize` and/or
38/// `Deserialize` derive macros on generated `Request` and/or `Response` enums.
39///
40/// Following options are available:
41/// - `request` - disables both `Serialize` and `Deserialize` for generated `Request` enum,
42/// - `response` - disables both `Serialize` and `Deserialize` for generated `Response` enum,
43/// - `request_serialize` - disables `Serialize` for generated `Request` enum,
44/// - `request_deserialize` - disables `Deserialize` for generated `Request` enum,
45/// - `response_serialize` - disables `Serialize` for generated `Response` enum,
46/// - `response_deserialize` - disables `Deserialize` for generated `Response` enum.
47///
48/// Use without arguments - `#[no_serde]` - is equivalent to `#[no_serde(request, response)]`.
49pub use dnet_macros::no_serde;
50
51/// Marker for api functions that are "fire-and-forget" - they return as soon as request is
52/// sent to the producer without waiting for response - in fact producer won't even send it.
53///
54/// It is useful for cases of one-directional communication where you don't care about
55/// the producer finishing the task.
56pub use dnet_macros::no_ack;
57
58/// Marker for api functions that will provide producer with
59/// [AbortionToken](crate::producer::abortable::AbortionToken)
60/// which will be triggered when consumer aborts the request.
61///
62/// Abortion will be passed as the last argument of the producer method as
63/// `abortion_token: AbortionToken`.
64pub use dnet_macros::abortable;
65
66/// Derive macro implementing [Produce] trait for struct.
67///
68/// **NOTE**: it depends on `impl_produce` macro, `Request` and `Response` enums
69/// generated by the [api] macro being in scope.
70///
71/// [Produce]: self::producer::Produce
72pub use dnet_macros::Produce;
73
74create_non_sync_send_variant_for_wasm! {
75 /// Helper trait for consumer errors.
76 pub trait TransportError: Send + 'static {}
77
78 impl<T> TransportError for T where T: Send + 'static {}
79}
80
81create_non_sync_send_variant_for_wasm! {
82 /// Helper trait for transports used by `dnet-rpc`.
83 pub trait Transport<Incoming, Outgoing, Error>:
84 dnet_base::Transport<Incoming, Outgoing, Error> + Send + 'static
85 {
86 }
87
88 impl<T, Incoming, Outgoing, Error> Transport<Incoming, Outgoing, Error> for T where
89 T: dnet_base::Transport<Incoming, Outgoing, Error> + Send + 'static
90 {
91 }
92}
93
94create_non_sync_send_variant_for_wasm! {
95 /// Helper trait for shutdown futures used by producers and consumers.
96 pub trait Shutdown: Future<Output = ShutdownType> + Send + Unpin + 'static {}
97
98 impl<T> Shutdown for T where T: Future<Output = ShutdownType> + Send + Unpin + 'static {}
99}
100
101/// RPC error.
102#[derive(Debug)]
103pub enum Error {
104 /// Connection closed.
105 Closed,
106
107 /// Request was aborted by consumer/producer.
108 Aborted,
109
110 /// Consumer/producer was shut down.
111 ///
112 /// **NOTE**: It may also be caused by connection being closed before consumer
113 /// request was made.
114 Shutdown,
115
116 /// Consumer timed out.
117 Timeout,
118
119 /// Consumer was dropped before request could complete.
120 Dropped,
121}
122
123impl Display for Error {
124 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
125 match self {
126 Error::Closed => write!(f, "transport closed"),
127 Error::Aborted => write!(f, "request was aborted"),
128 Error::Shutdown => write!(f, "producer/consumer was shutdown"),
129 Error::Timeout => write!(f, "producer/consumer timed out"),
130 Error::Dropped => write!(f, "consumer was dropped"),
131 }
132 }
133}
134
135impl std::error::Error for Error {}
136
137/// Cause of producer/consumer shutdown.
138#[derive(Debug, Clone, Copy, PartialEq, Eq)]
139pub enum ShutdownType {
140 /// Connection closed.
141 Closed,
142
143 /// Manual shutdown.
144 Shutdown,
145
146 /// Abort all requests.
147 Aborted,
148
149 /// Consumer/producer timed out.
150 ///
151 /// **NOTE**: Consumer requests will not receive [Error::Timeout] error
152 /// (they will error out with other error type like [Error::Closed] or [Error::Shutdown]).
153 /// This design is deliberate to not give consumers easily determinable info about timeout
154 /// duration producer was configured with.
155 Timeout,
156}
157
158impl From<ShutdownType> for Error {
159 fn from(value: ShutdownType) -> Self {
160 match value {
161 ShutdownType::Closed => Error::Closed,
162 ShutdownType::Shutdown => Error::Shutdown,
163 ShutdownType::Aborted => Error::Aborted,
164 ShutdownType::Timeout => Error::Timeout,
165 }
166 }
167}