arti_rpcserver/objmap/
methods.rs

1//! Implementations for rpc methods that interact with
2//! object IDs directly.
3//!
4//! (These methods do not use the regular dispatch system
5//! because they interact with the object map system in special ways.)
6
7use derive_deftly::Deftly;
8use futures::FutureExt as _;
9use std::sync::Arc;
10use tor_rpcbase::{self as rpc, templates::*};
11
12/// Release a single ObjectID.
13///
14/// Only works if the ObjectID is strong reference (also known as a "handle"):
15/// see RPC specification for more information on the distinction.
16/// (We intend to relax this requirement in the future.)
17///
18/// After calling this method, the provided ObjectID will no longer be usable,
19/// but other ObjectIDs for the same object may still exist.
20///
21/// TODO RPC: Releasing a weak reference is perilous and hard-to-define
22/// based on how we have implemented our object ids.  If you tell the objmap
23/// to "release" a single name for a weak reference, you are releasing every
24/// name for that weak reference, which may have surprising results.
25/// See also #838.
26#[derive(Debug, serde::Deserialize, Deftly)]
27#[derive_deftly(DynMethod)]
28#[deftly(rpc(method_name = "rpc:release", bypass_method_dispatch))]
29struct RpcRelease {}
30
31impl rpc::RpcMethod for RpcRelease {
32    type Output = rpc::Nil;
33    type Update = rpc::NoUpdates;
34}
35
36impl rpc::DynMethod for RpcRelease {
37    fn invoke_without_dispatch(
38        &self,
39        ctx: Arc<dyn rpc::Context>,
40        obj_id: &rpc::ObjectId,
41    ) -> Result<tor_rpcbase::dispatch::RpcResultFuture, tor_rpcbase::InvokeError> {
42        let result = match ctx.release_owned(obj_id) {
43            Ok(()) => Ok(Box::new(rpc::NIL) as _),
44            Err(e) => Err(rpc::RpcError::from(e)),
45        };
46        Ok(futures::future::ready(result).boxed())
47    }
48}