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