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 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}