@@ -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.
106123pub struct Context {
107124 config : Config ,
108125 multiplexer : Option < Multiplexer > ,
@@ -119,6 +136,14 @@ impl std::fmt::Debug for Context {
119136}
120137
121138impl 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
229297impl 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