Skip to main content

tango/server/
server.rs

1//! The server itself: what owns the classes, and through them the devices, and the backend
2//! serving them.
3//!
4//! Ownership is deliberately cyclic: the server owns its classes, a class owns its devices,
5//! and a device owns its class which owns the server, so that any of them reaches the
6//! others as plain field access. The cycles are broken by the [`ServerHandle`] alone, which
7//! empties every map when it is dropped, see [`Server::clear`]. Nothing of a server is
8//! therefore handed out as an [`Arc`], only as a [`Ref`].
9
10use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering};
11use std::collections::hash_map::Entry;
12use std::sync::{Arc, Mutex, Weak};
13use std::task::{Context, Poll};
14use std::collections::HashMap;
15use std::time::Duration;
16use std::borrow::Cow;
17use std::pin::Pin;
18use std::mem;
19
20use futures::stream::{BoxStream, Stream, StreamExt};
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, AttrValueEvent};
27use crate::error::{Error, ErrorKind, Result, reason};
28use crate::future::block_on_timeout;
29use crate::name::{ArcName, Name};
30use crate::value::Value;
31use crate::future::Slot;
32use crate::testing::TestContext;
33
34use super::class::{AnyClass, Class};
35use super::admin::{self, Admin};
36use super::def::ClassDef;
37use super::{Model, Ref};
38use super::dev::AnyDev;
39use super::signal;
40
41
42/// What the name of the admin device of a server is its `exe/inst` name prefixed with.
43const ADMIN_DEV_PREFIX: &str = "dserver/";
44
45/// The shared state of a server, co-owned by the [`ServerHandle`] and by every class of it.
46#[derive(Debug)]
47pub struct Server {
48    /// Self reference, for what a server hands its classes of itself.
49    this: Weak<Self>,
50    /// The `dserver/exe/inst` name of the admin device of that server, which is where its
51    /// own `exe/inst` name is taken from, see [`Self::name`].
52    pub(super) admin_dev_name: Arc<str>,
53    /// The database proxy used for that server.
54    database: DatabaseProxy,
55    /// The backend serving the devices of that server, owned by the handle, see
56    /// [`ServerHandle`]: the backend holds the devices, which hold the server, so this
57    /// owning it would be a cycle nothing breaks.
58    backend: Weak<dyn BackendServer>,
59    /// The classes of that server, each owning its devices.
60    classes: Mutex<HashMap<ArcName, Arc<dyn AnyClass>>>,
61    /// The number of classes made for that server so far, which is the index of the next
62    /// one, see [`AnyClass::index`].
63    class_count: AtomicUsize,
64    /// Every device of that server, which only the server owns, device names being unique
65    /// server-wide. This is the lock every addition of a device is made under, see
66    /// [`Class::add_dev`].
67    pub(super) devs: Mutex<HashMap<ArcName, Arc<dyn AnyDev>>>,
68    /// What the next [`Self::sync`] applies, which is never locked with any other lock.
69    pub(super) pending: Mutex<Pending>,
70    /// Held for the whole of a [`Self::sync`], so that two of them never interleave, and
71    /// while stopping, see [`Self::stop`].
72    sync_lock: async_lock::Mutex<()>,
73    /// Whether that server was stopped, which is only ever done once.
74    stopped: AtomicBool,
75    /// The subscriptions to the events of the attributes of the devices of that server, by
76    /// device and attribute name.
77    ///
78    /// They are the server's and not the devices': a device restarted, or a whole server
79    /// restarted, is made anew under the same name, and so are its attributes on every
80    /// Init, while its subscribers are kept, the way cppTango keeps them. A client of a
81    /// server that is still running sees nothing of a restart, so nothing would make it
82    /// subscribe again.
83    ///
84    /// The streams handed out end, after a [`ErrorKind::DevNotConnected`], once the device
85    /// is gone for good, see [`Self::sync`], or the server stops, see [`Self::stop`]: the
86    /// end of a subscription of a backend, see [`crate::backend::BackendDev`].
87    events: Mutex<HashMap<ArcName, HashMap<ArcName, AttrEvents>>>,
88    /// Whether the devices of that server are reached directly by the clients of this
89    /// process, see [`ServerBuilder::local`].
90    pub(super) local: bool,
91}
92
93/// The subscribers of the events of an attribute, see [`Server::events`].
94#[derive(Debug, Default)]
95struct AttrEvents {
96    values: HashMap<AttrValueEvent, Subscribers<AttrRead<Value>>>,
97    ready: Subscribers<()>,
98    conf: Subscribers<AttrInfo>,
99}
100
101/// The subscribers of an event, which only hold their slot weakly: a subscriber dropping
102/// its stream is what unsubscribes it, its slot being pruned the next time the event is
103/// pushed or subscribed to.
104type Subscribers<T> = Vec<Weak<Slot<Result<T>>>>;
105
106/// The operations on the devices of a server that wait for its next [`Server::sync`].
107#[derive(Debug, Default)]
108pub struct Pending {
109    /// The devices added and not initialized yet, in the order they were added.
110    pub added: Vec<Arc<dyn AnyDev>>,
111    /// The devices initialized and not exported yet, either because they were just
112    /// initialized or because serving or exporting them failed, along with the reference
113    /// the backend serves them at once it does.
114    pub unexported: Vec<(Arc<dyn AnyDev>, Option<Arc<str>>)>,
115    /// The devices removed and still served, possibly still exported.
116    pub removed: Vec<Arc<dyn AnyDev>>,
117}
118
119impl Server {
120
121    /// The `exe/inst` name of that server, under which it is registered in the database.
122    #[inline]
123    pub fn name(&self) -> &str {
124        &self.admin_dev_name[ADMIN_DEV_PREFIX.len()..]
125    }
126
127    #[inline]
128    pub fn admin_dev_name(&self) -> &str {
129        &self.admin_dev_name
130    }
131
132    #[inline]
133    pub fn database(&self) -> &DatabaseProxy {
134        &self.database
135    }
136
137    /// The backend serving the devices of that server, [`None`] once its handle is
138    /// dropped, see [`ServerHandle`].
139    #[inline]
140    pub fn backend(&self) -> Option<Arc<dyn BackendServer>> {
141        self.backend.upgrade()
142    }
143
144    /// The backend serving the devices of that server, failing once its handle is
145    /// dropped, see [`Self::backend`].
146    pub(super) fn served_backend(&self) -> Result<Arc<dyn BackendServer>> {
147        self.backend().ok_or_else(|| Error::new(ErrorKind::Reason(reason::API_ServerNotRunning))
148            .with_append_description(format_args!("Server {} is not served anymore", self.name())))
149    }
150
151    /// Register a new class in this server, from its definition.
152    pub fn add_class<M: Model>(&self, def: ClassDef<M>) -> Result<Ref<'_, Class<M>>> {
153
154        let def = Arc::new(def);
155        let mut classes = self.classes.lock().unwrap();
156        let name = ArcName::from(Arc::from(&*def.name));
157
158        let Entry::Vacant(entry) = classes.entry(name) else {
159            return Err(Error::new(ErrorKind::ClassAlreadyDefined)
160                .with_append_description(format_args!("Class {:?}", def.name)));
161        };
162
163        // A server is only ever reached through a reference to it, so it is alive.
164        let index = self.class_count.fetch_add(1, Ordering::Relaxed);
165        let class = Class::new(self.this.upgrade().unwrap(), def, index);
166        entry.insert(Arc::clone(&class) as Arc<dyn AnyClass>);
167        Ok(Ref::new(class))
168
169    }
170
171    /// Get a class of this server from its name.
172    pub fn get_class(&self, name: &str) -> Option<Ref<'_, dyn AnyClass>> {
173        self.classes.lock().unwrap().get(Name::new(name)).map(|class| Ref::new(Arc::clone(class)))
174    }
175
176    /// Add a device to this server, as an instance of the class of that name, which is how
177    /// the devices listed by the database are added, the database giving the class of each
178    /// by its name. See [`Class::add_dev`] for the typed form.
179    /// 
180    /// The device is only registered: it is initialized, served and exported by the next
181    /// [`Self::sync`].
182    pub fn add_dev(&self, class: &str, name: &str) -> Result<Ref<'_, dyn AnyDev>> {
183
184        let class = self.classes.lock().unwrap().get(Name::new(class))
185            .map(Arc::clone)
186            .ok_or_else(|| Error::new(ErrorKind::ClassNotFound)
187                .with_append_description(format_args!("Class {class:?}")))?;
188
189        class.add_dev(name).map(Ref::new)
190
191    }
192
193    /// Remove the device of that name from this server, giving back whether it had one.
194    /// 
195    /// Its name is free again right away, but the device itself is only unexported, no
196    /// longer served and deleted by the next [`Self::sync`]. A device removed before any
197    /// synchronization reached it is simply dropped.
198    pub fn remove_dev(&self, name: &str) -> bool {
199
200        let Some(dev) = self.devs.lock().unwrap().remove(Name::new(name)) else {
201            return false;
202        };
203
204        // If the device was still pending to be added, then we just remove it, otherwise
205        // we also remove its unexported state and then add it to the devices to be 
206        // removed.
207        let mut pending = self.pending.lock().unwrap();
208        if let Some(index) = pending.added.iter().position(|added| Arc::ptr_eq(added, &dev)) {
209            pending.added.remove(index);
210        } else {
211            pending.unexported.retain(|(unexported, _)| !Arc::ptr_eq(unexported, &dev));
212            pending.removed.push(dev);
213        }
214
215        true
216
217    }
218
219    /// Apply what was done to the devices of this server since the last synchronization:
220    /// the devices removed are unexported, no longer served and deleted, then the devices
221    /// added are initialized, served and exported, which is what makes them reachable.
222    /// 
223    /// The devices added are initialized one after the other, class by class in the order
224    /// the classes were made, and in the order they were added within a class. A device
225    /// whose initialization adds devices has them initialized by this same
226    /// synchronization, which is how the admin device boots a server. Each device is then
227    /// served and exported on its own, which is what a Tango server always tells the
228    /// database.
229    /// 
230    /// A device whose initialization failed is still served and exported, in FAULT, so
231    /// that a client can ask it what went wrong. A device that could not be served or
232    /// exported is retried by the next synchronization, and the first such error is given
233    /// back once every other device is done.
234    /// 
235    /// Synchronizations never interleave: one waits for the one running to be done, so
236    /// that everything done before calling it is applied once it returns. This is also why
237    /// an init function must never call it, since it would wait for itself.
238    pub async fn sync(&self) -> Result<()> {
239
240        let _sync = self.sync_lock.lock().await;
241        if self.stopped.load(Ordering::Acquire) {
242            return Ok(());
243        }
244
245        let mut first_err = None;
246
247        // Begin with pending removal of devices, they are first unexported and then we
248        // call dev.remove to make it remove itself from the backend.
249        let removed = mem::take(&mut self.pending.lock().unwrap().removed);
250        for dev in removed {
251
252            if let Err(err) = self.database.unexport_dev_async(dev.name()).await {
253                warn!(dev = %dev.name(), %err, "Failed to unexport the removed device");
254                first_err.get_or_insert(err);
255            }
256
257            if let Err(err) = dev.withdraw().await {
258                warn!(dev = %dev.name(), %err, "Failed to delete the removed device");
259                first_err.get_or_insert(err);
260            }
261
262            // A device added again under the same name, which is what a restart is, keeps
263            // the subscriptions of the one it replaces.
264            if !self.devs.lock().unwrap().contains_key(Name::new(dev.name())) {
265                self.end_dev_events(dev.name());
266            }
267
268            debug!(dev = %dev.name(), "Removed the device");
269
270        }
271
272        // Then we loop through added devices, we init their model and then we add them to
273        // the unexported list, which tell that they should be exported next!
274        loop {
275
276            let mut added = mem::take(&mut self.pending.lock().unwrap().added);
277            if added.is_empty() {
278                break;
279            }
280
281            added.sort_by_key(|dev| dev.class().index());
282            for dev in added {
283                // Only a panic of its init function ends here, a failed initialization
284                // being kept by the device itself: it is exported all the same.
285                if let Err(err) = dev.init().await {
286                    warn!(dev = %dev.name(), %err, "Failed to complete the initialization of the device");
287                }
288                self.pending.lock().unwrap().unexported.push((dev, None));
289            }
290
291        }
292
293        // Finally we process all the unexported device by exporting them to the database.
294        let unexported = mem::take(&mut self.pending.lock().unwrap().unexported);
295        let mut failed = Vec::new();
296        for (dev, itr) in unexported {
297
298            let served = match itr {
299                Some(itr) => Ok(itr),
300                None => dev.serve(),
301            };
302
303            let itr = match served {
304                Ok(itr) => itr,
305                Err(err) => {
306                    warn!(dev = %dev.name(), %err, "Failed to serve the device");
307                    first_err.get_or_insert(err);
308                    failed.push((dev, None));
309                    continue;
310                }
311            };
312
313            if let Err(err) = self.export_dev(&*dev, &itr).await {
314                warn!(dev = %dev.name(), %err, "Failed to export the device");
315                first_err.get_or_insert(err);
316                failed.push((dev, Some(itr)));
317                continue;
318            }
319
320            debug!(dev = %dev.name(), "Exported the device");
321
322        }
323
324        self.pending.lock().unwrap().unexported.extend(failed);
325        first_err.map_or(Ok(()), Err)
326
327    }
328
329    /// The blocking form of [`Self::sync`], which must therefore never run on the executor
330    /// of a backend, in an asynchronous handler in particular.
331    pub fn sync_blocking(&self) -> Result<()> {
332        block_on(self.sync())
333    }
334
335    /// Export a device served at that reference in the database, which is what a client
336    /// looks it up in.
337    async fn export_dev(&self, dev: &dyn AnyDev, itr: &str) -> Result<()> {
338        let backend = self.served_backend()?;
339        self.database.export_dev_async(ExportDevInfo {
340            name: Cow::Borrowed(dev.name()),
341            itr: Cow::Borrowed(itr),
342            host: Cow::Borrowed(&backend.host()),
343            version: Cow::Owned(backend.version().to_string()),
344            pid: std::process::id() as i32,
345        }).await
346    }
347
348    /// Every class of this server, in the order they were made, the admin one first, see
349    /// [`AnyClass::index`].
350    pub fn classes(&self) -> Vec<Ref<'_, dyn AnyClass>> {
351        let mut classes = self.classes.lock().unwrap().values().map(Arc::clone).collect::<Vec<_>>();
352        classes.sort_by_key(|class| class.index());
353        classes.into_iter().map(Ref::new).collect()
354    }
355
356    /// Every device of this server, class by class in the order of [`Self::classes`], and
357    /// by name within a class.
358    pub fn devs(&self) -> Vec<Ref<'_, dyn AnyDev>> {
359        let mut devs = self.devs.lock().unwrap().values().map(Arc::clone).collect::<Vec<_>>();
360        devs.sort_by(|a, b| a.class().index().cmp(&b.class().index()).then_with(|| a.name().cmp(b.name())));
361        devs.into_iter().map(Ref::new).collect()
362    }
363
364    /// Get a device of this server from its name.
365    pub fn get_dev(&self, name: &str) -> Option<Ref<'_, dyn AnyDev>> {
366        self.devs.lock().unwrap().get(Name::new(name)).map(|dev| Ref::new(Arc::clone(dev)))
367    }
368
369    /// Stop this server, which is only ever done once: it is unexported as a whole, so
370    /// that clients stop finding it, then its backend is stopped, the requests in flight
371    /// still being answered. The thread waiting on the server then deletes the models, see
372    /// [`ServerHandle::wait`]. No synchronization runs after this, the devices still
373    /// waiting for one never being served.
374    /// 
375    /// This does not wait for the backend, and can therefore be called from anywhere, a
376    /// request handler included, which is what the `Kill` command of the admin device does.
377    /// The backend is stopped even if the server could not be unexported, which is the
378    /// error then given back.
379    pub async fn stop(&self) -> Result<()> {
380
381        let _sync = self.sync_lock.lock().await;
382        if self.stopped.swap(true, Ordering::AcqRel) {
383            return Ok(());
384        }
385
386        info!(server = %self.name(), "Stopping the server");
387
388        let unexported = self.database.unexport_server_async(self.name()).await;
389        if let Err(err) = &unexported {
390            warn!(server = %self.name(), %err, "Failed to unexport the server");
391        }
392
393        if let Some(backend) = self.backend() {
394            backend.stop();
395        }
396
397        self.end_events();
398
399        unexported
400
401    }
402
403    /// Delete the model of every device, the classes in the reverse of their order, the
404    /// admin device last, once the backend holds nothing of them anymore and therefore no
405    /// request runs on any of them. The devices are taken out, so this is only ever done
406    /// once.
407    async fn delete_devs(&self) -> Result<()> {
408
409        let mut devs = mem::take(&mut *self.devs.lock().unwrap())
410            .into_values()
411            .collect::<Vec<_>>();
412        
413        devs.sort_by_key(|dev| std::cmp::Reverse(dev.class().index()));
414        *self.pending.lock().unwrap() = Pending::default();
415
416        let mut first_err = None;
417        for dev in devs {
418            if let Err(err) = dev.withdraw().await {
419                warn!(dev = %dev.name(), %err, "Failed to delete the device");
420                first_err.get_or_insert(err);
421            }
422        }
423
424        first_err.map_or(Ok(()), Err)
425
426    }
427
428    /// Let go of every device and every class, which is what breaks the ownership cycles.
429    /// Nothing is deleted here: the shutdown deletes every model before this.
430    fn clear(&self) {
431        let devs = std::mem::take(&mut *self.devs.lock().unwrap());
432        drop(devs);
433        let classes = std::mem::take(&mut *self.classes.lock().unwrap());
434        drop(classes);
435        // A server dropped without stopping lets go of its subscribers all the same.
436        self.end_events();
437    }
438
439    /// Subscribe to the readings of an attribute of a device, pushed for that event. Nothing
440    /// checks here that the device has the attribute, which is the device's to check.
441    pub(super) fn subscribe_attr_value(&self, dev: &str, attr: &str, event: AttrValueEvent) -> BoxStream<'static, Result<AttrRead<Value>>> {
442        self.subscribe_event(dev, attr, |events| events.values.entry(event).or_default()).boxed()
443    }
444
445    /// Subscribe to an attribute of a device being ready to be read.
446    pub(super) fn subscribe_attr_ready(&self, dev: &str, attr: &str) -> BoxStream<'static, Result<()>> {
447        self.subscribe_event(dev, attr, |events| &mut events.ready).boxed()
448    }
449
450    /// Subscribe to the configuration of an attribute of a device.
451    pub(super) fn subscribe_attr_conf(&self, dev: &str, attr: &str) -> BoxStream<'static, Result<AttrInfo>> {
452        self.subscribe_event(dev, attr, |events| &mut events.conf).boxed()
453    }
454
455    /// Push a reading of an attribute of a device, for that event.
456    pub(super) fn push_attr_value(&self, dev: &str, attr: &str, event: AttrValueEvent, read: Result<AttrRead<Value>>) {
457        self.push_event(dev, attr, |events| events.values.entry(event).or_default(), read);
458    }
459
460    /// Push an attribute of a device being ready to be read.
461    pub(super) fn push_attr_ready(&self, dev: &str, attr: &str, ready: Result<()>) {
462        self.push_event(dev, attr, |events| &mut events.ready, ready);
463    }
464
465    /// Push the configuration of an attribute of a device.
466    pub(super) fn push_attr_conf(&self, dev: &str, attr: &str, info: Result<AttrInfo>) {
467        self.push_event(dev, attr, |events| &mut events.conf, info);
468    }
469
470    fn subscribe_event<T>(&self, dev: &str, attr: &str, select: impl FnOnce(&mut AttrEvents) -> &mut Subscribers<T>) -> EventStream<T> {
471
472        let slot = Arc::new(Slot::new());
473
474        let mut devs = self.events.lock().unwrap();
475        let attrs = devs.entry(ArcName::from(Arc::<str>::from(dev))).or_default();
476        let events = attrs.entry(ArcName::from(Arc::<str>::from(attr))).or_default();
477        let subscribers = select(events);
478        subscribers.retain(|slot| slot.strong_count() != 0);
479        subscribers.push(Arc::downgrade(&slot));
480
481        EventStream {
482            slot,
483            ended: false,
484        }
485
486    }
487
488    fn push_event<T: Clone>(&self, dev: &str, attr: &str, select: impl FnOnce(&mut AttrEvents) -> &mut Subscribers<T>, event: Result<T>) {
489
490        let mut devs = self.events.lock().unwrap();
491        let Some(attrs) = devs.get_mut(Name::new(dev)) else { return };
492        let Some(events) = attrs.get_mut(Name::new(attr)) else { return };
493
494        // Pushed to under the lock, a slot only waking its subscriber.
495        let subscribers = select(events);
496        subscribers.retain(|slot| slot.strong_count() != 0);
497
498        // Each subscriber has its own copy of the event, the last one taking it as it is.
499        if let Some((last, others)) = subscribers.split_last() {
500            
501            for slot in others.iter().filter_map(Weak::upgrade) {
502                slot.push(match &event {
503                    Ok(value) => Ok(value.clone()),
504                    Err(err) => Err(err.duplicate()),
505                });
506            }
507
508            if let Some(slot) = last.upgrade() {
509                slot.push(event);
510            }
511
512        }
513
514        // What is left with no subscriber at all is removed, all the way up.
515        events.values.retain(|_, subscribers| !subscribers.is_empty());
516        if events.values.is_empty() && events.ready.is_empty() && events.conf.is_empty() {
517            attrs.remove(Name::new(attr));
518            if attrs.is_empty() {
519                devs.remove(Name::new(dev));
520            }
521        }
522
523    }
524
525    /// End the subscriptions to the events of that device, which is gone for good.
526    fn end_dev_events(&self, dev: &str) {
527        let attrs = self.events.lock().unwrap().remove(Name::new(dev));
528        for events in attrs.into_iter().flat_map(HashMap::into_values) {
529            events.end();
530        }
531    }
532
533    /// End every subscription, the server having stopped.
534    fn end_events(&self) {
535        let devs = mem::take(&mut *self.events.lock().unwrap());
536        for events in devs.into_values().flat_map(HashMap::into_values) {
537            events.end();
538        }
539    }
540
541}
542
543impl AttrEvents {
544
545    /// End the subscriptions of every subscriber still there.
546    fn end(self) {
547        for subscribers in self.values.into_values() {
548            end_subscribers(subscribers);
549        }
550        end_subscribers(self.ready);
551        end_subscribers(self.conf);
552    }
553
554}
555
556fn end_subscribers<T>(subscribers: Subscribers<T>) {
557    for slot in subscribers.iter().filter_map(Weak::upgrade) {
558        slot.end();
559    }
560}
561
562/// The events of one subscriber, which unsubscribes by being dropped, see [`Subscribers`].
563struct EventStream<T> {
564    slot: Arc<Slot<Result<T>>>,
565    /// Set once the end of the subscription was given.
566    ended: bool,
567}
568
569impl<T> Stream for EventStream<T> {
570
571    type Item = Result<T>;
572
573    fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
574
575        let this = self.get_mut();
576        if this.ended {
577            return Poll::Ready(None);
578        }
579
580        // The end of the slot is given as the end of the subscription, once.
581        this.slot.poll_take(cx).map(|event| event.or_else(|| {
582            this.ended = true;
583            Some(Err(Error::new(ErrorKind::DevNotConnected)
584                .with_append_description("The device is no longer served")))
585        }))
586
587    }
588
589}
590
591/// What a server is built with, and served by, see [`Self::serve`].
592pub struct ServerBuilder {
593    exe: String,
594    inst: String,
595    backend: Option<Arc<dyn Backend>>,
596    database: Option<DatabaseProxy>,
597    /// How the backend serves, see [`Self::host`] and [`Self::port`].
598    config: BackendServerConfig,
599    /// See [`Self::local`].
600    local: bool,
601    /// See [`Self::stop_on_signal`].
602    stop_on_signal: bool,
603    /// The database for testing the server is registered in, which the server owns for
604    /// as long as it runs, see [`ServerHandle`].
605    pub(super) test_context: Option<TestContext>,
606    /// The definitions of the classes of that server, each made a class once the server
607    /// exists, which is only once it is served: a class owns the server it is in. Kept in
608    /// the order they were defined, which is the order their devices are initialized in.
609    classes: Vec<(ArcName, Arc<dyn AnyClassDef>)>,
610}
611
612/// A class definition of any model, which is how a [`ServerBuilder`] holds them.
613trait AnyClassDef: Send + Sync {
614    fn new_class(self: Arc<Self>, server: Arc<Server>, index: usize) -> Arc<dyn AnyClass>;
615}
616
617impl<M: Model> AnyClassDef for ClassDef<M> {
618    fn new_class(self: Arc<Self>, server: Arc<Server>, index: usize) -> Arc<dyn AnyClass> {
619        Class::new(server, self, index)
620    }
621}
622
623impl ServerBuilder {
624
625    /// Build a server named `exe/inst`, after the executable running it and the name of
626    /// the instance of that executable, which is how it is registered in the database.
627    pub fn new(exe: &str, inst: &str) -> Self {
628        Self {
629            exe: exe.to_string(),
630            inst: inst.to_string(),
631            backend: None,
632            database: None,
633            config: BackendServerConfig::default(),
634            local: true,
635            stop_on_signal: true,
636            test_context: None,
637            classes: Vec::new(),
638        }
639    }
640
641    /// The backend to serve with, the default one if none is given, see
642    /// [`default_backend`].
643    pub fn backend(mut self, backend: Arc<dyn Backend>) -> Self {
644        self.backend = Some(backend);
645        self
646    }
647
648    /// The database to register in, the one of the environment if none is given.
649    pub fn database(mut self, database: DatabaseProxy) -> Self {
650        self.database = Some(database);
651        self
652    }
653
654    /// The host to listen at, see [`BackendServerConfig::host`].
655    pub fn host(mut self, host: &str) -> Self {
656        self.config.host = Some(host.to_string());
657        self
658    }
659
660    /// The port to listen at, see [`BackendServerConfig::port`].
661    pub fn port(mut self, port: u16) -> Self {
662        self.config.port = Some(port);
663        self
664    }
665
666    /// Enable or disable registration of the this server's devices into the local 
667    /// registry, which allow [`DevProxy`] created in this same process to access the
668    /// the device directly without going through the backend's wire protocol.
669    pub fn local(mut self, local: bool) -> Self {
670        self.local = local;
671        self
672    }
673
674    /// Define a class in that server, whose devices the database can then list.
675    pub fn class<M: Model>(mut self, def: ClassDef<M>) -> Result<Self> {
676        
677        if def.name.eq_ignore_ascii_case(admin::CLASS_NAME) {
678            return Err(Error::new(ErrorKind::ClassAlreadyDefined)
679                .with_append_description(format_args!("Class {:?} is reserved to the admin device", def.name)));
680        }
681        
682        if self.classes.iter().any(|(name, _)| **name == *Name::new(&def.name)) {
683            return Err(Error::new(ErrorKind::ClassAlreadyDefined)
684                .with_append_description(format_args!("Class {:?}", def.name)));
685        }
686
687        self.classes.push((ArcName::from(Arc::from(&*def.name)), Arc::new(def)));
688        Ok(self)
689
690    }
691
692    /// Stop the server on the signals the process is asked to terminate with, which is the
693    /// default: Ctrl-C, and SIGTERM and SIGHUP on Unix, the console being closed on
694    /// Windows. The server is then stopped as the `Kill` command of its admin device does,
695    /// see [`Server::stop`], and the thread waiting on it deletes its devices, see
696    /// [`ServerHandle::wait`].
697    ///
698    /// There is a single handler of these signals per process, which serving fails to
699    /// install if the application installed one of its own: this is then disabled, and
700    /// the application stops the server itself.
701    pub fn stop_on_signal(mut self, stop_on_signal: bool) -> Self {
702        self.stop_on_signal = stop_on_signal;
703        self
704    }
705
706    /// Start serving: the backend is acquired, every class is made from its definition,
707    /// and the admin device is added and synchronized, which boots the whole server.
708    /// 
709    /// This fails if the admin device fails to initialize, which is what a server that
710    /// cannot reach its database does: it would have nothing to serve.
711    ///
712    /// This blocks, see [`Self::serve_async`] for what does not.
713    pub fn serve(self) -> Result<ServerHandle> {
714        block_on(self.serve_async())
715    }
716
717    /// Serve until the server is stopped, by a signal or the `Kill` command of its admin
718    /// device, then delete its devices: this is [`Self::serve`] then [`ServerHandle::wait`],
719    /// which is all the main thread of most servers does.
720    pub fn run(self) -> Result<()> {
721        block_on(self.run_async())
722    }
723
724    /// Serve until the server is stopped, see [`Self::run`].
725    pub async fn run_async(self) -> Result<()> {
726        self.serve_async().await?.wait_async().await
727    }
728
729    /// Start serving, see [`Self::serve`], resolving once the whole server is booted.
730    pub async fn serve_async(self) -> Result<ServerHandle> {
731
732        // Before anything is served, which a handler that cannot be installed then spares.
733        if self.stop_on_signal {
734            signal::install()?;
735        }
736
737        let backend = self.backend.unwrap_or_else(default_backend);
738        let database = self.database
739            .unwrap_or_else(|| DatabaseProxy::new_from_env_with_backend(Arc::clone(&backend)));
740
741        // The backend names the events of the server after the server and its database,
742        // which is therefore reached before anything is served.
743        let admin_dev_name = Arc::<str>::from(format!("{ADMIN_DEV_PREFIX}{}/{}", self.exe, self.inst));
744        let (tango_host, tango_port) = database.host_and_port_async().await?;
745        let config = self.config.clone()
746            .with_admin_name(Arc::clone(&admin_dev_name))
747            .with_tango_host(tango_host, tango_port);
748
749        let backend = backend.serve(&config).await?;
750
751        let server = Arc::new_cyclic(|this| Server {
752            this: this.clone(),
753            admin_dev_name,
754            database,
755            backend: Arc::downgrade(&backend),
756            classes: Mutex::new(HashMap::new()),
757            class_count: AtomicUsize::new(1 + self.classes.len()),
758            devs: Mutex::new(HashMap::new()),
759            pending: Mutex::new(Pending::default()),
760            sync_lock: async_lock::Mutex::new(()),
761            stopped: AtomicBool::new(false),
762            events: Mutex::new(HashMap::new()),
763            local: self.local,
764        });
765
766        // The admin class is made first, its device being the one booting the others, and
767        // is kept typed, which is what its device is added through.
768        let admin = Class::new(Arc::clone(&server), Arc::new(Admin::def()), 0);
769        let mut classes = HashMap::new();
770        classes.insert(ArcName::from(Arc::from(admin::CLASS_NAME)), Arc::clone(&admin) as Arc<dyn AnyClass>);
771        for (index, (name, def)) in self.classes.into_iter().enumerate() {
772            classes.insert(name, def.new_class(Arc::clone(&server), 1 + index));
773        }
774        *server.classes.lock().unwrap() = classes;
775
776        // From here the server is in a cycle, which the handle breaks if anything fails.
777        let handle = ServerHandle { server, backend, _test_context: self.test_context };
778        let admin_dev = admin.add_dev(handle.server.admin_dev_name())?;
779
780        let booted = match handle.server.sync().await {
781            Ok(()) => admin_dev.check_model().await,
782            Err(err) => Err(err),
783        };
784
785        if let Err(err) = booted {
786            // The admin device may have been exported in FAULT, which is undone here at
787            // best: a server failing to boot usually has no database to tell anything.
788            let _ = handle.server.stop().await;
789            let _ = handle.wait_async().await;
790            return Err(err);
791        }
792
793        drop(admin_dev);
794
795        if self.stop_on_signal {
796            signal::register(&handle.server);
797        }
798
799        info!(server = %handle.server.name(), host = %handle.backend.host(), port = handle.backend.port(),
800            devs = handle.server.devs.lock().unwrap().len() - 1, "Serving");
801        Ok(handle)
802
803    }
804
805}
806
807/// The handle to a server being served, which is what owns it on behalf of its caller.
808///
809/// A server ends by being stopped, see [`Server::stop`], by its owner or by a client
810/// through the `Kill` command of its admin device, and by its handle being waited for,
811/// see [`Self::wait`], which is what deletes its devices. A handle is always waited for:
812/// dropping one drops the server as it stands, with no side effect, see [`Drop`].
813#[derive(Debug)]
814pub struct ServerHandle {
815    server: Arc<Server>,
816    /// The backend serving the server, which only the handle owns, see [`Server::backend`].
817    /// Note that this backend server is co-owning the [`Dev`] instances and so it also
818    /// own the server in the field above.
819    backend: Arc<dyn BackendServer>,
820    /// The database for testing the server is registered in, if any, which is dropped
821    /// after it, the server being unregistered from it once it is waited for.
822    _test_context: Option<TestContext>,
823}
824
825impl ServerHandle {
826
827    #[inline]
828    pub fn server(&self) -> &Server {
829        &self.server
830    }
831
832    /// The server, shared, which does not keep it from being stopped and cleared with this
833    /// handle, see [`Drop`].
834    pub(crate) fn server_arc(&self) -> Arc<Server> {
835        Arc::clone(&self.server)
836    }
837
838    /// Wait for the server to be stopped, see [`Server::stop`], and its devices deleted,
839    /// which is what the thread running a server spends its life in. The first error met
840    /// deleting a model is given back.
841    ///
842    /// This blocks, see [`Self::wait_async`] for what does not, and [`Self::wait_timeout`]
843    /// for a wait that gives up.
844    pub fn wait(&self) -> Result<()> {
845        block_on(self.wait_async())
846    }
847
848    /// Wait for the server to be stopped and its devices deleted, see [`Self::wait`], giving
849    /// up with [`ErrorKind::TimedOut`] if the backend is still answering requests once the
850    /// timeout has run out, which a request that never ends makes it.
851    ///
852    /// The timeout only bounds the backend: once it holds nothing of the devices anymore,
853    /// their models are all deleted, however long that takes. A wait that gave up deletes
854    /// nothing, a request still running being one that may still use its model, and the
855    /// handle is then waited for again, or dropped, which ends everything at once, see
856    /// [`Drop`].
857    pub fn wait_timeout(&self, timeout: Duration) -> Result<()> {
858        block_on_timeout(self.backend.wait(), timeout)
859            .map_err(|err| err.with_append_description(format_args!("Server {} is still answering requests", self.server.name())))?;
860        block_on(self.server.delete_devs())
861    }
862
863    /// Wait for the server to be stopped and its devices deleted, see [`Self::wait`].
864    ///
865    /// The backend is waited for first, after which no request is in flight and it holds
866    /// nothing of the devices anymore, see [`BackendServer::wait`], then the model of every
867    /// device is deleted, in the reverse order of their classes, the admin device last.
868    /// This never runs on the executor of the backend, which it would wait for.
869    pub async fn wait_async(&self) -> Result<()> {
870        self.backend.wait().await;
871        let deleted = self.server.delete_devs().await;
872        info!(server = %self.server.name(), "Stopped the server");
873        deleted
874    }
875
876}
877
878impl Drop for ServerHandle {
879
880    /// Break the ownership cycles of the server, see [`Server::clear`], and drop its
881    /// backend, with no side effect: a server that was not waited for, see
882    /// [`Self::wait`], is not unexported, the requests in flight are not answered, and the
883    /// models are not deleted, see [`BackendServer`].
884    fn drop(&mut self) {
885        self.server.clear();
886    }
887
888}
889
890#[cfg(test)]
891mod tests {
892
893    use futures::executor::block_on;
894    use futures::FutureExt;
895
896    use crate::dev::AttrQuality;
897    use crate::testing::TestContext;
898
899    use super::super::def::ClassDef;
900    use super::*;
901
902
903    /// A server with a device `a/b/c` of a class `A`, served and synchronized.
904    fn serve() -> (TestContext, Arc<Server>) {
905
906        let ctx = TestContext::new().unwrap();
907        ctx.database().add_server("Test/test", &[("a/b/c", "A")]).unwrap();
908
909        let server = ctx.serve(ServerBuilder::new("Test", "test")
910            .class(ClassDef::<()>::new_default("A")).unwrap())
911            .unwrap();
912
913        (ctx, server)
914
915    }
916
917    fn read(value: f64) -> AttrRead<Value> {
918        AttrRead {
919            value: Some(Value::from(value)),
920            w_value: None,
921            quality: AttrQuality::Valid,
922            time: std::time::SystemTime::UNIX_EPOCH + Duration::from_secs(1),
923        }
924    }
925
926    /// The next item of a stream, if there is one already.
927    fn now<T>(stream: &mut BoxStream<'static, T>) -> Option<Option<T>> {
928        stream.next().now_or_never()
929    }
930
931    #[test]
932    fn latest_only() {
933
934        let (_ctx, server) = serve();
935        let mut sub = server.subscribe_attr_value("a/b/c", "Attr", AttrValueEvent::Change);
936
937        assert!(now(&mut sub).is_none());
938
939        server.push_attr_value("a/b/c", "attr", AttrValueEvent::Change, Ok(read(1.0)));
940        server.push_attr_value("A/B/C", "ATTR", AttrValueEvent::Change, Ok(read(2.0)));
941
942        // Another event, or another attribute, reaches nothing.
943        server.push_attr_value("a/b/c", "attr", AttrValueEvent::Archive, Ok(read(3.0)));
944        server.push_attr_value("a/b/c", "other", AttrValueEvent::Change, Ok(read(4.0)));
945
946        assert_eq!(now(&mut sub).unwrap().unwrap().unwrap(), read(2.0));
947        assert!(now(&mut sub).is_none());
948
949    }
950
951    #[test]
952    fn every_subscriber() {
953
954        let (_ctx, server) = serve();
955        let mut first = server.subscribe_attr_value("a/b/c", "attr", AttrValueEvent::Change);
956        let mut second = server.subscribe_attr_value("a/b/c", "attr", AttrValueEvent::Change);
957
958        server.push_attr_value("a/b/c", "attr", AttrValueEvent::Change, Err(Error::new(ErrorKind::Reason(reason::API_AttrNotAllowed))));
959
960        for sub in [&mut first, &mut second] {
961            let err = now(sub).unwrap().unwrap().unwrap_err();
962            assert_eq!(err.kind(), ErrorKind::Reason(reason::API_AttrNotAllowed));
963        }
964
965    }
966
967    #[test]
968    fn unsubscribe() {
969
970        let (_ctx, server) = serve();
971        let sub = server.subscribe_attr_ready("a/b/c", "attr");
972        drop(sub);
973
974        // The push finds nothing to hand the event to, and forgets the attribute.
975        server.push_attr_ready("a/b/c", "attr", Ok(()));
976        assert!(server.events.lock().unwrap().is_empty());
977
978    }
979
980    #[test]
981    fn restart() {
982
983        let (_ctx, server) = serve();
984        let mut sub = server.subscribe_attr_conf("a/b/c", "attr");
985
986        // Removed and added again under the same name, as a restart does.
987        assert!(server.remove_dev("a/b/c"));
988        server.add_dev("A", "a/b/c").unwrap();
989        server.sync_blocking().unwrap();
990        assert!(now(&mut sub).is_none());
991
992        // Removed for good.
993        assert!(server.remove_dev("a/b/c"));
994        server.sync_blocking().unwrap();
995        assert_eq!(now(&mut sub).unwrap().unwrap().unwrap_err().kind(), ErrorKind::DevNotConnected);
996        assert!(now(&mut sub).unwrap().is_none());
997
998    }
999
1000    #[test]
1001    fn stop() {
1002
1003        let (_ctx, server) = serve();
1004        let mut sub = server.subscribe_attr_ready("a/b/c", "attr");
1005
1006        // The event pushed before the end is taken first.
1007        server.push_attr_ready("a/b/c", "attr", Ok(()));
1008        block_on(server.stop()).unwrap();
1009
1010        assert!(now(&mut sub).unwrap().unwrap().is_ok());
1011        assert_eq!(now(&mut sub).unwrap().unwrap().unwrap_err().kind(), ErrorKind::DevNotConnected);
1012        assert!(now(&mut sub).unwrap().is_none());
1013
1014    }
1015
1016    #[test]
1017    fn weak() {
1018
1019        let (_ctx, server) = serve();
1020        let weak = Ref::downgrade(&server.get_dev("a/b/c").unwrap());
1021        assert_eq!(weak.upgrade().unwrap().name(), "a/b/c");
1022
1023        // Restarted under the same name, the weak reference is to the device that was.
1024        assert!(server.remove_dev("a/b/c"));
1025        server.add_dev("A", "a/b/c").unwrap();
1026        server.sync_blocking().unwrap();
1027        assert!(weak.upgrade().is_none());
1028
1029    }
1030
1031    #[test]
1032    fn dropped() {
1033
1034        let (ctx, server) = serve();
1035        let mut sub = server.subscribe_attr_ready("a/b/c", "attr");
1036        drop(ctx);
1037
1038        assert_eq!(block_on(sub.next()).unwrap().unwrap_err().kind(), ErrorKind::DevNotConnected);
1039
1040    }
1041
1042}