1
//! Implementations for methods on Connection.
2

            
3
use derive_deftly::Deftly;
4
use std::sync::Arc;
5
use tor_rpcbase::{self as rpc, templates::*};
6

            
7
use super::Connection;
8

            
9
/// Cancel a single request.
10
///
11
/// Note that calling this method does not guarantee that the request is actually cancelled:
12
/// the request might finish first.
13
///
14
/// What we do guarantee is that either this method returns successfully and the request is cancelled,
15
/// or that this method fails and the request is not cancelled.
16
/// We also guarantee that both the request and this method will finish "fairly quickly"
17
/// after this method is called.
18
///
19
/// In Arti's current implementation, a cancel request is itself is not cancellable.
20
///
21
/// For more information see `rpc-meta-draft.md`.
22
#[derive(Debug, serde::Deserialize, Deftly)]
23
#[derive_deftly(DynMethod)]
24
#[deftly(rpc(method_name = "rpc:cancel", no_cancel))]
25
struct RpcCancel {
26
    /// The ID for the request that we should try to cancel.
27
    request_id: crate::msgs::RequestId,
28
}
29

            
30
impl rpc::RpcMethod for RpcCancel {
31
    type Output = rpc::Nil;
32
    type Update = rpc::NoUpdates;
33
}
34

            
35
/// Implement `RpcCancel` on a connection.
36
async fn connection_rpc_cancel(
37
    conn: Arc<Connection>,
38
    cancel: Box<RpcCancel>,
39
    _ctx: Arc<dyn rpc::Context>,
40
) -> Result<rpc::Nil, super::CancelError> {
41
    conn.cancel_request(&cancel.request_id).map(|()| rpc::NIL)
42
}
43

            
44
rpc::static_rpc_invoke_fn! {
45
    connection_rpc_cancel;
46
}