ouch_connect/
svc.rs

1use links_bindings_python::prelude::*;
2use links_nonblocking::prelude::*;
3use log::info;
4use ouch_connect_nonblocking::prelude::*;
5use pyo3::{prelude::*, types::PyDict};
6use serde::Serialize;
7use std::{num::NonZeroUsize, time::Duration};
8
9use crate::{DEFAULT_CONNECT_TIMEOUT, DEFAULT_IO_TIMEOUT, DEFAULT_MAX_CONNECTIONS, DEFAULT_MAX_HBEAT_INTERVAL, DEFAULT_USR_PWD};
10
11create_callback_for_messenger!(SvcOuchProtocolManual, SvcOuchProtocolManualCallback);
12create_svc_sender!(SvcManual, SvcOuchSender, SvcOuchProtocolManual, SvcOuchProtocolManualCallback, "ouch_connect");
13
14#[derive(Serialize)]
15struct SvcManualConfig {
16    pub max_connections: NonZeroUsize,
17    pub io_timeout: f64,
18    pub name: String,
19}
20impl Default for SvcManualConfig {
21    fn default() -> Self {
22        Self {
23            max_connections: DEFAULT_MAX_CONNECTIONS,
24            io_timeout: DEFAULT_IO_TIMEOUT,
25            name: asserted_short_name!("SvcManual", SvcManual).to_owned(),
26        }
27    }
28}
29impl From<&PyDict> for SvcManualConfig {
30    fn from(py_dict: &PyDict) -> Self {
31        let default = Self::default();
32        let max_connections = py_dict.get_item("max_connections").unwrap().map_or(default.max_connections, |any| any.extract::<NonZeroUsize>().unwrap());
33        let io_timeout = py_dict.get_item("io_timeout").unwrap().map_or(default.io_timeout, |any| any.extract::<f64>().unwrap());
34        let name = py_dict.get_item("name").unwrap().map_or(default.name, |any| any.extract::<String>().unwrap());
35        Self { max_connections, io_timeout, name }
36    }
37}
38
39#[pymethods]
40impl SvcManual {
41    #[new]
42    #[pyo3(signature = (host, callback, **kwargs))]
43    fn new(_py: Python<'_>, host: &str, callback: PyObject, kwargs: Option<&PyDict>) -> PyResult<Py<Self>> {
44        let config = kwargs.map_or(SvcManualConfig::default(), SvcManualConfig::from);
45        info!("{}: effective config: {} with kwargs: {:?}", asserted_short_name!("SvcManual", Self), serde_json::to_string(&config).unwrap(), kwargs);
46        let sender = {
47            let svc_callback = SvcOuchProtocolManualCallback::new_ref(callback.clone());
48            let protocol = SvcOuchProtocolManual::default();
49            let sender = _py.allow_threads(move || SvcOuch::bind(host, config.max_connections, svc_callback, protocol, Some(&config.name)))?.into_sender_with_spawned_recver();
50            let con_id = sender.con_id().clone();
51            Py::new(
52                _py,
53                Self {
54                    sender: Some(sender).into(),
55                    con_id,
56                    io_timeout: Some(config.io_timeout),
57                },
58            )?
59        };
60        patch_callback_if_settable_sender!(_py, sender, callback, asserted_short_name!("SvcManual", Self));
61
62        Ok(sender)
63    }
64    #[classattr]
65    fn msg_samples() -> Vec<String> {
66        ouch_connect_nonblocking::prelude::svc_ouch_default_msgs().iter().map(|m| serde_json::to_string(m).unwrap()).collect::<Vec<_>>()
67    }
68}
69
70create_callback_for_messenger!(SvcOuchProtocolAuto, SvcOuchProtocolAutoCallback);
71create_svc_sender!(SvcAuto, SvcOuchSenderRef, SvcOuchProtocolAuto, SvcOuchProtocolAutoCallback, "ouch_connect");
72
73#[derive(Serialize)]
74struct SvcAutoConfig {
75    pub username: String,
76    pub password: String,
77    pub session_id: String,
78    pub clt_max_hbeat_interval: f64,
79    pub svc_max_hbeat_interval: f64,
80    pub connect_timeout: f64,
81    pub max_connections: NonZeroUsize,
82    pub io_timeout: f64,
83    pub name: String,
84}
85impl Default for SvcAutoConfig {
86    fn default() -> Self {
87        Self {
88            username: DEFAULT_USR_PWD.to_owned(),
89            password: DEFAULT_USR_PWD.to_owned(),
90            session_id: "".to_owned(),
91            clt_max_hbeat_interval: DEFAULT_MAX_HBEAT_INTERVAL,
92            svc_max_hbeat_interval: DEFAULT_MAX_HBEAT_INTERVAL,
93            connect_timeout: DEFAULT_CONNECT_TIMEOUT,
94            max_connections: DEFAULT_MAX_CONNECTIONS,
95            io_timeout: DEFAULT_IO_TIMEOUT,
96            name: asserted_short_name!("SvcAuto", SvcAuto).to_owned(),
97        }
98    }
99}
100impl From<&PyDict> for SvcAutoConfig {
101    fn from(value: &PyDict) -> Self {
102        let default = Self::default();
103        let username = value.get_item("username").unwrap().map_or(default.username, |any| any.extract::<String>().unwrap());
104        let password = value.get_item("password").unwrap().map_or(default.password, |any| any.extract::<String>().unwrap());
105        let session_id = value.get_item("session_id").unwrap().map_or(default.session_id, |any| any.extract::<String>().unwrap());
106        let clt_max_hbeat_interval = value.get_item("clt_max_hbeat_interval").unwrap().map_or(default.clt_max_hbeat_interval, |any| any.extract::<f64>().unwrap());
107        let svc_max_hbeat_interval = value.get_item("svc_max_hbeat_interval").unwrap().map_or(default.svc_max_hbeat_interval, |any| any.extract::<f64>().unwrap());
108        let connect_timeout = value.get_item("connect_timeout").unwrap().map_or(default.connect_timeout, |any| any.extract::<f64>().unwrap());
109        let max_connections = value.get_item("max_connections").unwrap().map_or(default.max_connections, |any| any.extract::<NonZeroUsize>().unwrap());
110        let io_timeout = value.get_item("io_timeout").unwrap().map_or(default.io_timeout, |any| any.extract::<f64>().unwrap());
111        let name = value.get_item("name").unwrap().map_or(default.name, |any| any.extract::<String>().unwrap());
112        Self {
113            username,
114            password,
115            session_id,
116            clt_max_hbeat_interval,
117            svc_max_hbeat_interval,
118            connect_timeout,
119            max_connections,
120            io_timeout,
121            name,
122        }
123    }
124}
125
126#[pymethods]
127impl SvcAuto {
128    #[new]
129    #[pyo3(signature = (host, callback, **kwargs))]
130    fn new(_py: Python<'_>, host: &str, callback: PyObject, kwargs: Option<&PyDict>) -> PyResult<Py<Self>> {
131        let config = kwargs.map_or(SvcAutoConfig::default(), SvcAutoConfig::from);
132        info!("{}: effective config: {} with kwargs: {:?}", asserted_short_name!("SvcAuto", Self), serde_json::to_string(&config).unwrap(), kwargs);
133        let sender = {
134            // let max_connections = max_connections.unwrap_or(NonZeroUsize::new(1).unwrap());
135            let callback = SvcOuchProtocolAutoCallback::new_ref(callback.clone());
136            let protocol = SvcOuchProtocolAuto::new(
137                UserName::from(config.username.as_str()),
138                Password::from(config.password.as_str()),
139                SessionId::from(config.session_id.as_str()),
140                Duration::from_secs_f64(config.io_timeout),
141                Duration::from_secs_f64(config.clt_max_hbeat_interval),
142                Duration::from_secs_f64(config.svc_max_hbeat_interval),
143            );
144            let sender = _py.allow_threads(move || SvcOuch::bind(host, config.max_connections, callback, protocol, Some(&config.name)))?.into_sender_with_spawned_recver_ref();
145            let con_id = sender.con_id().clone();
146            Py::new(
147                _py,
148                Self {
149                    sender: Some(sender).into(),
150                    con_id,
151                    io_timeout: Some(config.io_timeout),
152                },
153            )?
154        };
155        patch_callback_if_settable_sender!(_py, sender, callback, asserted_short_name!("SvcAuto", Self));
156        Ok(sender)
157    }
158
159    #[classattr]
160    fn msg_samples() -> Vec<String> {
161        ouch_connect_nonblocking::prelude::svc_ouch_default_msgs().iter().map(|m| serde_json::to_string(m).unwrap()).collect::<Vec<_>>()
162    }
163}