Skip to content

Commit e118e04

Browse files
Junha Yangjunha1
Junha Yang
authored andcommitted
Write doc comments
1 parent edc9993 commit e118e04

File tree

9 files changed

+627
-21
lines changed

9 files changed

+627
-21
lines changed

remote-trait-object-macro/src/lib.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,12 @@ fn create_env_path() -> syn::Path {
3333
}
3434

3535
/// It generates all necessary helper `struct`s that makes the trait be able to be used as a service.
36+
///
37+
/// It takes three arguments optionally
38+
/// - `serde_format = _` - Specify a type that implements `trait SerdeFormat`. The default is [serde_cbor](https://github.com/pyfisch/cbor)
39+
/// - `no_proxy` - If provided, the trait will be used only as a service object.
40+
/// - `no_skeleton` - If provided, the trait will be used only as a proxy object.
41+
///
3642
/// There will be many new public `struct`s, but you don't have to know about them.
3743
#[proc_macro_attribute]
3844
pub fn service(args: TokenStream, input: TokenStream) -> TokenStream {

remote-trait-object/src/context.rs

Lines changed: 72 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ pub struct Config {
7373

7474
/// A timeout for a remote method call.
7575
///
76-
/// All remote method invocations through your remote object and delete requests (that happens when you drop a remote object)
76+
/// All remote method invocations through your proxy object and delete requests (that happens when you drop a proxy object)
7777
/// will have this timeout. If it exceeds, it will cause an error.
7878
///
7979
/// Use `None` for to wait indefinitely.
@@ -103,6 +103,23 @@ impl Config {
103103
}
104104
}
105105

106+
/// One end of a `remote-trait-object` connection.
107+
///
108+
/// If you establish a remote-trait-object connection,
109+
/// there must be two ends and each will be provided as a `Context` to each user on both sides.
110+
///
111+
/// A context holds multiple things to function as a `remote-trait-object` connection end.
112+
/// Since the connection is symmetric, it manages both _server_ and _client_ toward the other end.
113+
/// It also manages a _registry_ that contains all exported services.
114+
/// The server will look up the registry to find a target object for handling an incoming method invocation.
115+
///
116+
/// Note that `remote-trait-object` is a point-to-point connection protocol.
117+
/// Exporting & importing a service are always performed on a specific connection,
118+
/// which is toward the other side, or another instance of `Context`.
119+
///
120+
/// If you created an instance of this, that means you have a connection that has been successfully established **once**,
121+
/// but is not guaranteed to be alive.
122+
/// If the other end (or the other `Context`) is closed, most operations performed on `Context` will just cause an error.
106123
pub struct Context {
107124
config: Config,
108125
multiplexer: Option<Multiplexer>,
@@ -119,6 +136,14 @@ impl std::fmt::Debug for Context {
119136
}
120137

121138
impl Context {
139+
/// Creates a new context without any initial services.
140+
///
141+
/// If you decide to use this, you have to exchange raw [`HandleToExchange`] at least once using a secondary transportation means.
142+
/// It is really rarely needed, so please consider introducing an initializing service as an initial service, to avoid any raw exchange.
143+
///
144+
/// Please see [`with_initial_service()`] for a general explanation of creation of `Context`.
145+
///
146+
/// [`with_initial_service()`]: ./struct.Context.html#method.with_initial_service
122147
pub fn new<S: TransportSend + 'static, R: TransportRecv + 'static>(
123148
config: Config,
124149
transport_send: S,
@@ -130,6 +155,12 @@ impl Context {
130155
ctx
131156
}
132157

158+
/// Creates a new context only exporting a service, but importing nothing.
159+
///
160+
/// The other end's context must be initialized with `with_initial_service_import()`.
161+
/// Please see [`with_initial_service()`] for a general explanation of creation of `Context`.
162+
///
163+
/// [`with_initial_service()`]: ./struct.Context.html#method.with_initial_service
133164
pub fn with_initial_service_export<S: TransportSend + 'static, R: TransportRecv + 'static, A: ?Sized + Service>(
134165
config: Config,
135166
transport_send: S,
@@ -141,6 +172,12 @@ impl Context {
141172
ctx
142173
}
143174

175+
/// Creates a new context only importing a service, but exporting nothing.
176+
///
177+
/// The other end's context must be initialized with `with_initial_service_export()`.
178+
/// Please see [`with_initial_service()`] for a general explanation of creation of `Context`.
179+
///
180+
/// [`with_initial_service()`]: ./struct.Context.html#method.with_initial_service
144181
pub fn with_initial_service_import<S: TransportSend + 'static, R: TransportRecv + 'static, B: ?Sized + Service>(
145182
config: Config,
146183
transport_send: S,
@@ -152,6 +189,15 @@ impl Context {
152189
(ctx, import)
153190
}
154191

192+
/// Creates a new context exchanging two services, one for export and one for import.
193+
///
194+
/// It takes `initial_service` and registers in it, and passes a `HandleToExchange` internally. (_export_).
195+
/// Also it receives a `HandleToExchange` from the other side, and makes it into a proxy object. (_import_)
196+
///
197+
/// The other end's context must be initialized with `with_initial_service()` as well, and
198+
/// such processes will be symmetric for both.
199+
///
200+
/// [`HandleToExchange`]: ../raw_exchange/struct.HandleToExchange.html
155201
pub fn with_initial_service<
156202
S: TransportSend + 'static,
157203
R: TransportRecv + 'static,
@@ -204,16 +250,38 @@ impl Context {
204250
Arc::downgrade(&self.port.clone().expect("It becomes None only when the context is dropped.")) as Weak<dyn Port>
205251
}
206252

253+
/// Clears all service objects in its registry.
254+
///
255+
/// The most usual way of deleting a service object is dropping its proxy object on the client side, and letting it request a delete to the exporter side.
256+
/// However, in some cases (especially while you're trying to shut down the connection) it is useful to clear all exported service objects
257+
/// **by the exporter side itself**.
258+
///
259+
/// Note that it will cause an error if the client side drops a proxy object of an already deleted (by this method) service object.
260+
/// Consider calling [`disable_garbage_collection()`] on the other end if there's such an issue.
261+
///
262+
/// Note also that this might trigger _delete request_ as a side effect since the service object might own a proxy object.
263+
///
264+
/// [`disable_garbage_collection()`]: ./struct.Context.html#method.disable_garbage_collection
207265
pub fn clear_service_registry(&mut self) {
208266
self.port.as_mut().unwrap().clear_registry();
209267
}
210268

269+
/// Disables all _delete request_ from this end to the other end.
270+
///
271+
/// If you call this, all `drop()` of proxy objects imported from this context won't send a delete request anymore.
272+
/// This is useful when you're not sure if the connection is still alive, but you have to close your side's context anyway.
211273
pub fn disable_garbage_collection(&self) {
212274
self.port.as_ref().expect("It becomes None only when the context is dropped.").set_no_drop();
213275
}
214276

215-
/// TODO: write a good explanation
216-
/// FIXME: use timeout
277+
/// Closes a context with a firm synchronization with the other end.
278+
///
279+
/// If you call this method, it will block until the other end calls `firm_close()` too.
280+
/// This is useful when you want to assure that two ends never suffer from 'other end has been closed' error.
281+
/// If one of the contexts dropped too early, all remote calls (including delete request) from the other end will fail.
282+
/// To avoid such a situation, consider using this to stay alive as long as it is required.
283+
///
284+
/// FIXME: currently it doesn't use `timeout` and blocks indefinitely.
217285
pub fn firm_close(self, _timeout: Option<std::time::Duration>) -> Result<(), Self> {
218286
let barrier = Arc::clone(&self.firm_close_barrier);
219287
let t = std::thread::spawn(move || {
@@ -227,6 +295,7 @@ impl Context {
227295
}
228296

229297
impl Drop for Context {
298+
/// This will delete all service objects after calling `disable_garbage_collection()` internally.
230299
fn drop(&mut self) {
231300
// We have to clean all registered service, as some might hold another proxy object inside, which refers this context's port.
232301
// For such case, we have to make them be dropped first before we unwrap the Arc<BasicPort>

0 commit comments

Comments
 (0)