syslog_rs/a_sync/
syslog_async_queue.rs

1/*-
2 * syslog-rs - a syslog client translated from libc to rust
3 * 
4 * Copyright 2025 Aleksandr Morozov
5 * 
6 * The syslog-rs crate can be redistributed and/or modified
7 * under the terms of either of the following licenses:
8 *
9 *   1. the Mozilla Public License Version 2.0 (the “MPL”) OR
10 *                     
11 *   2. EUROPEAN UNION PUBLIC LICENCE v. 1.2 EUPL © the European Union 2007, 2016
12 */
13
14use std::marker::PhantomData;
15
16use crate::
17{
18    sync::q_adapter::{SyslogQueueAdapter, SendChannelSyCmd}, 
19    error::SyRes, 
20    formatters::{DefaultSyslogFormatter, SyslogFormatter}, 
21    map_error_code, 
22    sy_sync_queue::SyCmd, 
23    Priority, 
24    SyslogDestination, 
25    SyslogLocal
26};
27
28use super::syslog_trait::{AsyncSyChanOneshotRcv, AsyncSyChanSend, AsyncSyslogApi};
29
30
31
32/// A structure for the `sy_sync_queue::Syslog` instace mirrowing.
33#[derive(Debug)]
34pub struct AsyncSyslogQueue<F: SyslogFormatter = DefaultSyslogFormatter, D: SyslogDestination = SyslogLocal>
35{
36    /// commands channel
37    pub(crate) tasks: SendChannelSyCmd<D>,
38
39    _p: PhantomData<F>
40}
41
42unsafe impl<F: SyslogFormatter, D: SyslogDestination> Send for AsyncSyslogQueue<F, D> {}
43unsafe impl<F: SyslogFormatter, D: SyslogDestination> Sync for AsyncSyslogQueue<F, D> {}
44
45
46impl<F: SyslogFormatter, D: SyslogDestination> AsyncSyslogQueue<F, D>
47{
48    pub(crate) async 
49    fn attachlog(queue_adapter: SyslogQueueAdapter<D>) -> SyRes<Self>
50    {
51        return Ok(
52            Self
53            {
54                tasks: queue_adapter.consume()?,
55                _p: PhantomData::<F>,
56            }
57        );
58    }
59}
60
61
62impl<F: SyslogFormatter, D: SyslogDestination> AsyncSyslogApi<D> for AsyncSyslogQueue<F, D>
63{
64    async 
65    fn connectlog(&mut self) -> SyRes<()>
66    {
67        let (sy_cmd, loopback) = 
68            SyCmd::form_connectlog();
69
70        self
71            .send_msg(sy_cmd)
72            .await
73            .map_err(|e| map_error_code!(SendError, "connectlog() error: '{}'", e))?;
74
75        return 
76            loopback
77                .recv_once_msg()
78                .await?;
79    }
80
81    async 
82    fn setlogmask(&self, logmask: i32) -> SyRes<i32>
83    {
84        let (sy_cmd, loopback) = 
85            SyCmd::form_logmask(logmask);
86
87        self
88            .send_msg(sy_cmd)
89            .await
90            .map_err(|e| map_error_code!(SendError, "closelog() error: '{}'", e))?;
91
92        return 
93            loopback
94                .recv_once_msg()
95                .await;
96    }
97
98    async 
99    fn closelog(&self) -> SyRes<()>
100    {
101        let (sy_cmd, loopback) = 
102            SyCmd::form_disconnectlog();
103
104        // send stop
105        self
106            .send_msg(sy_cmd)
107            .await
108            .map_err(|e| 
109                map_error_code!(SendError, "closelog() error: '{}'", e)
110            )?;
111
112        return 
113            loopback
114                .recv_once_msg()
115                .await?;
116    }
117
118    async 
119    fn syslog(&self, pri: Priority, fmt: String)
120    {
121        // even if the thread is in a process of termination, there is
122        // no need to sync access to the run_control field as even if
123        // syslog thread will terminate before someone push something on the
124        // queue, it will be left in the queue until the end of program's time.
125        let sy_cmd = SyCmd::form_syslog(pri, fmt);
126
127        let _ = self.tasks.send(sy_cmd);
128
129        return;
130    }
131
132    async 
133    fn vsyslog(&self, pri: Priority, fmt: &str)
134    {
135        let sy_cmd = SyCmd::form_syslog(pri, fmt.to_string());
136
137        let _ = self.tasks.send(sy_cmd);
138
139        return;
140    }
141
142    async 
143    fn change_identity(&self, ident: &str) -> SyRes<()>
144    {
145        let sy_cmd =  SyCmd::form_change_ident(ident.to_string());
146
147        return 
148            self
149                .send_msg(sy_cmd)
150                .await
151                .map_err(|e| 
152                    map_error_code!(SendError, "change_identity() error: '{}'", e)
153                );
154    }
155
156    async 
157    fn reconnect(&self) -> SyRes<()>
158    {
159        return 
160            self
161                .send_msg(SyCmd::form_reconnect())
162                .await
163                .map_err(|e| 
164                    map_error_code!(SendError, "signal_rotate_log() error: '{}'", e)
165                );
166    }
167
168    async 
169    fn update_tap_data(&self, tap_data: D) -> SyRes<()>
170    {
171        let (tap_data_cmd, loopback) = SyCmd::form_update_tap(tap_data);
172
173        self
174            .send_msg(tap_data_cmd)
175            .await
176            .map_err(|e| 
177                map_error_code!(SendError, "signal_rotate_log() error: '{}'", e)
178            )?;
179
180        return 
181            loopback
182                .recv_once_msg()
183                .await?;
184    }
185}
186
187