volo_grpc/client/callopt.rs
1//! This module provides the ability to set some options at call time.
2//! These options also only apply to the call once.
3//!
4//! Note: If you set a [`CallOpt`] to a [`Client`][super::Client] and clones it,
5//! the [`CallOpt`] will be discarded.
6//!
7//! # Example
8//!
9//! ```rust,ignore
10//! use volo_grpc::client::CallOpt;
11//!
12//! static CLIENT: LazyLock<volo_gen::volo::example::item::ItemServiceClient> = LazyLock::new(|| {
13//! let addr: SocketAddr = "127.0.0.1:8080".parse().unwrap();
14//! volo_gen::volo::example::item::ItemServiceClientBuilder::new("volo-example-item")
15//! .layer_inner(LogLayer)
16//! .address(addr)
17//! .build()
18//! })
19//!
20//! #[volo::main]
21//! async fn main() {
22//! let callopt = CallOpt::default();
23//! // Do something with callopt here
24//! ...
25//! let req = volo_gen::volo::example::item::GetItemRequest { id: 1024 };
26//! let resp = CLIENT.clone().get_item(req).await;
27//! match resp {
28//! Ok(info) => tracing::info!("{:?}", info),
29//! Err(e) => tracing::error!("{:?}", e),
30//! }
31//! }
32//! ```
33
34use metainfo::{FastStrMap, TypeMap};
35use volo::net::Address;
36
37use crate::context::Config;
38
39#[derive(Debug, Default)]
40pub struct CallOpt {
41 /// Sets the callee faststr_tags for the call.
42 pub callee_faststr_tags: FastStrMap,
43 /// Sets the callee tags for the call.
44 pub callee_tags: TypeMap,
45 /// Sets the address for the call.
46 ///
47 /// The client will skip the discovery and loadbalance Service if this is set.
48 pub address: Option<Address>,
49 pub config: Config,
50 /// Sets the caller faststr_tags for the call.
51 pub caller_faststr_tags: FastStrMap,
52 /// Sets the caller tags for the call.
53 pub caller_tags: TypeMap,
54}
55
56impl CallOpt {
57 /// Creates a new [`CallOpt`].
58 pub fn new() -> Self {
59 Default::default()
60 }
61}
62
63impl volo::client::Apply<crate::context::ClientContext> for CallOpt {
64 type Error = crate::Status;
65
66 fn apply(self, cx: &mut crate::context::ClientContext) -> Result<(), Self::Error> {
67 let caller = cx.rpc_info.caller_mut();
68 if !self.caller_faststr_tags.is_empty() {
69 caller.faststr_tags.extend(self.caller_faststr_tags);
70 }
71 if !self.caller_tags.is_empty() {
72 caller.tags.extend(self.caller_tags);
73 }
74
75 let callee = cx.rpc_info.callee_mut();
76 if !self.callee_faststr_tags.is_empty() {
77 callee.faststr_tags.extend(self.callee_faststr_tags);
78 }
79 if !self.callee_tags.is_empty() {
80 callee.tags.extend(self.callee_tags);
81 }
82 if let Some(addr) = self.address {
83 callee.set_address(addr);
84 }
85 cx.rpc_info.config_mut().merge(self.config);
86 Ok(())
87 }
88}