Skip to main content

tango/server/
server.rs

1//! The server itself: what owns the classes, the devices and the backend serving them.
2//!
3//! Ownership is a tree rooted at the [`ServerHandle`], which alone owns the `Core` of its
4//! server: its classes, its devices and its backend. The [`Server`] the classes and the
5//! devices hold is only the context they share, which reaches its core weakly, so that a
6//! handler reaches its class and its server as plain field access, without any cycle.
7
8use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering};
9use std::collections::hash_map::Entry;
10use std::sync::{Arc, Mutex, Weak};
11use std::task::{Context, Poll};
12use std::collections::HashMap;
13use std::ops::{Deref, RangeBounds};
14use std::pin::{pin, Pin};
15use std::time::Duration;
16use std::borrow::Cow;
17use std::mem;
18
19use futures::stream::{BoxStream, Stream, StreamExt};
20use futures::future::{self, Either};
21use futures::executor::block_on;
22use tracing::{debug, info, warn};
23
24use crate::backend::{default_backend, Backend, BackendServer, BackendServerConfig};
25use crate::database::{DatabaseProxy, ExportDevInfo};
26use crate::dev::{AttrInfo, AttrRead, AttrReady, AttrValueEvent};
27use crate::error::{Error, ErrorKind, Result, reason};
28use crate::name::{self, ArcName, Name};
29use crate::future::block_on_timeout;
30use crate::testing::TestContext;
31use crate::value::Value;
32use crate::future::Slot;
33
34use super::class::{AnyClass, Class};
35use super::admin::{self, Admin};
36use super::def::ClassDef;
37use super::Model;
38use super::dev::{AnyDev, Dev};
39use super::polling::Poller;
40use super::terminate;
41
42#[cfg(feature = "cli")]
43use super::cli::{self, ServerArgs};
44
45
46/// What the name of the admin device of a server is its `exe/inst` name prefixed with.
47const ADMIN_DEV_PREFIX: &str = "dserver/";
48
49/// How long a server is given to boot by default, see [`ServerBuilder::boot_timeout`].
50const DEFAULT_BOOT_TIMEOUT: Duration = Duration::from_secs(30);
51
52/// The context shared by the classes and the devices of a server, which every class of it
53/// owns, and which reaches what owns them, its `Core`, weakly.
54///
55/// # Ownership
56///
57/// ```text
58///                  ┌───────────────────────────┐                                     ┌─────────────────┐
59///                  │        ServerHandle       │                                     │ DevProxy        │
60///                  └─────────────┬─────────────┘                                     └─────┬───────────┘
61///                                │                                                         │
62///                                │core                                                     │backend: BackendDev
63///                                │1                                                        │0..1
64///          ┌─────────────────────┴─────────────────────┐      1┌───────────────────┐       │
65///          │ Core                                      ├───────┤ dyn BackendServer │       │
66///          └─┬──────┬──┬───┬──────┬────┬─────┬─────────┘backend└─────────┬──────┬──┘       │
67///            │ name │  │   │ name │    │     ╎1                          │ name │          │
68///            ╰──┬───╯  │   ╰──┬───╯    │     ╎core                       ╰──┬───╯          │
69///               │      │      │  server│     ╎                              │              │
70///               │      │      │       1│     ╎                              │              │
71///               │      │      │    ┌───┴─────┴───────┐                      │              │
72///               │      │      │    │ Server          │                      │              │
73///               │      │      │    └───────────────┬─┘                      │              │
74///               │      │      │classes: AnyClass   │1                       │              │
75///               │      │      │0..1                │server                  │              │
76///               │      │ ┌────┴────────────────────┴───────┐                │              │
77///               │      │ │ Class<M>                        │                │              │
78///               │      │ └─────────────────────────┬───────┘                │              │
79///               │      │                           │1                       │              │
80///               │      │                           │class                   │              │
81///   devs: AnyDev│      │pending: AnyDev            │        devs: BackendDev│              │
82///           0..1│      │*                          │                    0..1│              │
83///         ┌─────┴──────┴───────────────────────────┴────────────────────────┴──────────────┴─────────┐
84///         │ Dev<M>                                                                                   │
85///         └─┬──────┬─┬──────┬──┬────────────┬─────────────┬─────────────────────┬───────────┬────────┘
86///           │ name │ │ name │  │            │             │                 0..1╎           ╎0..1
87///           ╰──┬───╯ ╰─┬────╯  │            │             │      dev: BackendDev╎           ╎dev: BackendDev
88///              │       │       │            │             │                     ╎           ╎
89///      commands│       │attrs  │state_attr  │status_attr  │                     ╎           ╎
90///          0..1│       │0..1   │1           │1            │                     ╎           ╎
91///  ┌───────────┴┐  ┌───┴───────┴────────────┴────────┐    │                     ╎           ╎
92///  │ Command<M> │  │ Attr<M>                         │    │                     ╎           ╎
93///  └────────────┘  └─────────────────────────────────┘    │local_handle     ╭───┴───╮ ╭─────┴──────╮
94///                                                         │0..1             │  itr  │ │ port, name │
95///                                                 ┌───────┴────────┐     1┌─┴───────┴─┴────────────┴─┐
96///                                                 │ LocalDevHandle ├╌╌╌╌╌╌┤      local registry      │
97///                                                 └────────────────┘  keys└──────────────────────────┘
98/// ```
99///
100/// A solid line is an [`Arc`], a dashed one a [`Weak`]. An end of a line has a
101/// multiplicity, and the name of the field holding it, only when the class at the other end
102/// reaches it: an end without one is not reached through that line. A field holding the
103/// other end as a trait object is written `field: Trait`. A rounded box is the key of a map
104/// of the class it hangs from, which holds at most one of the other end per key.
105/// `LocalDevHandle` holds the keys of the entries of its device, which it takes out of the
106/// registry when dropped, and a weak reference to the device, not drawn, which only tells
107/// its entries from those of a device registered since.
108///
109/// The backend is given each device as a `dyn BackendDev`, which is the `DevImpl<M>`
110/// wrapper of a [`Dev<M>`]. A [`DevProxy`](crate::dev::DevProxy) holds the backend it
111/// reaches its device through as a `dyn BackendDev` too, which is the device itself when it
112/// is served by this process and found in the registry, and a client of the protocol of the
113/// backend otherwise.
114///
115/// The commands and attributes of a device, kept in its `mutable` field, each hold their
116/// definition, not drawn, which is shared with the [`ClassDef`] of its class.
117///
118/// Every solid line points down from the handle: the only links going back up are the weak
119/// `core` field and those of the local registry. Dropping the handle stops the backend, and
120/// frees everything once nothing else holds the core, which a request running a
121/// [`Self::sync_async`] or a [`Self::stop_async`] does until it ends, see [`ServerHandle`].
122///
123/// The local registry only ever holds devices weakly, so it never keeps one alive, while a
124/// client of this process holds the device it found for as long as it is connected to it,
125/// which refuses its requests once withdrawn, see [`Dev::is_withdrawn`]. A device is taken
126/// out of the registry, by dropping its `LocalDevHandle`, before it is removed from the
127/// backend, so that local clients stop finding it first.
128#[derive(Debug)]
129pub struct Server {
130    /// What owns the classes, the devices and the backend of that server, which is only
131    /// there for as long as it is served, see [`Self::core`].
132    core: Weak<Core>,
133    /// The `dserver/exe/inst` name of the admin device of that server, which is where its
134    /// own `exe/inst` name is taken from, see [`Self::name`].
135    pub(super) admin_dev_name: Arc<str>,
136    /// The database proxy used for that server.
137    database: DatabaseProxy,
138    /// The subscriptions to the events of the attributes of the devices of that server, by
139    /// device and attribute name.
140    ///
141    /// They are the server's and not the devices': a device restarted, or a whole server
142    /// restarted, is made anew under the same name, and so are its attributes on every
143    /// Init, while its subscribers are kept, the way cppTango keeps them. A client of a
144    /// server that is still running sees nothing of a restart, so nothing would make it
145    /// subscribe again.
146    ///
147    /// The streams handed out end, after an [`ErrorKind::DevNotConnected`], once the device
148    /// is gone for good, see [`Self::sync_async`], or the server stops, see
149    /// [`Self::stop_async`]: the end of a subscription of a backend, see
150    /// [`crate::backend::BackendDev`].
151    events: Mutex<HashMap<ArcName, HashMap<ArcName, AttrEvents>>>,
152    /// Whether the devices of that server are reached directly by the clients of this
153    /// process, see [`ServerBuilder::local`].
154    pub(super) local: bool,
155}
156
157/// The owner of the classes, the devices and the backend of a server, which only its
158/// [`ServerHandle`] holds and which is never handed out: the [`Server`] reaches it weakly,
159/// see [`Server::core`], which is what keeps the ownership of a server a tree.
160///
161/// The methods of the server reaching what it owns hold it for the time of their call,
162/// across the whole of it for [`Server::sync_async`], [`Server::stop_async`] and
163/// [`Server::wait_async`], so that a call started is finished before the devices go.
164#[derive(Debug)]
165pub(super) struct Core {
166    /// The server, which the handle derefs to.
167    server: Arc<Server>,
168    /// The backend serving the devices of that server.
169    backend: Arc<dyn BackendServer>,
170    /// The classes of that server.
171    classes: Mutex<HashMap<ArcName, Arc<dyn AnyClass>>>,
172    /// The number of classes made for that server so far, which is the index of the next
173    /// one, see [`AnyClass::index`].
174    class_count: AtomicUsize,
175    /// Every device of that server, device names being unique server-wide. This is the
176    /// lock every addition of a device is made under, see [`Class::add_dev`].
177    pub(super) devs: Mutex<HashMap<ArcName, Arc<dyn AnyDev>>>,
178    /// What the next [`Server::sync_async`] applies, which is never locked with any other lock.
179    pub(super) pending: Mutex<Pending>,
180    /// Held for the whole of a [`Server::sync_async`], so that two of them never interleave, and
181    /// for the whole of a [`Server::stop_async`], which [`Server::wait`] waits for through it.
182    sync_lock: async_lock::Mutex<()>,
183    /// Whether that server was stopped, which is only ever done once.
184    stopped: AtomicBool,
185    /// The polling of the devices of that server, see [`Poller`], which ends with it.
186    poller: Poller,
187}
188
189impl Drop for Core {
190
191    /// Stop the backend, which the handle did already unless this outlived it: a backend
192    /// stops for good once nothing holds its server anymore, whatever it was serving.
193    ///
194    /// Every device left is marked withdrawn and taken out of the local registry, which a
195    /// stopped server has none of, see [`Server::stop_async`]: a server that ended without
196    /// being stopped never withdraws them, while its devices may still be held, by a thread
197    /// of their own or a client of this process in particular.
198    fn drop(&mut self) {
199        self.backend.stop();
200        self.poller.shutdown();
201        let removed = &self.pending.get_mut().unwrap().removed;
202        for dev in self.devs.get_mut().unwrap().values().chain(removed) {
203            dev.withdraw_now();
204        }
205    }
206
207}
208
209/// The subscribers of the events of an attribute, see [`Server::events`].
210#[derive(Debug, Default)]
211struct AttrEvents {
212    values: HashMap<AttrValueEvent, Subscribers<AttrRead<Value>>>,
213    ready: Subscribers<AttrReady>,
214    conf: Subscribers<AttrInfo>,
215}
216
217/// The subscribers of an event, which only hold their slot weakly: a subscriber dropping
218/// its stream is what unsubscribes it, its slot being pruned the next time the event is
219/// pushed or subscribed to.
220type Subscribers<T> = Vec<Weak<Slot<Result<T>>>>;
221
222/// The operations on the devices of a server that wait for its next [`Server::sync_async`].
223#[derive(Debug, Default)]
224pub struct Pending {
225    /// The devices added and not initialized yet, in the order they were added.
226    pub added: Vec<Arc<dyn AnyDev>>,
227    /// The devices initialized and not exported yet, either because they were just
228    /// initialized or because serving or exporting them failed, along with the reference
229    /// the backend serves them at once it does.
230    pub unexported: Vec<(Arc<dyn AnyDev>, Option<Arc<str>>)>,
231    /// The devices removed and still served, possibly still exported.
232    pub removed: Vec<Arc<dyn AnyDev>>,
233}
234
235impl Server {
236
237    /// The `exe/inst` name of that server, under which it is registered in the database.
238    #[inline]
239    pub fn name(&self) -> &str {
240        &self.admin_dev_name[ADMIN_DEV_PREFIX.len()..]
241    }
242
243    /// The name of the admin device of that server, `dserver/exe/inst`.
244    #[inline]
245    pub fn admin_dev_name(&self) -> &str {
246        &self.admin_dev_name
247    }
248
249    /// The database that server is registered in.
250    #[inline]
251    pub fn database(&self) -> &DatabaseProxy {
252        &self.database
253    }
254
255    /// What owns the classes, the devices and the backend of that server, failing once it
256    /// is gone, which is once its handle is dropped and nothing else holds it, see
257    /// [`ServerHandle`].
258    pub(super) fn core_checked(&self) -> Result<Arc<Core>> {
259        self.core.upgrade().ok_or_else(|| Error::new(ErrorKind::Reason(reason::API_ServerNotRunning))
260            .with_description(format!("Server {:?} is not served anymore", self.name())))
261    }
262
263    /// The polling of the devices of that server, absent once it is not served anymore,
264    /// see [`Self::core`].
265    pub(super) fn poller(&self) -> Option<Poller> {
266        self.core.upgrade().map(|core| core.poller.clone())
267    }
268
269    /// The backend serving the devices of that server, failing once it is not served
270    /// anymore, see [`Self::core`].
271    pub(super) fn backend_checked(&self) -> Result<Arc<dyn BackendServer>> {
272        Ok(Arc::clone(&self.core_checked()?.backend))
273    }
274
275    /// The backend serving the devices of that server, [`None`] once it is not served
276    /// anymore, see [`ServerHandle`].
277    #[inline]
278    pub fn backend(&self) -> Option<Arc<dyn BackendServer>> {
279        self.core.upgrade().map(|core| Arc::clone(&core.backend))
280    }
281
282    /// Register a new class in this server, from its definition.
283    pub fn add_class<M: Model>(&self, def: ClassDef<M>) -> Result<Arc<Class<M>>> {
284
285        if !name::check_tango_class_name(&def.name) {
286            return Err(Error::new(ErrorKind::ClassNameInvalid)
287                .with_description(format!("Class {:?} has an invalid name, it should be made of \
288                    letters, digits, '_' and '-'", def.name)));
289        }
290
291        let core = self.core_checked()?;
292        let def = Arc::new(def);
293        let mut classes = core.classes.lock().unwrap();
294        let name = ArcName::from(&*def.name);
295
296        let Entry::Vacant(entry) = classes.entry(name) else {
297            return Err(Error::new(ErrorKind::ClassAlreadyDefined)
298                .with_description(format!("Class {:?} is already defined on the server", def.name)));
299        };
300
301        let index = core.class_count.fetch_add(1, Ordering::Relaxed);
302        let class = Class::new(Arc::clone(&core.server), def, index);
303        entry.insert(Arc::clone(&class) as Arc<dyn AnyClass>);
304        Ok(class)
305
306    }
307
308    /// Get a class of this server from its name, if it is one of that model.
309    pub fn get_class<M: Model>(&self, name: &str) -> Option<Arc<Class<M>>> {
310        self.any_class(name)?.into_any().downcast().ok()
311    }
312
313    /// Get a class of this server from its name, whatever its model.
314    pub(super) fn any_class(&self, name: &str) -> Option<Arc<dyn AnyClass>> {
315        let core = self.core.upgrade()?;
316        core.classes.lock().unwrap().get(Name::new(name)).map(Arc::clone)
317    }
318
319    /// Add a device to this server, as an instance of the class of that name, which is how
320    /// the devices listed by the database are added, the database giving the class of each
321    /// by its name. See [`Class::add_dev`] for the typed form.
322    /// 
323    /// The device is only registered: it is initialized, served and exported by the next
324    /// [`Self::sync_async`].
325    pub fn add_dev(&self, class: &str, name: &str) -> Result<()> {
326
327        let class = self.core_checked()?.classes.lock().unwrap()
328            .get(Name::new(class))
329            .map(Arc::clone)
330            .ok_or_else(|| Error::new(ErrorKind::ClassNotFound)
331                .with_description(format!("Class {class:?} is not defined on the server")))?;
332
333        class.add_dev(name).map(drop)
334
335    }
336
337    /// Remove the device of that name from this server, giving back whether it had one.
338    /// 
339    /// Its name is free again right away, but the device itself is only unexported, no
340    /// longer served and deleted by the next [`Self::sync_async`]. A device removed before any
341    /// synchronization reached it is simply dropped.
342    pub fn remove_dev(&self, name: &str) -> bool {
343
344        let Some(core) = self.core.upgrade() else {
345            return false;
346        };
347
348        let Some(dev) = core.devs.lock().unwrap().remove(Name::new(name)) else {
349            return false;
350        };
351
352        // If the device was still pending to be added, then we just remove it, otherwise
353        // we also remove its unexported state and then add it to the devices to be
354        // removed.
355        let mut pending = core.pending.lock().unwrap();
356        if let Some(index) = pending.added.iter().position(|added| Arc::ptr_eq(added, &dev)) {
357            pending.added.remove(index);
358        } else {
359            pending.unexported.retain(|(unexported, _)| !Arc::ptr_eq(unexported, &dev));
360            pending.removed.push(dev);
361        }
362
363        true
364
365    }
366
367    /// Apply what was done to the devices of this server since the last synchronization:
368    /// the devices removed are unexported, no longer served and deleted, then the devices
369    /// added are initialized, served and exported, which is what makes them reachable.
370    /// 
371    /// The devices added are initialized one after the other, class by class in the order
372    /// the classes were made, and in the order they were added within a class. A device
373    /// whose initialization adds devices has them initialized by this same
374    /// synchronization, which is how the admin device boots a server. Each device is then
375    /// served and exported on its own, which is what a Tango server always tells the
376    /// database.
377    /// 
378    /// A device whose initialization failed is still served and exported, in FAULT, so
379    /// that a client can ask it what went wrong. A device that could not be served or
380    /// exported is retried by the next synchronization, and the first such error is given
381    /// back once every other device is done.
382    /// 
383    /// Synchronizations never interleave: one waits for the one running to be done, so
384    /// that everything done before calling it is applied once it returns. This is also why
385    /// an init function must never call it, since it would wait for itself.
386    pub async fn sync_async(&self) -> Result<()> {
387
388        let Some(core) = self.core.upgrade() else {
389            return Ok(());
390        };
391
392        let _sync = core.sync_lock.lock().await;
393        if core.stopped.load(Ordering::Acquire) {
394            return Ok(());
395        }
396
397        let mut first_err = None;
398
399        // Begin with pending removal of devices, they are first unexported and then
400        // withdrawn from the backend.
401        let removed = mem::take(&mut core.pending.lock().unwrap().removed);
402        for dev in removed {
403
404            if let Err(err) = self.database.unexport_dev_async(dev.name()).await {
405                warn!(dev = %dev.name(), %err, "Failed to unexport the removed device");
406                first_err.get_or_insert(err);
407            }
408
409            if let Err(err) = dev.withdraw().await {
410                warn!(dev = %dev.name(), %err, "Failed to delete the removed device");
411                first_err.get_or_insert(err);
412            }
413
414            // A device added again under the same name, which is what a restart is, keeps
415            // the subscriptions of the one it replaces.
416            if !core.devs.lock().unwrap().contains_key(Name::new(dev.name())) {
417                self.end_dev_events(dev.name());
418            }
419
420            debug!(dev = %dev.name(), "Removed the device");
421
422        }
423
424        // Then we loop through added devices, we init their model and then we add them to
425        // the unexported list, which tells that they should be exported next!
426        loop {
427
428            let mut added = mem::take(&mut core.pending.lock().unwrap().added);
429            if added.is_empty() {
430                break;
431            }
432
433            added.sort_by_key(|dev| dev.class().index());
434            for dev in added {
435                // Only a panic of its init function ends here, a failed initialization
436                // being kept by the device itself: it is exported all the same.
437                if let Err(err) = dev.init().await {
438                    warn!(dev = %dev.name(), %err, "Failed to complete the initialization of the device, its init function panicked");
439                }
440                core.pending.lock().unwrap().unexported.push((dev, None));
441            }
442
443        }
444
445        // Finally we process all the unexported devices by exporting them to the database.
446        let unexported = mem::take(&mut core.pending.lock().unwrap().unexported);
447        let mut failed = Vec::new();
448        for (dev, itr) in unexported {
449
450            let served = match itr {
451                Some(itr) => Ok(itr),
452                None => dev.serve(),
453            };
454
455            let itr = match served {
456                Ok(itr) => itr,
457                Err(err) => {
458                    warn!(dev = %dev.name(), %err, "Failed to serve the device");
459                    first_err.get_or_insert(err);
460                    failed.push((dev, None));
461                    continue;
462                }
463            };
464
465            if let Err(err) = self.export_dev(&*core.backend, &*dev, &itr).await {
466                warn!(dev = %dev.name(), %err, "Failed to export the device");
467                first_err.get_or_insert(err);
468                failed.push((dev, Some(itr)));
469                continue;
470            }
471
472            debug!(dev = %dev.name(), "Exported the device");
473
474        }
475
476        core.pending.lock().unwrap().unexported.extend(failed);
477        first_err.map_or(Ok(()), Err)
478
479    }
480
481    /// The blocking form of [`Self::sync_async`], which must therefore never run on the
482    /// executor of a backend, in an asynchronous handler in particular.
483    pub fn sync(&self) -> Result<()> {
484        block_on(self.sync_async())
485    }
486
487    /// Export a device served at that reference in the database, which is what a client
488    /// looks it up in.
489    async fn export_dev(&self, backend: &dyn BackendServer, dev: &dyn AnyDev, itr: &str) -> Result<()> {
490        self.database.export_dev_async(ExportDevInfo {
491            name: Cow::Borrowed(dev.name()),
492            itr: Cow::Borrowed(itr),
493            host: Cow::Borrowed(&backend.host()),
494            version: Cow::Owned(backend.version().to_string()),
495            pid: std::process::id() as i32,
496        }).await
497    }
498
499    /// The names of every class of this server, in the order they were made, the admin
500    /// one first.
501    pub fn class_names(&self) -> Vec<Arc<str>> {
502        self.any_classes().iter().map(|class| Arc::clone(class.name())).collect()
503    }
504
505    /// Every class of this server, whatever its model, see [`Self::class_names`].
506    pub(super) fn any_classes(&self) -> Vec<Arc<dyn AnyClass>> {
507        let Some(core) = self.core.upgrade() else {
508            return Vec::new();
509        };
510        let mut classes = core.classes.lock().unwrap().values().map(Arc::clone).collect::<Vec<_>>();
511        classes.sort_by_key(|class| class.index());
512        classes
513    }
514
515    /// The names of every device of this server, class by class in the order of
516    /// [`Self::class_names`], and by name within a class.
517    pub fn dev_names(&self) -> Vec<Arc<str>> {
518        self.any_devs().iter().map(|dev| Arc::clone(dev.name())).collect()
519    }
520
521    /// Every device of this server, whatever its model, see [`Self::dev_names`].
522    pub(super) fn any_devs(&self) -> Vec<Arc<dyn AnyDev>> {
523        let Some(core) = self.core.upgrade() else {
524            return Vec::new();
525        };
526        let mut devs = core.devs.lock().unwrap().values().map(Arc::clone).collect::<Vec<_>>();
527        devs.sort_by(|a, b| a.class().index().cmp(&b.class().index()).then_with(|| a.name().cmp(b.name())));
528        devs
529    }
530
531    /// Whether this server has a device of that name.
532    pub fn has_dev(&self, name: &str) -> bool {
533        self.core.upgrade().is_some_and(|core| core.devs.lock().unwrap().contains_key(Name::new(name)))
534    }
535
536    /// Get a device of this server from its name, if its class is one of that model.
537    pub fn get_dev<M: Model>(&self, name: &str) -> Option<Arc<Dev<M>>> {
538        self.any_dev(name)?.into_any().downcast().ok()
539    }
540
541    /// Get a device of this server from its name, whatever its model.
542    pub(super) fn any_dev(&self, name: &str) -> Option<Arc<dyn AnyDev>> {
543        let core = self.core.upgrade()?;
544        core.devs.lock().unwrap().get(Name::new(name)).map(Arc::clone)
545    }
546
547    /// Stop this server, which is only ever done once: it is unexported as a whole, so
548    /// that clients stop finding it, then its backend is stopped, the requests in flight
549    /// still being answered, and its devices are deleted, see [`Self::wait`] for what waits
550    /// for the backend to be through. No synchronization runs after this, the devices
551    /// still waiting for one never being served.
552    ///
553    /// The devices are deleted one after the other, the classes in the reverse of their
554    /// order, the admin device last, each once the requests still running on it are
555    /// through, see [`Dev::is_withdrawn`]: a request that never ends therefore keeps this
556    /// from ever returning. This is also why a request handler must never call it, since
557    /// it would wait for itself; the `Kill` command of the admin device stops its server
558    /// from the pool instead.
559    ///
560    /// The backend is stopped and the devices deleted even if the server could not be
561    /// unexported, and the first error met is given back.
562    pub async fn stop_async(&self) -> Result<()> {
563
564        let Some(core) = self.core.upgrade() else {
565            return Ok(());
566        };
567
568        let _sync = core.sync_lock.lock().await;
569        if core.stopped.swap(true, Ordering::AcqRel) {
570            return Ok(());
571        }
572
573        info!(server = %self.name(), "Stopping the server");
574
575        let unexported = self.database.unexport_server_async(self.name()).await;
576        if let Err(err) = &unexported {
577            warn!(server = %self.name(), %err, "Failed to unexport the server");
578        }
579
580        core.backend.stop();
581        core.poller.shutdown();
582        self.end_events();
583
584        // The devices removed and not synchronized yet first, as the next synchronization
585        // would have, then the others, the classes in the reverse of their order, the admin
586        // device last.
587        let removed = mem::take(&mut *core.pending.lock().unwrap()).removed;
588        let mut devs = mem::take(&mut *core.devs.lock().unwrap())
589            .into_values()
590            .collect::<Vec<_>>();
591
592        devs.sort_by_key(|dev| std::cmp::Reverse(dev.class().index()));
593
594        let mut first_err = unexported.err();
595        for dev in removed.into_iter().chain(devs) {
596            if let Err(err) = dev.withdraw().await {
597                warn!(dev = %dev.name(), %err, "Failed to delete the device");
598                first_err.get_or_insert(err);
599            }
600        }
601
602        info!(server = %self.name(), "Stopped the server");
603        first_err.map_or(Ok(()), Err)
604
605    }
606
607    /// The blocking form of [`Self::stop_async`], which must therefore never run on the
608    /// executor of a backend, in an asynchronous handler in particular.
609    pub fn stop(&self) -> Result<()> {
610        block_on(self.stop_async())
611    }
612
613    /// Wait for this server to be stopped, see [`Self::stop_async`], which is what the
614    /// thread running a server spends its life in: for its backend to be through with
615    /// every request, and for its devices to be deleted. A server that is not served
616    /// anymore, see [`ServerHandle`], is not waited for.
617    ///
618    /// The backend is waited for first, which is only through once stopped, see
619    /// [`BackendServer::wait`], then the stop itself, which deletes the devices under the
620    /// lock of the synchronizations. This waits for every request in flight, and must
621    /// therefore never be called from a request handler, which would wait for itself.
622    pub async fn wait_async(&self) {
623        let Some(core) = self.core.upgrade() else {
624            return;
625        };
626        core.backend.wait().await;
627        drop(core.sync_lock.lock().await);
628    }
629
630    /// The blocking form of [`Self::wait_async`], which must therefore never run on the
631    /// executor of a backend, in an asynchronous handler in particular. See
632    /// [`Self::wait_timeout`] for a wait that gives up.
633    pub fn wait(&self) {
634        block_on(self.wait_async())
635    }
636
637    /// Wait for this server to be stopped, see [`Self::wait_async`], giving up with
638    /// [`ErrorKind::TimedOut`] if the backend is still answering requests once the timeout
639    /// has run out, which a request that never ends makes it, or a server never stopped.
640    ///
641    /// The timeout only bounds the backend: once it is through, the deletion of the
642    /// devices is waited for, however long that takes.
643    pub fn wait_timeout(&self, timeout: Duration) -> Result<()> {
644        let Some(core) = self.core.upgrade() else {
645            return Ok(());
646        };
647        block_on_timeout(core.backend.wait(), timeout)
648            .map_err(|err| err.with_description(format!("Server {:?} is still answering requests after {timeout:?}", self.name())))?;
649        block_on(core.sync_lock.lock());
650        Ok(())
651    }
652
653    /// Subscribe to the readings of an attribute of a device, pushed for that event. Nothing
654    /// checks here that the device has the attribute, which is the device's to check.
655    pub(super) fn subscribe_attr_value(&self, dev: &str, attr: &str, event: AttrValueEvent) -> BoxStream<'static, Result<AttrRead<Value>>> {
656        self.subscribe_event(dev, attr, |events| events.values.entry(event).or_default()).boxed()
657    }
658
659    /// Subscribe to an attribute of a device being ready to be read.
660    pub(super) fn subscribe_attr_ready(&self, dev: &str, attr: &str) -> BoxStream<'static, Result<AttrReady>> {
661        self.subscribe_event(dev, attr, |events| &mut events.ready).boxed()
662    }
663
664    /// Subscribe to the configuration of an attribute of a device.
665    pub(super) fn subscribe_attr_config(&self, dev: &str, attr: &str) -> BoxStream<'static, Result<AttrInfo>> {
666        self.subscribe_event(dev, attr, |events| &mut events.conf).boxed()
667    }
668
669    /// Push a reading of an attribute of a device, for that event.
670    pub(super) fn push_attr_value(&self, dev: &str, attr: &str, event: AttrValueEvent, read: Result<AttrRead<Value>>) {
671        self.push_event(dev, attr, |events| events.values.entry(event).or_default(), read);
672    }
673
674    /// Push an attribute of a device being ready to be read.
675    pub(super) fn push_attr_ready(&self, dev: &str, attr: &str, ready: Result<AttrReady>) {
676        self.push_event(dev, attr, |events| &mut events.ready, ready);
677    }
678
679    /// Push the configuration of an attribute of a device.
680    pub(super) fn push_attr_config(&self, dev: &str, attr: &str, info: Result<AttrInfo>) {
681        self.push_event(dev, attr, |events| &mut events.conf, info);
682    }
683
684    fn subscribe_event<T>(&self, dev: &str, attr: &str, select: impl FnOnce(&mut AttrEvents) -> &mut Subscribers<T>) -> EventStream<T> {
685
686        let slot = Arc::new(Slot::new());
687
688        let dev = Arc::<str>::from(dev);
689        let mut devs = self.events.lock().unwrap();
690        let attrs = devs.entry(ArcName::from(Arc::clone(&dev))).or_default();
691        let events = attrs.entry(ArcName::from(attr)).or_default();
692        let subscribers = select(events);
693        subscribers.retain(|slot| slot.strong_count() != 0);
694        subscribers.push(Arc::downgrade(&slot));
695
696        EventStream {
697            dev,
698            slot,
699            ended: false,
700        }
701
702    }
703
704    fn push_event<T: Clone>(&self, dev: &str, attr: &str, select: impl FnOnce(&mut AttrEvents) -> &mut Subscribers<T>, event: Result<T>) {
705
706        let mut devs = self.events.lock().unwrap();
707        let Some(attrs) = devs.get_mut(Name::new(dev)) else { return };
708        let Some(events) = attrs.get_mut(Name::new(attr)) else { return };
709
710        // Pushed to under the lock, a slot only waking its subscriber.
711        let subscribers = select(events);
712        subscribers.retain(|slot| slot.strong_count() != 0);
713
714        // Each subscriber has its own copy of the event, the last one taking it as it is.
715        if let Some((last, others)) = subscribers.split_last() {
716            
717            for slot in others.iter().filter_map(Weak::upgrade) {
718                slot.push(event.clone());
719            }
720
721            if let Some(slot) = last.upgrade() {
722                slot.push(event);
723            }
724
725        }
726
727        // What is left with no subscriber at all is removed, all the way up.
728        events.values.retain(|_, subscribers| !subscribers.is_empty());
729        if events.values.is_empty() && events.ready.is_empty() && events.conf.is_empty() {
730            attrs.remove(Name::new(attr));
731            if attrs.is_empty() {
732                devs.remove(Name::new(dev));
733            }
734        }
735
736    }
737
738    /// End the subscriptions to the events of that device, which is gone for good.
739    fn end_dev_events(&self, dev: &str) {
740        let attrs = self.events.lock().unwrap().remove(Name::new(dev));
741        for events in attrs.into_iter().flat_map(HashMap::into_values) {
742            events.end();
743        }
744    }
745
746    /// End every subscription, the server having stopped.
747    fn end_events(&self) {
748        let devs = mem::take(&mut *self.events.lock().unwrap());
749        for events in devs.into_values().flat_map(HashMap::into_values) {
750            events.end();
751        }
752    }
753
754}
755
756impl AttrEvents {
757
758    /// End the subscriptions of every subscriber still there.
759    fn end(self) {
760        for subscribers in self.values.into_values() {
761            end_subscribers(subscribers);
762        }
763        end_subscribers(self.ready);
764        end_subscribers(self.conf);
765    }
766
767}
768
769fn end_subscribers<T>(subscribers: Subscribers<T>) {
770    for slot in subscribers.iter().filter_map(Weak::upgrade) {
771        slot.end();
772    }
773}
774
775/// The events of one subscriber, which unsubscribes by being dropped, see [`Subscribers`].
776struct EventStream<T> {
777    /// The name of the device the events are of, which the end of the subscription names.
778    dev: Arc<str>,
779    slot: Arc<Slot<Result<T>>>,
780    /// Set once the end of the subscription was given.
781    ended: bool,
782}
783
784impl<T> Stream for EventStream<T> {
785
786    type Item = Result<T>;
787
788    fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
789
790        let this = self.get_mut();
791        if this.ended {
792            return Poll::Ready(None);
793        }
794
795        // The end of the slot is given as the end of the subscription, once.
796        this.slot.poll_take(cx).map(|event| event.or_else(|| {
797            this.ended = true;
798            Some(Err(Error::new(ErrorKind::DevNotConnected)
799                .with_description(format!("Device {:?} is no longer served", this.dev))))
800        }))
801
802    }
803
804}
805
806/// What a server is built with, and served by, see [`Self::serve`].
807pub struct ServerBuilder {
808    exe: String,
809    inst: String,
810    backend: Option<Arc<dyn Backend>>,
811    database: Option<DatabaseProxy>,
812    /// How the backend serves, see [`Self::host`] and [`Self::port`].
813    config: BackendServerConfig,
814    /// See [`Self::local`].
815    local: bool,
816    /// See [`Self::stop_on_terminate`].
817    stop_on_terminate: bool,
818    /// See [`Self::terminate_on_signals`].
819    #[cfg(feature = "cli")]
820    terminate_on_signals: bool,
821    /// See [`Self::boot_timeout`].
822    boot_timeout: Duration,
823    /// The database for testing the server is registered in, which the server owns for
824    /// as long as it runs, see [`ServerHandle`].
825    test_context: Option<TestContext>,
826    /// The definitions of the classes of that server, each made a class once the server
827    /// exists, which is only once it is served: a class owns the server it is in. Kept in
828    /// the order they were defined, which is the order their devices are initialized in.
829    classes: Vec<(ArcName, Arc<dyn AnyClassDef>)>,
830}
831
832/// A class definition of any model, which is how a [`ServerBuilder`] holds them.
833trait AnyClassDef: Send + Sync {
834    fn new_class(self: Arc<Self>, server: Arc<Server>, index: usize) -> Arc<dyn AnyClass>;
835}
836
837impl<M: Model> AnyClassDef for ClassDef<M> {
838    fn new_class(self: Arc<Self>, server: Arc<Server>, index: usize) -> Arc<dyn AnyClass> {
839        Class::new(server, self, index)
840    }
841}
842
843impl ServerBuilder {
844
845    /// Build a server named `exe/inst`, after the executable running it and the name of
846    /// the instance of that executable, which is how it is registered in the database.
847    pub fn new(exe: &str, inst: &str) -> Self {
848        Self {
849            exe: exe.to_string(),
850            inst: inst.to_string(),
851            backend: None,
852            database: None,
853            config: BackendServerConfig::default(),
854            local: true,
855            stop_on_terminate: false,
856            #[cfg(feature = "cli")]
857            terminate_on_signals: false,
858            boot_timeout: DEFAULT_BOOT_TIMEOUT,
859            test_context: None,
860            classes: Vec::new(),
861        }
862    }
863
864    /// The backend to serve with, the default one if none is given, see
865    /// [`default_backend`].
866    pub fn backend(mut self, backend: Arc<dyn Backend>) -> Self {
867        self.backend = Some(backend);
868        self
869    }
870
871    /// The database to register in, the one of the environment if none is given.
872    pub fn database(mut self, database: DatabaseProxy) -> Self {
873        self.database = Some(database);
874        self
875    }
876
877    /// The host to listen at, see [`BackendServerConfig::host`].
878    pub fn host(mut self, host: &str) -> Self {
879        self.config = self.config.host(host);
880        self
881    }
882
883    /// The port to listen at, see [`BackendServerConfig::port`].
884    pub fn port<R: RangeBounds<u16>>(mut self, port: R) -> Self {
885        self.config = self.config.port(port);
886        self
887    }
888
889    /// Make ZMQ listen at this port for its heartbeat, see
890    /// [`BackendServerConfig::zmq_heartbeat_port`].
891    pub fn zmq_heartbeat_port<R: RangeBounds<u16>>(mut self, port: R) -> Self {
892        self.config = self.config.zmq_heartbeat_port(port);
893        self
894    }
895
896    /// Make ZMQ listen at this port for its events, see
897    /// [`BackendServerConfig::zmq_event_port`].
898    pub fn zmq_event_port<R: RangeBounds<u16>>(mut self, port: R) -> Self {
899        self.config = self.config.zmq_event_port(port);
900        self
901    }
902
903    /// Enable or disable registration of this server's devices into the local registry,
904    /// which allows a [`DevProxy`](crate::dev::DevProxy) created in this same process to
905    /// access the device directly without going through the backend's wire protocol.
906    /// Enabled by default.
907    pub fn local(mut self, local: bool) -> Self {
908        self.local = local;
909        self
910    }
911
912    /// Define a class in that server, whose devices the database can then list.
913    ///
914    /// # Panics
915    ///
916    /// If the name of the class is invalid, see [`name::check_tango_class_name`], if it is
917    /// the one of the admin class, or if the server already defines a class of that name.
918    #[track_caller]
919    pub fn class<M: Model>(mut self, def: ClassDef<M>) -> Self {
920
921        if !name::check_tango_class_name(&def.name) {
922            panic!("the class name {:?} is invalid", def.name);
923        }
924
925        if def.name.eq_ignore_ascii_case(admin::CLASS_NAME) {
926            panic!("the class name {:?} is reserved to the admin device", def.name);
927        }
928
929        if self.classes.iter().any(|(name, _)| **name == *Name::new(&def.name)) {
930            panic!("the class {:?} is already defined", def.name);
931        }
932
933        self.classes.push((ArcName::from(&*def.name), Arc::new(def)));
934        self
935
936    }
937
938    /// Stop the server when the process terminates, see [`terminate`], which is not the
939    /// default unless built from the command line, see [`Self::terminate_on_signals`]. The
940    /// server is then stopped as the `Kill` command of its admin device does, which deletes
941    /// its devices, see [`Server::stop_async`], and the thread waiting on it returns, see
942    /// [`Server::wait`]. A server still booting gives up its boot, see [`Self::serve`].
943    ///
944    /// [`terminate`]: super::terminate()
945    pub fn stop_on_terminate(mut self, stop_on_terminate: bool) -> Self {
946        self.stop_on_terminate = stop_on_terminate;
947        self
948    }
949
950    /// How long the server is given to boot when served blocking, 30 seconds by default,
951    /// see [`Self::serve`]: the database being reached, every device initialized and every
952    /// one of them exported. An asynchronous caller bounds [`Self::serve_async`] itself.
953    pub fn boot_timeout(mut self, boot_timeout: Duration) -> Self {
954        self.boot_timeout = boot_timeout;
955        self
956    }
957
958    /// Boot the server, see [`Self::serve_async`].
959    async fn boot(self) -> Result<ServerHandle> {
960
961        let backend = self.backend.unwrap_or_else(default_backend);
962        let database = self.database
963            .unwrap_or_else(|| DatabaseProxy::new_from_env_with_backend(Arc::clone(&backend)));
964
965        // The backend names the events of the server after the server and its database,
966        // which is therefore reached before anything is served.
967        let admin_dev_name = Arc::<str>::from(format!("{ADMIN_DEV_PREFIX}{}/{}", self.exe, self.inst));
968        let (tango_host, tango_port) = database.host_and_port_async().await?;
969        let config = self.config.clone()
970            .admin_name(Arc::clone(&admin_dev_name))
971            .tango_host(tango_host, tango_port);
972
973        let backend = backend.serve(&config).await?;
974        let poller = Poller::spawn()?;
975
976        let core = Arc::new_cyclic(|core| Core {
977            server: Arc::new(Server {
978                core: core.clone(),
979                admin_dev_name,
980                database,
981                events: Mutex::new(HashMap::new()),
982                local: self.local,
983            }),
984            backend,
985            classes: Mutex::new(HashMap::new()),
986            class_count: AtomicUsize::new(1 + self.classes.len()),
987            devs: Mutex::new(HashMap::new()),
988            pending: Mutex::new(Pending::default()),
989            sync_lock: async_lock::Mutex::new(()),
990            stopped: AtomicBool::new(false),
991            poller,
992        });
993
994        // The admin class is made first, its device being the one booting the others, and
995        // is kept typed, which is what its device is added through.
996        let admin = Class::new(Arc::clone(&core.server), Arc::new(Admin::def()), 0);
997        let mut classes = HashMap::new();
998        classes.insert(ArcName::from(admin::CLASS_NAME), Arc::clone(&admin) as Arc<dyn AnyClass>);
999        for (index, (name, def)) in self.classes.into_iter().enumerate() {
1000            classes.insert(name, def.new_class(Arc::clone(&core.server), 1 + index));
1001        }
1002        *core.classes.lock().unwrap() = classes;
1003
1004        // From here the handle owns the server, which it stops if anything fails.
1005        let handle = ServerHandle { core, _test_context: self.test_context };
1006        let admin_dev = admin.add_dev(handle.admin_dev_name())?;
1007
1008        let booted = match handle.sync_async().await {
1009            Ok(()) => admin_dev.check_model().await,
1010            Err(err) => Err(err),
1011        };
1012
1013        if let Err(err) = booted {
1014            // The admin device may have been exported in FAULT, which is undone here at
1015            // best: a server failing to boot usually has no database to tell anything.
1016            let _ = handle.stop_async().await;
1017            handle.wait_async().await;
1018            return Err(err);
1019        }
1020
1021        drop(admin_dev);
1022
1023        info!(server = %handle.name(),
1024            host = %handle.core.backend.host(),
1025            port = handle.core.backend.port(),
1026            devs = handle.core.devs.lock().unwrap().len() - 1, "Started the server");
1027
1028        Ok(handle)
1029
1030    }
1031
1032    /// Start serving: the backend is acquired, every class is made from its definition,
1033    /// and the admin device is added and synchronized, which boots the whole server.
1034    /// 
1035    /// This fails if the admin device fails to initialize, which is what a server that
1036    /// cannot reach its database does: it would have nothing to serve.
1037    ///
1038    /// This blocks, see [`Self::serve_async`] for what does not, and fails once the server
1039    /// did not boot within its timeout, see [`Self::boot_timeout`], or once the process
1040    /// terminates while it boots, see [`Self::stop_on_terminate`]. The boot is then given
1041    /// up wherever it was, so devices it had exported already stay exported in the
1042    /// database until the server is served again.
1043    pub fn serve(self) -> Result<ServerHandle> {
1044        let boot_timeout = self.boot_timeout;
1045        let server_name = format!("{}/{}", self.exe, self.inst);
1046        block_on_timeout(self.serve_async(), boot_timeout)
1047            .map_err(|err| err.with_description(format!("Server {server_name:?} did not boot within {boot_timeout:?}")))?
1048    }
1049
1050    /// Start serving, see [`Self::serve`], resolving once the whole server is booted.
1051    pub async fn serve_async(self) -> Result<ServerHandle> {
1052
1053        let server_name = format!("{}/{}", self.exe, self.inst);
1054        if !name::check_tango_server_part_name(&self.exe) 
1055        || !name::check_tango_server_part_name(&self.inst) {
1056            return Err(Error::new(ErrorKind::ServerNameInvalid)
1057                .with_description(format!("Server {server_name:?} has an invalid name, it should be \
1058                    exe/inst, each part made of letters, digits, '_' and '-'")));
1059        }
1060
1061        // Before anything is served, which a handler that cannot be installed then spares.
1062        #[cfg(feature = "cli")]
1063        if self.terminate_on_signals {
1064            cli::install_signal_handler()?;
1065        }
1066
1067        let stop_on_terminate = self.stop_on_terminate;
1068        let boot = pin!(self.boot());
1069        if !stop_on_terminate {
1070            return boot.await;
1071        }
1072
1073        let handle = match future::select(boot, pin!(terminate::terminating())).await {
1074            Either::Left((booted, _)) => booted?,
1075            Either::Right(((), _)) => return Err(Error::new(ErrorKind::Aborted)
1076                .with_description(format!("Server {server_name:?} did not finish booting, the process is terminating"))),
1077        };
1078
1079        // The process may have terminated right after the boot, the server being missed.
1080        if terminate::register(&handle.core.server) {
1081            let _ = handle.stop_async().await;
1082        }
1083
1084        Ok(handle)
1085
1086    }
1087
1088    /// Serve until the server is stopped, by [`terminate`](super::terminate()) (on a signal
1089    /// when [`Self::terminate_on_signals`] is set) or by the `Kill` command of its admin
1090    /// device, which deletes its devices: this is [`Self::serve`] then [`Server::wait`],
1091    /// which is all the main thread of most servers does.
1092    pub fn run(self) -> Result<()> {
1093        self.serve()?.wait();
1094        Ok(())
1095    }
1096
1097    /// Serve until the server is stopped, see [`Self::run`].
1098    pub async fn run_async(self) -> Result<()> {
1099        self.serve_async().await?.wait_async().await;
1100        Ok(())
1101    }
1102
1103}
1104
1105#[cfg(feature = "cli")]
1106impl ServerBuilder {
1107
1108    /// Terminate the process on the signals it is asked to terminate with, see
1109    /// [`terminate::terminate`], which a server built from the command line does: Ctrl-C, and SIGTERM
1110    /// and SIGHUP on Unix, the console being closed on Windows. Handling them also stops
1111    /// the server on termination, see [`Self::stop_on_terminate`].
1112    ///
1113    /// There is a single handler of these signals per process, which serving fails to
1114    /// install if the application installed one of its own: this is then disabled, and
1115    /// the application calls [`terminate::terminate`] from its own handler.
1116    pub fn terminate_on_signals(mut self, terminate_on_signals: bool) -> Self {
1117        self.terminate_on_signals = terminate_on_signals;
1118        if terminate_on_signals {
1119            self = self.stop_on_terminate(true);
1120        }
1121        self
1122    }
1123
1124    /// Build the server from the command line of this process, see [`ServerArgs`], which
1125    /// is what launching a server usually takes. The process exits with its usage when
1126    /// the command line is invalid or asks for help.
1127    ///
1128    /// See [`Self::from_raw_args`] for what the server is named after.
1129    pub fn from_args() -> Self {
1130        Self::from_raw_args(None, None)
1131    }
1132
1133    /// Build the server named after that executable and the instance of that command
1134    /// line, see [`ServerArgs`], which is also where it listens. The logs of the process
1135    /// are printed at the level it asks for.
1136    ///
1137    /// With no executable given, the server is named after the one of this process, as
1138    /// cppTango names it: the name the process was run under, without its directory nor
1139    /// the suffix of the platform's executables, which is what the Starter of a host runs
1140    /// a server by. Giving one keeps the name of the server whatever its file is called.
1141    ///
1142    /// With no command line given, the one of this process is parsed, as
1143    /// [`Self::from_args`] does; a server with options of its own parses it itself and
1144    /// gives what it flattened, see [`ServerArgs`].
1145    pub fn from_raw_args(exec: Option<&str>, args: Option<&ServerArgs>) -> Self {
1146
1147        use std::process;
1148
1149        use clap::{Args, Command, FromArgMatches};
1150        use tracing_subscriber::filter::LevelFilter;
1151        use tracing_subscriber::EnvFilter;
1152
1153        let exec = exec.map(Cow::Borrowed).unwrap_or_else(|| Cow::Owned(cli::exe()));
1154
1155        let args = match args {
1156            Some(args) => Cow::Borrowed(args),
1157            None => {
1158                let matches = ServerArgs::augment_args(Command::new(exec.to_string())).get_matches();
1159                let args = ServerArgs::from_arg_matches(&matches).unwrap_or_else(|err| err.exit());
1160                Cow::Owned(args)
1161            }
1162        };
1163
1164        // The subscriber printing the logs of the process, at the level asked for unless
1165        // `RUST_LOG` says otherwise. An application that installed one of its own keeps it.
1166        let level = match args.verbose {
1167            0 => LevelFilter::INFO,
1168            1 => LevelFilter::DEBUG,
1169            _ => LevelFilter::TRACE,
1170        };
1171
1172        let _ = tracing_subscriber::fmt()
1173            .with_env_filter(EnvFilter::builder()
1174                .with_default_directive(level.into())
1175                .from_env_lossy())
1176            .try_init();
1177
1178        let mut builder = Self::new(&exec, &args.inst)
1179            .terminate_on_signals(true);
1180
1181        if let Some(host) = &args.host {
1182            builder = builder.host(host);
1183        }
1184
1185        if let Some((start, end)) = args.port {
1186            builder = builder.port(start..=end);
1187        }
1188
1189        if let Some((start, end)) = args.zmq_heartbeat_port {
1190            builder = builder.zmq_heartbeat_port(start..=end);
1191        }
1192
1193        if let Some((start, end)) = args.zmq_event_port {
1194            builder = builder.zmq_event_port(start..=end);
1195        }
1196
1197        // The database for testing, served from now on, which the server is registered in
1198        // and owns: failing to serve it is failing to launch the server at all.
1199        if !args.devs.is_empty() {
1200            let ctx = cli::test_context(&exec, &args).unwrap_or_else(|err| {
1201                eprintln!("Error: {err:#}");
1202                process::exit(1)
1203            });
1204            builder = builder.database(ctx.database().clone());
1205            builder.test_context = Some(ctx);
1206        }
1207
1208        builder
1209
1210    }
1211
1212}
1213
1214/// The handle to a server being served, which is what owns it on behalf of its caller, and
1215/// derefs to it.
1216///
1217/// A server ends by being stopped, see [`Server::stop_async`], which deletes its devices, by its
1218/// owner or by a client through the `Kill` command of its admin device, and is waited for
1219/// by its owner, see [`Server::wait`]. A server is always stopped: dropping the handle of a
1220/// server that was not only stops its backend, with no other side effect, see [`Drop`].
1221#[derive(Debug)]
1222pub struct ServerHandle {
1223    /// What owns the server, which only the handle holds for good.
1224    core: Arc<Core>,
1225    /// The database for testing the server is registered in, if any, which is dropped
1226    /// after it, the server being unregistered from it once it is waited for.
1227    _test_context: Option<TestContext>,
1228}
1229
1230impl ServerHandle {
1231
1232    /// The server this handle serves.
1233    #[inline]
1234    pub fn server(&self) -> &Server {
1235        &self.core.server
1236    }
1237
1238    /// The server, shared, which does not keep it served: once the handle is dropped, see
1239    /// [`Drop`], it is not served anymore.
1240    pub(crate) fn server_arc(&self) -> Arc<Server> {
1241        Arc::clone(&self.core.server)
1242    }
1243
1244}
1245
1246impl Deref for ServerHandle {
1247
1248    type Target = Server;
1249
1250    #[inline]
1251    fn deref(&self) -> &Server {
1252        &self.core.server
1253    }
1254
1255}
1256
1257impl Drop for ServerHandle {
1258
1259    /// Stop the backend and end the subscriptions, with no other side effect: a server
1260    /// that was not stopped, see [`Server::stop_async`], is not unexported, and its models are
1261    /// not deleted. The requests in flight are not waited for, and everything of the server
1262    /// is let go of once they end, see [`BackendServer`], a request still holding it for
1263    /// the time of a [`Server::sync_async`] or a [`Server::stop_async`] it runs.
1264    fn drop(&mut self) {
1265        self.core.backend.stop();
1266        self.core.server.end_events();
1267    }
1268
1269}
1270
1271#[cfg(test)]
1272mod tests {
1273
1274    use futures::executor::block_on;
1275    use futures::FutureExt;
1276
1277    use crate::dev::{AttrQuality, DevState};
1278    use crate::value::AttrDataKind;
1279    use crate::testing::TestContext;
1280
1281    use super::super::def::ClassDef;
1282    use super::*;
1283
1284
1285    /// A server with a device `a/b/c` of a class `A`, served and synchronized.
1286    fn serve() -> (TestContext, Arc<Server>) {
1287
1288        let ctx = TestContext::new().unwrap();
1289        ctx.database().add_server("Test/test", &[("a/b/c", "A")]).unwrap();
1290
1291        let server = ctx.serve(ServerBuilder::new("Test", "test")
1292            .class(ClassDef::<()>::new_default("A")))
1293            .unwrap();
1294
1295        (ctx, server)
1296
1297    }
1298
1299    fn read(value: f64) -> AttrRead<Value> {
1300        AttrRead {
1301            value: Some(Value::from(value)),
1302            w_value: None,
1303            quality: AttrQuality::Valid,
1304            time: std::time::SystemTime::UNIX_EPOCH + Duration::from_secs(1),
1305        }
1306    }
1307
1308    /// The next item of a stream, if there is one already.
1309    fn now<T>(stream: &mut BoxStream<'static, T>) -> Option<Option<T>> {
1310        stream.next().now_or_never()
1311    }
1312
1313    #[test]
1314    fn latest_only() {
1315
1316        let (_ctx, server) = serve();
1317        let mut sub = server.subscribe_attr_value("a/b/c", "Attr", AttrValueEvent::Change);
1318
1319        assert!(now(&mut sub).is_none());
1320
1321        server.push_attr_value("a/b/c", "attr", AttrValueEvent::Change, Ok(read(1.0)));
1322        server.push_attr_value("A/B/C", "ATTR", AttrValueEvent::Change, Ok(read(2.0)));
1323
1324        // Another event, or another attribute, reaches nothing.
1325        server.push_attr_value("a/b/c", "attr", AttrValueEvent::Archive, Ok(read(3.0)));
1326        server.push_attr_value("a/b/c", "other", AttrValueEvent::Change, Ok(read(4.0)));
1327
1328        assert_eq!(now(&mut sub).unwrap().unwrap().unwrap(), read(2.0));
1329        assert!(now(&mut sub).is_none());
1330
1331    }
1332
1333    #[test]
1334    fn every_subscriber() {
1335
1336        let (_ctx, server) = serve();
1337        let mut first = server.subscribe_attr_value("a/b/c", "attr", AttrValueEvent::Change);
1338        let mut second = server.subscribe_attr_value("a/b/c", "attr", AttrValueEvent::Change);
1339
1340        server.push_attr_value("a/b/c", "attr", AttrValueEvent::Change, Err(Error::new(ErrorKind::Reason(reason::API_AttrNotAllowed))));
1341
1342        for sub in [&mut first, &mut second] {
1343            let err = now(sub).unwrap().unwrap().unwrap_err();
1344            assert_eq!(err.kind(), ErrorKind::Reason(reason::API_AttrNotAllowed));
1345        }
1346
1347    }
1348
1349    #[test]
1350    fn unsubscribe() {
1351
1352        let (_ctx, server) = serve();
1353        let sub = server.subscribe_attr_ready("a/b/c", "attr");
1354        drop(sub);
1355
1356        // The push finds nothing to hand the event to, and forgets the attribute.
1357        server.push_attr_ready("a/b/c", "attr", Ok(AttrReady { data_kind: AttrDataKind::Long, counter: 1 }));
1358        assert!(server.events.lock().unwrap().is_empty());
1359
1360    }
1361
1362    #[test]
1363    fn restart() {
1364
1365        let (_ctx, server) = serve();
1366        let mut sub = server.subscribe_attr_config("a/b/c", "attr");
1367
1368        // Removed and added again under the same name, as a restart does.
1369        assert!(server.remove_dev("a/b/c"));
1370        server.add_dev("A", "a/b/c").unwrap();
1371        server.sync().unwrap();
1372        assert!(now(&mut sub).is_none());
1373
1374        // Removed for good.
1375        assert!(server.remove_dev("a/b/c"));
1376        server.sync().unwrap();
1377        assert_eq!(now(&mut sub).unwrap().unwrap().unwrap_err().kind(), ErrorKind::DevNotConnected);
1378        assert!(now(&mut sub).unwrap().is_none());
1379
1380    }
1381
1382    #[test]
1383    fn stop() {
1384
1385        let (_ctx, server) = serve();
1386        let mut sub = server.subscribe_attr_ready("a/b/c", "attr");
1387
1388        // The event pushed before the end is taken first.
1389        server.push_attr_ready("a/b/c", "attr", Ok(AttrReady { data_kind: AttrDataKind::Long, counter: 1 }));
1390        server.stop().unwrap();
1391
1392        assert!(now(&mut sub).unwrap().unwrap().is_ok());
1393        assert_eq!(now(&mut sub).unwrap().unwrap().unwrap_err().kind(), ErrorKind::DevNotConnected);
1394        assert!(now(&mut sub).unwrap().is_none());
1395
1396    }
1397
1398    #[test]
1399    fn weak() {
1400
1401        let (_ctx, server) = serve();
1402        let weak = Arc::downgrade(&server.any_dev("a/b/c").unwrap());
1403        assert_eq!(&**weak.upgrade().unwrap().name(), "a/b/c");
1404
1405        // Restarted under the same name, the weak reference is to the device that was.
1406        assert!(server.remove_dev("a/b/c"));
1407        server.add_dev("A", "a/b/c").unwrap();
1408        server.sync().unwrap();
1409        assert!(weak.upgrade().is_none());
1410
1411    }
1412
1413    #[test]
1414    fn dropped() {
1415
1416        let (ctx, server) = serve();
1417        let mut sub = server.subscribe_attr_ready("a/b/c", "attr");
1418        drop(ctx);
1419
1420        assert_eq!(block_on(sub.next()).unwrap().unwrap_err().kind(), ErrorKind::DevNotConnected);
1421
1422    }
1423
1424    #[test]
1425    fn freed() {
1426
1427        let (ctx, server) = serve();
1428        server.add_dev("A", "a/b/d").unwrap();
1429        let served = Arc::downgrade(&server.any_dev("a/b/c").unwrap());
1430        let pending = Arc::downgrade(&server.any_dev("a/b/d").unwrap());
1431        drop(ctx);
1432
1433        // Every device is let go of, those still waiting for a synchronization included,
1434        // while the server itself, still held, is not served anymore.
1435        assert!(served.upgrade().is_none());
1436        assert!(pending.upgrade().is_none());
1437        assert!(!server.has_dev("a/b/c"));
1438        assert_eq!(server.add_dev("A", "a/b/e").unwrap_err().kind(), ErrorKind::Reason(reason::API_ServerNotRunning));
1439        server.wait();
1440
1441    }
1442
1443    #[test]
1444    fn withdrawn() {
1445
1446        let (ctx, server) = serve();
1447        let dev = server.get_dev::<()>("a/b/c").unwrap();
1448        assert!(!dev.is_withdrawn());
1449        dev.push_user_event("state", DevState::On).unwrap();
1450
1451        // Restarted under the same name, the device held is not the one served anymore.
1452        assert!(server.remove_dev("a/b/c"));
1453        server.add_dev("A", "a/b/c").unwrap();
1454        server.sync().unwrap();
1455        assert!(dev.is_withdrawn());
1456        assert_eq!(dev.push_user_event("state", DevState::On).unwrap_err().kind(), ErrorKind::DevNotConnected);
1457
1458        // Nor is any once the server is not served anymore.
1459        let restarted = server.get_dev::<()>("a/b/c").unwrap();
1460        assert!(!restarted.is_withdrawn());
1461        drop(ctx);
1462        assert!(restarted.is_withdrawn());
1463
1464    }
1465
1466    #[test]
1467    fn withdrawn_local() {
1468
1469        let (ctx, server) = serve();
1470        let client = ctx.dev("a/b/c");
1471        client.ping().unwrap();
1472        assert!(ctx.is_local("a/b/c").unwrap());
1473
1474        // The proxy reaches the device itself, which is kept alive here once removed: it
1475        // is refused all the same, rather than answered as an uninitialized device, which
1476        // makes the proxy look it up again on its next request, and find it unexported.
1477        let dev = server.get_dev::<()>("a/b/c").unwrap();
1478        assert!(server.remove_dev("a/b/c"));
1479        server.sync().unwrap();
1480        assert!(dev.is_withdrawn());
1481        assert_eq!(client.ping().unwrap_err().kind(), ErrorKind::DevNotConnected);
1482        assert_eq!(client.state().unwrap_err().kind(), ErrorKind::DevNotExported);
1483
1484    }
1485
1486    #[test]
1487    fn wait_twice() {
1488
1489        let (_ctx, server) = serve();
1490        server.stop().unwrap();
1491        server.wait();
1492        server.wait();
1493        assert!(server.dev_names().is_empty());
1494
1495    }
1496
1497}