Skip to main content

tango/server/
dev.rs

1//! A device: its interface, its model, and every request a client makes of it.
2
3use std::collections::{HashMap, VecDeque};
4use std::sync::{Arc, Mutex, Weak};
5use std::fmt::{self, Debug};
6use std::future::Future;
7use std::borrow::Cow;
8use std::time::SystemTime;
9
10use async_lock::{RwLock, RwLockReadGuard, RwLockWriteGuard};
11use futures::future::{join, ready, BoxFuture};
12use tracing::{debug, error, info};
13use futures::stream::BoxStream;
14
15use crate::dev::{All, AttrConfig, AttrInfo, AttrMemorized, AttrMode, AttrQuality, AttrRead, AttrValueEvent, CommandInfo, DevInfo, Named, NamedResult, ToNames, ToNamesNotAll, 
16    DevSource, DevState, DisplayLevel};
17use crate::value::{CommandDataKind, IntoValue, Scalar, Spectrum, Value};
18use crate::error::{reason, Error, ErrorKind, Result};
19use crate::database::{GetPropSpec, SetPropSpec};
20use crate::local::{self, LocalDevHandle};
21use crate::name::{Name, ArcName};
22use crate::backend::BackendDev;
23use crate::pool;
24
25use super::def::{AttrDef, CommandDef, DeleteFn, InitFn, StateFn, StatusFn, WriteFn};
26use super::{reserved_name, Model, Ref, DEFAULT_STATE, DEFAULT_STATUS, INIT_NAME, 
27    MISSING_STATUS, RESERVED_ATTRS, RESERVED_COMMANDS, STATE_NAME, STATUS_NAME};
28use super::class::{AnyClass, Class};
29use super::attr::{Attr, AttrAlarm};
30use super::command::Command;
31use super::server::Server;
32
33
34/// The model-erased view of a [`Dev`], which is how a server refers to the devices it
35/// serves, whatever the model of the class they belong to.
36pub trait AnyDev: Debug + Send + Sync {
37
38    /// The name of that device.
39    fn name(&self) -> &str;
40
41    /// The class of that device.
42    fn class(&self) -> &dyn AnyClass;
43
44    /// Initialize that device: its model, if it has one, is deleted, and a new one is built
45    /// by the init function of its class, on the pool of the server when that may block.
46    /// This only fails when the initialization never ran to its end, its function having
47    /// panicked: one that failed is kept by the device instead.
48    fn init(&self) -> BoxFuture<'_, Result<()>>;
49
50    /// Stop serving that device, for good, and delete its model, if it has one, giving it
51    /// back to the delete function of its class so that it may release what it owns: what
52    /// a device goes through once it is removed from its server, or when the server shuts
53    /// down. Not to be confused with the deletion of the model alone, which is also what an
54    /// initialization starts with, see [`Dev::init`].
55    /// 
56    /// The backend is told first, so that no new request reaches a device that is being
57    /// deleted, see [`crate::backend::BackendServer::remove`]. A request it was answering
58    /// may still be running, and the model is only deleted once it is through with it,
59    /// which is why a request of that device must never wait for this.
60    fn withdraw(&self) -> BoxFuture<'_, Result<()>>;
61
62    /// Start serving that device through the backend of its server, giving back the ITR it
63    /// is reached at. This is quick and never blocks, see
64    /// [`crate::backend::BackendServer::add`].
65    fn serve(&self) -> Result<Arc<str>>;
66
67}
68
69/// The handle to a device from within its own execution functions, giving access to the
70/// device outside of its model.
71/// 
72/// A device can be served while having no model: until it is initialized, or when its
73/// initialization failed. It is then in UNKNOWN or FAULT state, with a status describing
74/// why it has no model. The idea behind this is that the Init command, that
75/// delete-then-init a device, might fail, however we don't want to stop serving the device
76/// for that. This also allows a server to start if any of its devices fails to init, the
77/// device will be available but it will not be usable in any way, it will just be possible
78/// to call Init and try to fix it, individually from the other devices that might be
79/// running.
80pub struct Dev<M: Model> {
81    /// Self reference, for what a device hands the backend of itself.
82    this: Weak<Self>,
83    /// The name of the device.
84    name: Arc<str>,
85    /// The class this device is an instance of, through which its definition is reached.
86    class: Arc<Class<M>>,
87    /// Mutable state of the device where the commands and attributes definitions with
88    /// polling cache and more are stored.
89    mutable: Mutex<DevMutable<M>>,
90    /// The internal model of the device, absent until the device is initialized.
91    /// 
92    /// An asynchronous lock, held across the awaits of the asynchronous handlers.
93    model: RwLock<Option<Result<M>>>,
94    /// The device recorded as served by this process while it is served, which is how a
95    /// client of this process reaches it directly, see [`crate::local`].
96    local_handle: Mutex<Option<LocalDevHandle>>,
97}
98
99impl<M: Model> Dev<M> {
100
101    pub(super) fn new(class: Arc<Class<M>>, name: Arc<str>) -> Arc<Self> {
102        let state_attr = Arc::new(Attr::new(Arc::clone(&class.def().state_attr)));
103        let status_attr = Arc::new(Attr::new(Arc::clone(&class.def().status_attr)));
104        Arc::new_cyclic(|this| Self {
105            this: this.clone(),
106            name,
107            class,
108            mutable: Mutex::new(DevMutable {
109                black_box: VecDeque::new(),
110                commands: HashMap::new(),
111                attrs: HashMap::new(),
112                state_attr,
113                status_attr,
114                auto_alarm_states: Arc::from([DevState::On]),
115            }),
116            model: RwLock::new(None),
117            local_handle: Mutex::new(None),
118        })
119    }
120
121    #[inline]
122    pub fn name(&self) -> &str {
123        &self.name
124    }
125
126    #[inline]
127    pub fn class(&self) -> &Class<M> {
128        &self.class
129    }
130
131    #[inline]
132    pub fn server(&self) -> &Server {
133        self.class.server()
134    }
135
136    // The properties of a device are the database's: everything below asks the database 
137    // of the server for what it holds of this device, see the very same methods on
138    // [`crate::database::DatabaseProxy`]. The blocking forms are for synchronous handlers, 
139    // which run on the pool, and must never run in an asynchronous one.
140
141    /// The names of the properties of this device that match the given filter.
142    pub async fn list_prop_async(&self, filter: &str) -> Result<Spectrum<str>> {
143        self.server().database().list_dev_prop_async(&self.name, filter).await
144    }
145
146    /// The names of the properties of this device, see [`Self::list_prop_async`].
147    pub fn list_prop(&self, filter: &str) -> Result<Spectrum<str>> {
148        self.server().database().list_dev_prop(&self.name, filter)
149    }
150
151    /// The properties of this device, parsed into the shape the given names ask for, see
152    /// [`crate::database::DatabaseProxy::get_dev_prop`].
153    pub fn get_prop_async<Spec, Names: ToNames>(&self, names: Names) -> impl Future<Output = Result<Spec::Output>> + Send
154    where
155        Spec: GetPropSpec<Names>,
156    {
157        self.server().database().get_dev_prop_async::<Spec, Names>(&self.name, names)
158    }
159
160    /// The properties of this device, see [`Self::get_prop_async`].
161    pub fn get_prop<Spec, Names: ToNames>(&self, names: Names) -> Result<Spec::Output>
162    where
163        Spec: GetPropSpec<Names>,
164    {
165        self.server().database().get_dev_prop::<Spec, Names>(&self.name, names)
166    }
167
168    /// Write the given properties of this device.
169    pub fn set_prop_async<'a, Spec>(&'a self, spec: Spec) -> impl Future<Output = Result<()>> + Send
170    where
171        Spec: SetPropSpec<'a>,
172    {
173        self.server().database().set_dev_prop_async(&self.name, spec)
174    }
175
176    /// Write the given properties of this device, see [`Self::set_prop_async`].
177    pub fn set_prop<'a, Spec>(&'a self, spec: Spec) -> Result<()>
178    where
179        Spec: SetPropSpec<'a>,
180    {
181        self.server().database().set_dev_prop(&self.name, spec)
182    }
183
184    /// Delete the given properties of this device.
185    pub fn del_prop_async<Names: ToNamesNotAll>(&self, names: Names) -> impl Future<Output = Result<()>> + Send {
186        self.server().database().del_dev_prop_async(&self.name, names)
187    }
188
189    /// Delete the given properties of this device, see [`Self::del_prop_async`].
190    pub fn del_prop<Names: ToNamesNotAll>(&self, names: Names) -> Result<()> {
191        self.server().database().del_dev_prop(&self.name, names)
192    }
193
194    /// The device, strongly, for a request to run on the pool with, see [`pool::run`].
195    #[inline]
196    fn arc(&self) -> Arc<Self> {
197        // A device is only ever reached through a reference to it, so it is alive.
198        self.this.upgrade().unwrap()
199    }
200
201    /// Add a command to that device only, from its definition, which is what a device
202    /// whose interface depends on its properties does at initialization; a command every
203    /// device of the class has is defined on the class instead, see [`ClassDef::command`].
204    /// 
205    /// A name the class already defines is refused rather than shadowed: the device was
206    /// given every command of its class before its initialization ran.
207    /// 
208    /// [`ClassDef::command`]: super::def::ClassDef::command
209    pub fn add_command(&self, def: CommandDef<M>) -> Result<()> {
210
211        // Refused rather than panicked on, unlike the same name given to a class, see
212        // [`ClassDef::command`]: what a device adds to itself it usually reads from its
213        // properties, so a reserved name here is a configuration to report, not a
214        // definition to fix.
215        if let Some(reserved) = reserved_name(&def.name, RESERVED_COMMANDS) {
216            return Err(Error::new(ErrorKind::CommandNameInvalid)
217                .with_description(format!("Command {} cannot be defined in the device {}, \
218                    {reserved} is answered by the server itself", def.name, self.name)));
219        }
220
221        let mut mutable = self.mutable.lock().unwrap();
222        if mutable.commands.contains_key(Name::new(&def.name)) {
223            return Err(Error::new(ErrorKind::CommandAlreadyDefined)
224                .with_append_description(format_args!("Command {:?}", def.name)));
225        }
226
227        let name = ArcName::from(Arc::<str>::from(&*def.name));
228        mutable.commands.insert(name, Arc::new(Command::new(Arc::new(def))));
229        Ok(())
230
231    }
232
233    /// Remove a command from that device, telling whether it was defined.
234    pub fn remove_command(&self, name: &str) -> bool {
235        self.mutable.lock().unwrap().commands.remove(Name::new(name)).is_some()
236    }
237
238    /// Add an attribute to that device only, from its definition, see
239    /// [`Self::add_command`] and [`ClassDef::attr`].
240    /// 
241    /// An attribute added by the initialization of the device is configured from the
242    /// database once the initialization returns. One added at any other time keeps the
243    /// configuration of its definition.
244    /// 
245    /// [`ClassDef::attr`]: super::def::ClassDef::attr
246    pub fn add_attr(&self, def: AttrDef<M>) -> Result<()> {
247
248        if let Some(reserved) = reserved_name(&def.name, RESERVED_ATTRS) {
249            return Err(Error::new(ErrorKind::AttrNameInvalid)
250                .with_description(format!("Attribute {} cannot be defined in the device {}, \
251                    {reserved} is answered by the server itself", def.name, self.name)));
252        }
253
254        if let Err(err) = def.check() {
255            return Err(Error::new(ErrorKind::AttrNameInvalid)
256                .with_description(format!("Attribute {} cannot be defined in the device {}, {err}",
257                    def.name, self.name)));
258        }
259
260        let mut mutable = self.mutable.lock().unwrap();
261        if mutable.attrs.contains_key(Name::new(&def.name)) {
262            return Err(Error::new(ErrorKind::AttrAlreadyDefined)
263                .with_append_description(format_args!("Attribute {:?}", def.name)));
264        }
265
266        let name = ArcName::from(Arc::<str>::from(&*def.name));
267        mutable.attrs.insert(name, Arc::new(Attr::new(Arc::new(def))));
268        Ok(())
269
270    }
271
272    /// Give the attribute of that name a new set point without writing it, which every read
273    /// gives back as its write value from then on, and which the database remembers if the
274    /// attribute is memorized, see [`AttrMemorized`].
275    /// 
276    /// This is for a device whose set point changes by itself, a motor stopped short of its
277    /// target for instance, so that a client and the next initialization find the value
278    /// the device actually works towards.
279    pub async fn set_attr_w_value_async(&self, name: &str, value: impl IntoValue) -> Result<()> {
280        let attr = self.find_attr(name)?;
281        attr.set_w_value(self, value.into_value()).await
282    }
283
284    /// Give the attribute of that name a new set point, see [`Self::set_attr_w_value_async`],
285    /// which must therefore never run in an asynchronous handler. Giving up after the
286    /// timeout of the database of the server, which is what it waits for.
287    pub fn set_attr_w_value(&self, name: &str, value: impl IntoValue) -> Result<()> {
288        self.server().database().block_on(self.set_attr_w_value_async(name, value))?
289    }
290
291    /// Change the configuration of the attribute of that name, given as the whole of it,
292    /// which is what a client changing it does: refused if it is incoherent, stored in the
293    /// database, and pushed to the subscribers of the configuration of that attribute. Its
294    /// current configuration is the one [`Attr::config`] gives.
295    pub async fn set_attr_config_async(&self, name: &str, config: &AttrConfig) -> Result<()> {
296        self.change_attr_config(name, config).await
297    }
298
299    /// Change the configuration of the attribute of that name, see
300    /// [`Self::set_attr_config_async`], which must therefore never run in an asynchronous
301    /// handler. Giving up after the timeout of the database of the server, which is what it
302    /// waits for.
303    pub fn set_attr_config(&self, name: &str, config: &AttrConfig) -> Result<()> {
304        self.server().database().block_on(self.set_attr_config_async(name, config))?
305    }
306
307    /// Set the states in which this device is put in ALARM when one of its attributes is in
308    /// alarm, which is only [`DevState::On`] unless set otherwise, an empty list leaving
309    /// the state of the device to its state function alone.
310    /// 
311    /// When the state function gives one of those states, the attributes that have any
312    /// alarm configured are read, and a single one of them in alarm or in warning makes
313    /// the device ALARM, its status telling which and why, the way cppTango does. Getting
314    /// the state of the device then borrows its model the way reading those attributes
315    /// does.
316    pub fn set_auto_alarm_states(&self, states: &[DevState]) {
317        self.mutable.lock().unwrap().auto_alarm_states = Arc::from(states);
318    }
319
320    /// Remove an attribute from that device, telling whether it was defined.
321    pub fn remove_attr(&self, name: &str) -> bool {
322        self.mutable.lock().unwrap().attrs.remove(Name::new(name)).is_some()
323    }
324
325    /// The command of that name on this device, absent when it has none of that name.
326    /// 
327    /// Every request on a command goes through this, and it is borrowed rather than kept:
328    /// the interface store is unlocked as soon as the command is out of it, because a
329    /// handler is free to change the interface of its own device, and that store is the
330    /// lock taken *under* the model, never around it.
331    pub fn get_command(&self, name: &str) -> Option<Ref<'_, Command<M>>> {
332        self.find_command(name).ok().map(Ref::new)
333    }
334
335    /// The attribute of that name on this device, reached the way [`Self::get_command`]
336    /// reaches a command.
337    pub fn get_attr(&self, name: &str) -> Option<Ref<'_, Attr<M>>> {
338        self.find_attr(name).ok().map(Ref::new)
339    }
340
341    /// Every command of the interface of this device.
342    pub fn commands(&self) -> Vec<Ref<'_, Command<M>>> {
343        self.all_commands().into_iter().map(Ref::new).collect()
344    }
345
346    /// Every attribute of the interface of this device.
347    /// 
348    /// TODO: The order is the one of the interface store, which is a hash map and therefore
349    /// arbitrary; a client reading a whole interface expects a stable one.
350    pub fn attrs(&self) -> Vec<Ref<'_, Attr<M>>> {
351        self.all_attrs().into_iter().map(Ref::new).collect()
352    }
353
354    // The events of the attributes of this device are pushed to the subscriptions its
355    // server keeps of them, see [`Server::events`]. A push never blocks and needs no
356    // executor, so that it is made from anywhere, a thread of the device's own included.
357    // Nothing is sent of an event no client subscribed to.
358
359    /// Push an event of that kind for the attribute of that name, the state and the status
360    /// included: a reading, or the error reading it, failing if the device has no such
361    /// attribute, or if that attribute does not declare it pushes such events, see
362    /// [`AttrDef::push_change_event`]. See the methods below for what a device pushes most.
363    ///
364    /// A reading with no write value is given the set point of its attribute, and one with
365    /// a write value makes it the set point, the way a read does, so that an event and a
366    /// read of a writable attribute carry the same, as with cppTango.
367    pub fn push_attr_event(&self, name: &str, event: AttrValueEvent, mut read: Result<AttrRead<Value>>) -> Result<()> {
368        let attr = self.resolve_attr(name)?.into_attr();
369        attr.check_push_event(self, event)?;
370        if let Ok(read) = &mut read {
371            attr.merge_w_value(read);
372        }
373        self.server().push_attr_value(&self.name, attr.name(), event, read);
374        Ok(())
375    }
376
377    /// Push a change event for the attribute of that name, a value of a valid quality read
378    /// now, see [`Self::push_attr_event`].
379    pub fn push_change_event(&self, name: &str, value: impl IntoValue) -> Result<()> {
380        self.push_attr_event(name, AttrValueEvent::Change, Ok(read_now(value)))
381    }
382
383    /// Push an archive event for the attribute of that name, see [`Self::push_change_event`].
384    pub fn push_archive_event(&self, name: &str, value: impl IntoValue) -> Result<()> {
385        self.push_attr_event(name, AttrValueEvent::Archive, Ok(read_now(value)))
386    }
387
388    /// Push a user event for the attribute of that name, see [`Self::push_change_event`].
389    pub fn push_user_event(&self, name: &str, value: impl IntoValue) -> Result<()> {
390        self.push_attr_event(name, AttrValueEvent::User, Ok(read_now(value)))
391    }
392
393    /// Push an alarm event for the attribute of that name, see [`Self::push_change_event`].
394    pub fn push_alarm_event(&self, name: &str, value: impl IntoValue) -> Result<()> {
395        self.push_attr_event(name, AttrValueEvent::Alarm, Ok(read_now(value)))
396    }
397
398    /// Push that the attribute of that name is ready to be read, failing if the device has
399    /// no such attribute.
400    pub fn push_data_ready_event(&self, name: &str) -> Result<()> {
401        let target = self.resolve_attr(name)?;
402        self.server().push_attr_ready(&self.name, target.name(), Ok(()));
403        Ok(())
404    }
405
406    /// Initialize this device by deleting (if previously existing), and init a new model
407    /// for this device.
408    /// 
409    /// If this fails, the error is reported into the model and will later be reported in 
410    /// the device's status and the device will be in FAULT.
411    /// 
412    /// This will usually be called once when the device is first added and after explicit
413    /// synchronization of the server.
414    /// 
415    /// The model is taken exclusively for the whole initialization, so that a request
416    /// arriving in the middle of it waits for it rather than seeing a half built device.
417    /// This is also why the init function of a class must not reach the model of the very
418    /// device it is building: it is that lock it would be asking for.
419    /// 
420    /// The attributes are configured from the database around the init function: those of
421    /// the class before it, so that it finds them configured, and those it added after it,
422    /// see [`Self::load_attr_config`].
423    async fn init(&self) {
424
425        let def = self.class.def();
426        let mut model = self.model.write().await;
427
428        // An initialization is a delete-then-init, which is what the Init command of a
429        // device is: a device that was running is deleted first, and a device whose
430        // previous initialization failed has only that error to drop.
431        self.delete_model(&mut model).await;
432
433        // The interface goes with the model it was built for: whatever the previous
434        // initialization added to this device alone is gone, and the next one is free to
435        // add it again, possibly differently.
436        //
437        // What the class defines is put back, so that the device starts again from the
438        // interface every device of its class has and its initialization only adds to it,
439        // see [`Self::add_attr`].
440        self.reset_interface();
441        self.load_all_attr_config().await;
442
443        let mut res = match &def.init {
444            InitFn::Sync(init) => init(self),
445            InitFn::Async(init) => init(self).await,
446        };
447
448        // We re-load attribute config afterward in case new attributes have been added,
449        // in which case only their config will be loaded. The memorized values are then
450        // written back, which needs the model.
451        if let Ok(new_model) = &mut res {
452            self.load_all_attr_config().await;
453            for attr in self.all_attrs() {
454                attr.restore(self, new_model).await;
455            }
456        }
457
458        // Initialize, we just log the result but keep the error for state/status.
459        *model = Some(match res {
460            Ok(new_model) => {
461                info!(dev = %&*self.name, class = %&*def.name, "Initialized the device");
462                Ok(new_model)
463            }
464            Err(err) => {
465                error!(dev = %&*self.name, class = %&*def.name, %err, "Failed to initialize the device");
466                Err(err)
467            }
468        });
469
470    }
471
472    /// Delete the model of this device, if it has one, giving it back to the delete
473    /// function of its class so that it may release what it owns, taking the model
474    /// already locked so that [`Self::init`] can delete and initialize under a single
475    /// lock.
476    /// 
477    /// The device itself keeps existing, with no model, until it is initialized again:
478    /// every request on it fails until then, but its state and its status still answer,
479    /// see [`Self::state`].
480    async fn delete_model(&self, model: &mut Option<Result<M>>) {
481
482        // Only a model that was actually built is deleted: the error of a failed
483        // initialization is dropped, there being nothing to give back.
484        let Some(Ok(prev)) = model.take() else {
485            return;
486        };
487
488        let def = self.class.def();
489        debug!(dev = %&*self.name, class = %&*def.name, "Deleting the model of the device");
490
491        match &def.delete {
492            Some(DeleteFn::Sync(delete)) => delete(prev, self),
493            Some(DeleteFn::Async(delete)) => delete(prev, self).await,
494            None => {}
495        }
496
497    }
498
499    /// Give this device the interface of its class and nothing else, dropping whatever it
500    /// had added to its own: what a device starts every initialization from, and therefore
501    /// what it has no part of until it is initialized once.
502    fn reset_interface(&self) {
503
504        let def = self.class.def();
505        let mut mutable = self.mutable.lock().unwrap();
506
507        mutable.commands.clear();
508        mutable.attrs.clear();
509        mutable.state_attr = Arc::new(Attr::new(Arc::clone(&def.state_attr)));
510        mutable.status_attr = Arc::new(Attr::new(Arc::clone(&def.status_attr)));
511
512        for def in &def.commands {
513            let name = ArcName::from(Arc::<str>::from(&*def.name));
514            mutable.commands.insert(name, Arc::new(Command::new(Arc::clone(def))));
515        }
516
517        for def in &def.attrs {
518            let name = ArcName::from(Arc::<str>::from(&*def.name));
519            mutable.attrs.insert(name, Arc::new(Attr::new(Arc::clone(def))));
520        }
521
522    }
523
524    /// Configure every attribute of this device that is not yet from what the database holds
525    /// for its class and for this device, both asked at once, see [`Attr::load_config`].
526    /// 
527    /// A request that fails does not fail the device: it is kept as the error of every
528    /// attribute it was for, which a client finds out reading any of them.
529    async fn load_all_attr_config(&self) {
530
531        // Find all attributes that are not yet loaded from the database, the State and the
532        // Status included.
533        let attrs = {
534            let mutable = self.mutable.lock().unwrap();
535            [&mutable.state_attr, &mutable.status_attr]
536                .into_iter()
537                .chain(mutable.attrs.values())
538                .filter(|attr| !attr.is_loaded())
539                .map(Arc::clone)
540                .collect::<Vec<_>>()
541        };
542
543        self.load_given_attr_config(&attrs).await;
544
545    }
546
547    /// Configure those attributes from what the database holds for them, see
548    /// [`Self::load_attr_config`].
549    async fn load_given_attr_config(&self, attrs: &[Arc<Attr<M>>]) {
550
551        if attrs.is_empty() {
552            return;
553        }
554
555        // Now we collect the names of the attributes.
556        let names = attrs
557            .iter()
558            .map(|attr| attr.name())
559            .collect::<Vec<_>>();
560
561        // Waiting on both class attr properties and dev attr properties.
562        let (
563            class_props, 
564            dev_props,
565        ) = join(
566            self.class.attr_props(&names), 
567            self.server()
568                .database()
569                .get_dev_attr_prop_async::<Spectrum<str>, _, _>(&self.name, names.as_slice(), All),
570        ).await;
571
572        let dev_props = dev_props.and_then(|props| props
573                .into_iter()
574                .collect::<Result<Vec<_>>>());
575
576        for (index, attr) in attrs.iter().enumerate() {
577            attr.load_config(self,
578                class_props.as_ref().map(|props| &*props[index]),
579                dev_props.as_ref().map(|props| &*props[index]));
580        }
581
582    }
583
584    /// The state of the device as a client gets it: what the state function of the class
585    /// derives from the model or, for a device that has no model, what the device says of
586    /// itself: the FAULT of a failed initialization, or the UNKNOWN of a device that has
587    /// not been initialized yet.
588    /// 
589    /// Neither of those is an error: a client asking a broken device what is wrong with
590    /// it is answered, the reason itself being in its status, see [`Self::status`].
591    async fn state(&self, ctx: &mut ReadCtx<M>) -> Result<DevState> {
592        let mut guard = self.lock(self.state_access(ctx)).await;
593        match guard.get() {
594            Some(Ok(_)) => self.model_state(&mut guard.model(), ctx).await,
595            Some(Err(_)) => Ok(DevState::Fault),
596            None => Ok(DevState::Unknown),
597        }
598    }
599
600    /// The status of the device, the counterpart of [`Self::state`]: a device that failed
601    /// to initialize gives the error it failed with, which is what keeping that error is
602    /// for, and a device that has not been initialized yet says so.
603    async fn status(&self, ctx: &mut ReadCtx<M>) -> Result<String> {
604        let mut guard = self.lock(self.status_access(ctx)).await;
605        match guard.get() {
606            Some(Ok(_)) => self.model_status(&mut guard.model(), ctx).await,
607            Some(Err(err)) => Ok(make_failed_status(err)),
608            None => Ok(MISSING_STATUS.to_string()),
609        }
610    }
611
612    /// The state of the device derived from its model, which is already borrowed with the
613    /// access [`Self::state_access`] asked for: the half of [`Self::state`] that needs a
614    /// model, so that a request reading the state among other attributes derives it under
615    /// the same borrow as the rest of them.
616    /// 
617    /// The state the state function gives is ALARM when an attribute is in alarm, see
618    /// [`Self::set_auto_alarm_states`].
619    async fn model_state(&self, model: &mut ModelRef<'_, M>, ctx: &mut ReadCtx<M>) -> Result<DevState> {
620        let state = self.model_state_inner(model, ctx).await?;
621        if self.attrs_in_alarm(ctx, state, model, false).await.is_empty() {
622            Ok(state)
623        } else {
624            Ok(DevState::Alarm)
625        }
626    }
627
628    /// The counterpart of [`Self::model_state`] for the status of the device, which tells
629    /// every attribute in alarm after what the status function gives.
630    async fn model_status(&self, model: &mut ModelRef<'_, M>, ctx: &mut ReadCtx<M>) -> Result<String> {
631
632        let mut status = match &self.class.def().status {
633            Some(StatusFn::SharedSync(func)) => func(model.shared(), self).map(Cow::into_owned),
634            Some(StatusFn::ExclusiveSync(func)) => func(model.exclusive()?, self).map(Cow::into_owned),
635            Some(StatusFn::SharedAsync(func)) => func(model.shared(), self).await.map(Cow::into_owned),
636            Some(StatusFn::ExclusiveAsync(func)) => func(model.exclusive()?, self).await.map(Cow::into_owned),
637            None => Ok(DEFAULT_STATUS.to_string()),
638        }?;
639
640        if ctx.has_alarm() {
641            let state = self.model_state_inner(model, ctx).await?;
642            for (attr, alarm) in self.attrs_in_alarm(ctx, state, model, true).await {
643                status.push('\n');
644                status.push_str(&alarm.describe(attr.name()));
645            }
646        }
647
648        Ok(status)
649
650    }
651
652    /// The state the state function of the class gives, see [`Self::model_state`], called
653    /// once for the whole request, see [`ReadCtx::state`].
654    async fn model_state_inner(&self, model: &mut ModelRef<'_, M>, ctx: &mut ReadCtx<M>) -> Result<DevState> {
655
656        if let Some(state) = ctx.state {
657            return Ok(state);
658        }
659
660        let state = match &self.class.def().state {
661            Some(StateFn::SharedSync(func)) => func(model.shared(), self),
662            Some(StateFn::ExclusiveSync(func)) => func(model.exclusive()?, self),
663            Some(StateFn::SharedAsync(func)) => func(model.shared(), self).await,
664            Some(StateFn::ExclusiveAsync(func)) => func(model.exclusive()?, self).await,
665            None => Ok(DEFAULT_STATE),
666        }?;
667
668        ctx.state = Some(state);
669        Ok(state)
670
671    }
672
673    /// The attributes in alarm, with the alarm each is in, when the state function gave
674    /// a state that alarms put the device in ALARM in, see [`Self::set_auto_alarm_states`].
675    /// Only the first is looked for unless every one is asked for.
676    /// 
677    /// An attribute the request already read is not read again, see [`AlarmAttr::read`].
678    async fn attrs_in_alarm(&self, ctx: &mut ReadCtx<M>, state: DevState, model: &mut ModelRef<'_, M>, every: bool) -> Vec<(Arc<Attr<M>>, AttrAlarm)> {
679
680        let mut found = Vec::new();
681        if !ctx.may_alarm(state) {
682            return found;
683        }
684
685        for alarm_attr in ctx.alarm.iter_mut().flat_map(|alarm| &mut alarm.attrs) {
686
687            let alarm = match alarm_attr.read {
688                Some(alarm) => alarm,
689                None => {
690                    
691                    // The attribute hasn't been read in the request, so we read it here
692                    // just to know its alarm state, we ignore the value!
693                    let alarm = alarm_attr.attr.read_with_alarm(self, model).await
694                        .ok()
695                        .and_then(|(_, alarm)| alarm);
696
697                    alarm_attr.read = Some(alarm);
698                    alarm
699                    
700                }
701            };
702
703            if let Some(alarm) = alarm {
704                found.push((Arc::clone(&alarm_attr.attr), alarm));
705                if !every {
706                    break;
707                }
708            }
709
710        }
711
712        found
713
714    }
715
716    /// The access deriving the state of the device needs to its model, which reads the
717    /// attributes that may put it in ALARM as well.
718    fn state_access(&self, ctx: &ReadCtx<M>) -> Access {
719        let access = match &self.class.def().state {
720            Some(StateFn::ExclusiveSync(_) | StateFn::ExclusiveAsync(_)) => Access::Exclusive,
721            _ => Access::Shared,
722        };
723        access.merge(ctx.access())
724    }
725
726    /// The access deriving the status of the device needs to its model, which derives its
727    /// state as well when the attributes may put it in ALARM.
728    fn status_access(&self, ctx: &ReadCtx<M>) -> Access {
729        let access = match &self.class.def().status {
730            Some(StatusFn::ExclusiveSync(_) | StatusFn::ExclusiveAsync(_)) => Access::Exclusive,
731            _ => Access::Shared,
732        };
733        if ctx.has_alarm() { access.merge(self.state_access(ctx)) } else { access }
734    }
735
736    /// Whether initializing this device may block, its init function or its delete
737    /// function being synchronous, see [`pool::run`].
738    /// 
739    /// The memorized values the initialization writes back count too, though only those of
740    /// the attributes of the class are known beforehand.
741    fn init_may_block(&self) -> bool {
742        let def = self.class.def();
743        matches!(def.init, InitFn::Sync(_)) || self.delete_may_block() || def.attrs.iter().any(|attr| {
744            attr.memorized == Some(AttrMemorized::RestoreAndWrite)
745                && matches!(attr.write, Some(WriteFn::SharedSync(_) | WriteFn::ExclusiveSync(_)))
746        })
747    }
748
749    /// Whether deleting the model of this device may block, its delete function being
750    /// synchronous, see [`pool::run`].
751    fn delete_may_block(&self) -> bool {
752        matches!(self.class.def().delete, Some(DeleteFn::Sync(_)))
753    }
754
755    /// Whether deriving the state of this device may block, see [`pool::run`], reading
756    /// the attributes that may put it in ALARM included.
757    fn state_may_block(&self, ctx: &ReadCtx<M>) -> bool {
758        matches!(&self.class.def().state, Some(StateFn::SharedSync(_) | StateFn::ExclusiveSync(_)))
759            || ctx.may_block()
760    }
761
762    /// Whether deriving the status of this device may block, see [`pool::run`], deriving
763    /// its state included when the attributes may put it in ALARM.
764    fn status_may_block(&self, ctx: &ReadCtx<M>) -> bool {
765        matches!(&self.class.def().status, Some(StatusFn::SharedSync(_) | StatusFn::ExclusiveSync(_)))
766            || (ctx.has_alarm() && self.state_may_block(ctx))
767    }
768
769    /// Whether reading that target may block, see [`pool::run`].
770    fn read_may_block(&self, target: &AttrTarget<M>, ctx: &ReadCtx<M>) -> bool {
771        match target {
772            AttrTarget::State(_) => self.state_may_block(ctx),
773            AttrTarget::Status(_) => self.status_may_block(ctx),
774            AttrTarget::Attr(attr) => attr.read_may_block(),
775        }
776    }
777
778    /// Whether executing that target may block, see [`pool::run`].
779    fn command_may_block(&self, target: &CommandTarget<M>, ctx: &ReadCtx<M>) -> bool {
780        match target {
781            CommandTarget::State(_) => self.state_may_block(ctx),
782            CommandTarget::Status(_) => self.status_may_block(ctx),
783            CommandTarget::Init => self.init_may_block(),
784            CommandTarget::Command(command) => command.may_block(),
785        }
786    }
787
788    /// The access reading that target needs to the model.
789    fn read_access(&self, target: &AttrTarget<M>, ctx: &ReadCtx<M>) -> Access {
790        match target {
791            AttrTarget::State(_) => self.state_access(ctx),
792            AttrTarget::Status(_) => self.status_access(ctx),
793            AttrTarget::Attr(attr) => attr.read_access(),
794        }
795    }
796
797    /// Lock the model of this device with the given access, whether it has one or not.
798    async fn lock(&self, access: Access) -> ModelGuard<'_, M> {
799        match access {
800            Access::Shared => ModelGuard::Shared(self.model.read().await),
801            Access::Exclusive => ModelGuard::Exclusive(self.model.write().await),
802        }
803    }
804
805    /// Lock the model of this device with the given access, which is how every request
806    /// that needs the model reaches it.
807    /// 
808    /// A device that has no model fails instead: with the error of its failed
809    /// initialization, so that the caller is told the actual cause, or with
810    /// [`ErrorKind::DevNotConnected`] when it has not been initialized yet.
811    async fn lock_model(&self, access: Access) -> Result<ModelGuard<'_, M>> {
812        let guard = self.lock(access).await;
813        match guard.get() {
814            Some(Ok(_)) => Ok(guard),
815            Some(Err(err)) => Err(init_err(Some(err), &self.name)),
816            None => Err(init_err(None, &self.name)),
817        }
818    }
819
820    /// Fail if this device has no model to serve a request with, with the error saying
821    /// why: what a request that does not itself need the model answers with.
822    pub(super) async fn check_model(&self) -> Result<()> {
823        match &*self.model.read().await {
824            Some(Ok(_)) => Ok(()),
825            Some(Err(err)) => Err(init_err(Some(err), &self.name)),
826            None => Err(init_err(None, &self.name)),
827        }
828    }
829
830    /// The command of that name, owned to run it with the interface store unlocked, and
831    /// the error a client is answered with when the device has no command of that name.
832    fn find_command(&self, name: &str) -> Result<Arc<Command<M>>> {
833        self.mutable.lock().unwrap().commands.get(Name::new(name))
834            .map(Arc::clone)
835            .ok_or_else(|| Error::new(ErrorKind::CommandNotFound)
836                .with_append_description(format_args!("Command {name:?} of the device {:?}", self.name)))
837    }
838
839    /// The counterpart of [`Self::find_command`] for the attributes.
840    fn find_attr(&self, name: &str) -> Result<Arc<Attr<M>>> {
841        self.mutable.lock().unwrap().attrs.get(Name::new(name))
842            .map(Arc::clone)
843            .ok_or_else(|| Error::new(ErrorKind::AttrNotFound)
844                .with_append_description(format_args!("Attribute {name:?} of the device {:?}", self.name)))
845    }
846
847    /// Every command of the interface, owned, see [`Self::find_command`].
848    fn all_commands(&self) -> Vec<Arc<Command<M>>> {
849        self.mutable.lock().unwrap().commands.values().map(Arc::clone).collect()
850    }
851
852    /// Every attribute of the interface, owned, see [`Self::find_attr`].
853    fn all_attrs(&self) -> Vec<Arc<Attr<M>>> {
854        self.mutable.lock().unwrap().attrs.values().map(Arc::clone).collect()
855    }
856
857    /// The State attribute of this device, which holds its configuration, the state itself
858    /// being read through the state function, see [`Self::state`].
859    fn state_attr(&self) -> Arc<Attr<M>> {
860        Arc::clone(&self.mutable.lock().unwrap().state_attr)
861    }
862
863    /// The Status attribute of this device, see [`Self::state_attr`].
864    fn status_attr(&self) -> Arc<Attr<M>> {
865        Arc::clone(&self.mutable.lock().unwrap().status_attr)
866    }
867
868    /// What a name a client asked an attribute of is on this device: the state and the
869    /// status are answered by the device itself, whatever its class defines, and every
870    /// other name is looked up in its interface.
871    fn resolve_attr(&self, name: &str) -> Result<AttrTarget<M>> {
872        if name.eq_ignore_ascii_case(STATE_NAME) {
873            Ok(AttrTarget::State(self.state_attr()))
874        } else if name.eq_ignore_ascii_case(STATUS_NAME) {
875            Ok(AttrTarget::Status(self.status_attr()))
876        } else {
877            self.find_attr(name).map(AttrTarget::Attr)
878        }
879    }
880
881    /// The attribute of that name to write, the two every device has being refused here
882    /// already since neither is writable.
883    fn resolve_writable_attr(&self, name: &str) -> Result<Arc<Attr<M>>> {
884        match self.resolve_attr(name)? {
885            AttrTarget::Attr(attr) => Ok(attr),
886            AttrTarget::State(_) | AttrTarget::Status(_) => Err(not_writable_err(self, name)),
887        }
888    }
889
890    /// What a name a client asked a command of is on this device, the counterpart of
891    /// [`Self::resolve_attr`]: the state, the status and the initialization are the server's
892    /// own, and every other name is looked up in the interface of the device.
893    fn resolve_command(&self, name: &str) -> Result<CommandTarget<M>> {
894        if name.eq_ignore_ascii_case(STATE_NAME) {
895            Ok(CommandTarget::State(self.state_attr()))
896        } else if name.eq_ignore_ascii_case(STATUS_NAME) {
897            Ok(CommandTarget::Status(self.status_attr()))
898        } else if name.eq_ignore_ascii_case(INIT_NAME) {
899            Ok(CommandTarget::Init)
900        } else {
901            self.find_command(name).map(CommandTarget::Command)
902        }
903    }
904
905    /// Every attribute a client asking for none in particular is answered with: the two
906    /// every device has first, then its whole interface.
907    fn all_attr_targets(&self) -> Vec<Resolved<AttrTarget<M>>> {
908        [Ok(AttrTarget::State(self.state_attr())), Ok(AttrTarget::Status(self.status_attr()))]
909            .into_iter()
910            .chain(self.all_attrs().into_iter().map(|attr| Ok(AttrTarget::Attr(attr))))
911            .collect()
912    }
913
914    /// The attributes of the given names, or every one when none is given, resolved before
915    /// the model is borrowed, since resolving one locks the interface store. A name that
916    /// resolves to nothing only fails that one attribute: the others are still answered.
917    fn attr_targets(&self, names: Option<Spectrum<str>>) -> Vec<Resolved<AttrTarget<M>>> {
918        match names {
919            Some(names) => scalars(&names)
920                .map(|name| {
921                    let target = self.resolve_attr(name.value());
922                    resolved(name, target)
923                })
924                .collect(),
925            None => self.all_attr_targets(),
926        }
927    }
928
929    /// The counterpart of [`Self::attr_targets`] for the commands, the three every device
930    /// has coming first.
931    fn command_targets(&self, names: Option<Spectrum<str>>) -> Vec<Resolved<CommandTarget<M>>> {
932        match names {
933            Some(names) => scalars(&names)
934                .map(|name| {
935                    let target = self.resolve_command(name.value());
936                    resolved(name, target)
937                })
938                .collect(),
939            None => [Ok(CommandTarget::State(self.state_attr())), Ok(CommandTarget::Status(self.status_attr())), Ok(CommandTarget::Init)]
940                .into_iter()
941                .chain(self.all_commands().into_iter().map(|command| Ok(CommandTarget::Command(command))))
942                .collect(),
943        }
944    }
945
946    /// Execute a command, resolved beforehand, see [`BackendDev::command`].
947    async fn exec_command(&self, target: Result<CommandTarget<M>>, input: Value, mut ctx: ReadCtx<M>) -> Result<Value> {
948
949        // A device whose initialization failed only has what its class defines, so a name
950        // it does not have may well be one it would have had: its own failure is what a
951        // client needs to hear then, not that the name is unknown.
952        let target = match target {
953            Ok(target) => target,
954            Err(err) => return Err(self.check_model().await.err().unwrap_or(err)),
955        };
956
957        match target {
958            // The three commands every Tango device has, whatever its class, none of them
959            // borrowing the model: the two things the device says of itself, and the one
960            // that rebuilds that model, which could not run while it was borrowed.
961            CommandTarget::State(_) => Ok(self.state(&mut ctx).await?.into()),
962            CommandTarget::Status(_) => Ok(self.status(&mut ctx).await?.into()),
963            CommandTarget::Init => {
964                self.init().await;
965                // An initialization that failed is a failed Init: the device keeps that
966                // error to report it in its status, and the client that asked for the
967                // initialization is given it too.
968                self.check_model().await?;
969                Ok(Value::Void)
970            }
971            CommandTarget::Command(command) => {
972                let mut guard = self.lock_model(command.access()).await?;
973                command.exec(self, &mut guard.model(), input).await
974            }
975        }
976
977    }
978
979    /// Read attributes, resolved beforehand, see [`BackendDev::read_attr`].
980    async fn exec_read_attr(&self, targets: Vec<Resolved<AttrTarget<M>>>, mut ctx: ReadCtx<M>) -> Result<Vec<NamedResult<AttrRead<Value>>>> {
981
982        // They are all read under a single borrow of the model, which is what makes the
983        // values of a multiple read consistent with each other, and that borrow is
984        // exclusive as soon as one of the read functions asks for it.
985        let access = targets.iter()
986            .filter_map(|target| target.as_ref().ok())
987            .fold(Access::Shared, |access, target| access.merge(self.read_access(target, &ctx)));
988
989        let mut guard = self.lock_model(access).await?;
990        let mut model = guard.model();
991
992        // The attributes are read first and the state and the status derived after them, so
993        // that an attribute that may put the device in ALARM is read once, its reading being
994        // what the state is derived from, see [`ReadCtx::record`]. Each is answered where it
995        // was asked for all the same.
996        let mut reads = targets
997            .iter()
998            .map(|_| None)
999            .collect::<Vec<_>>();
1000
1001        for (target, slot) in targets.iter().zip(&mut reads) {
1002            if let Ok(AttrTarget::Attr(attr)) = target {
1003                let read = attr.read_with_alarm(self, &mut model).await;
1004                ctx.record(attr, read.as_ref().ok().and_then(|(_, alarm)| *alarm));
1005                *slot = Some(Named::new(Scalar::from(attr.name()), read.map(|(read, _)| read)));
1006            }
1007        }
1008
1009        for (target, slot) in targets.into_iter().zip(&mut reads) {
1010            *slot = Some(match target {
1011                Ok(AttrTarget::Attr(_)) => continue,
1012                Ok(AttrTarget::State(_)) => Named::new(Scalar::from(STATE_NAME), self.model_state(&mut model, &mut ctx).await
1013                    .map(|state| AttrRead::new(state.into()))),
1014                Ok(AttrTarget::Status(_)) => Named::new(Scalar::from(STATUS_NAME), self.model_status(&mut model, &mut ctx).await
1015                    .map(|status| AttrRead::new(status.into()))),
1016                Err(unresolved) => unresolved.map(Err),
1017            });
1018        }
1019
1020        Ok(reads.into_iter().map(|read| read.expect("every target is read")).collect())
1021
1022    }
1023
1024    /// Write attributes, resolved beforehand, see [`BackendDev::write_attr`].
1025    async fn exec_write_attr(&self, targets: Vec<(Result<Arc<Attr<M>>>, Value)>) -> Result<Vec<Result<()>>> {
1026
1027        // Written under a single borrow of the model, so that a client writing several
1028        // attributes at once has them written together.
1029        let access = targets.iter()
1030            .filter_map(|(target, _)| target.as_ref().ok())
1031            .fold(Access::Shared, |access, attr| access.merge(attr.write_access()));
1032
1033        let mut guard = self.lock_model(access).await?;
1034        let mut model = guard.model();
1035
1036        let mut writes = Vec::with_capacity(targets.len());
1037        for (target, value) in targets {
1038            writes.push(match target {
1039                Ok(attr) => attr.write(self, &mut model, value).await,
1040                Err(err) => Err(err),
1041            });
1042        }
1043
1044        Ok(writes)
1045
1046    }
1047
1048    /// Change the configuration of attributes, each given as the whole configuration it is
1049    /// to have, see [`BackendDev::set_attr_config`].
1050    /// 
1051    /// Every attribute is changed on its own, one failing leaving the others to be changed:
1052    /// on the device first, and then in the database, the way cppTango does.
1053    async fn exec_set_attr_config(&self, configs: Vec<Named<AttrConfig>>) -> Vec<Result<()>> {
1054        let mut results = Vec::with_capacity(configs.len());
1055        for Named { name, value } in configs {
1056            results.push(self.change_attr_config(name.value(), &value).await);
1057        }
1058        results
1059    }
1060
1061    /// Change the configuration of one attribute, see [`Self::exec_set_attr_config`].
1062    /// 
1063    /// A change the database fails to store is the one the device has all the same, until
1064    /// it is configured from the database again, and is therefore pushed all the same.
1065    async fn change_attr_config(&self, name: &str, config: &AttrConfig) -> Result<()> {
1066
1067        let target = self.resolve_attr(name)?;
1068        let attr = target.attr();
1069
1070        let class_props = self.class.attr_props(&[attr.name()]).await?;
1071        let changes = attr.change_config(&class_props[0], config)
1072            .map_err(|err| Error::new(ErrorKind::Reason(reason::API_IncoherentValues))
1073                .with_description(format!("The configuration of the attribute {:?} of the device {:?} \
1074                    cannot be changed: {err}", attr.name(), self.name)))?;
1075
1076        if changes.is_empty() {
1077            return Ok(());
1078        }
1079
1080        self.server().push_attr_conf(&self.name, attr.name(), target.info());
1081
1082        let database = self.server().database();
1083
1084        if !changes.put.is_empty() {
1085            let put = changes.put.into_iter()
1086                .map(|(prop, values)| (prop.name(), values))
1087                .collect::<Vec<_>>();
1088            database.set_dev_attr_prop_async(&self.name, (attr.name(), put)).await?;
1089        }
1090
1091        if !changes.del.is_empty() {
1092            let del = changes.del.iter().map(|prop| prop.name()).collect::<Vec<_>>();
1093            database.del_dev_attr_prop_async(&self.name, attr.name(), del.as_slice()).await?;
1094        }
1095
1096        Ok(())
1097
1098    }
1099
1100    /// Write then read back attributes, resolved beforehand, see
1101    /// [`BackendDev::write_read_attr`].
1102    async fn exec_write_read_attr(&self, targets: Vec<(Resolved<Arc<Attr<M>>>, Value)>) -> Result<Vec<NamedResult<AttrRead<Value>>>> {
1103
1104        // Every value is written and read back under a single borrow of the model, which is
1105        // the whole point of asking for the two together: what a client is given is what the
1106        // device had right after its write, with nothing of anyone else in between.
1107        let access = targets.iter()
1108            .filter_map(|(target, _)| target.as_ref().ok())
1109            .fold(Access::Shared, |access, attr| access.merge(attr.write_access()).merge(attr.read_access()));
1110
1111        let mut guard = self.lock_model(access).await?;
1112        let mut model = guard.model();
1113
1114        let mut reads = Vec::with_capacity(targets.len());
1115        for (target, value) in targets {
1116            reads.push(match target {
1117                // A write that failed is not read back: what a client gets of that
1118                // attribute is the reason its write was refused.
1119                Ok(attr) => {
1120                    let read = match attr.write(self, &mut model, value).await {
1121                        Ok(()) => attr.read(self, &mut model).await,
1122                        Err(err) => Err(err),
1123                    };
1124                    Named::new(Scalar::from(attr.name()), read)
1125                }
1126                Err(unresolved) => unresolved.map(Err),
1127            });
1128        }
1129
1130        Ok(reads)
1131
1132    }
1133}
1134
1135impl<M: Model> AnyDev for Dev<M> {
1136
1137    #[inline]
1138    fn name(&self) -> &str {
1139        &self.name
1140    }
1141
1142    #[inline]
1143    fn class(&self) -> &dyn AnyClass {
1144        &*self.class
1145    }
1146
1147    fn init(&self) -> BoxFuture<'_, Result<()>> {
1148        let dev = self.arc();
1149        pool::run(self.init_may_block(), async move {
1150            dev.init().await;
1151            Ok(())
1152        })
1153    }
1154
1155    fn withdraw(&self) -> BoxFuture<'_, Result<()>> {
1156        let dev = self.arc();
1157        Box::pin(async move {
1158
1159            // Out of reach of the clients of this process first, as of the others next.
1160            dev.local_handle.lock().unwrap().take();
1161            if let Some(backend) = dev.server().backend() {
1162                backend.remove(&dev.name);
1163            }
1164
1165            pool::run(dev.delete_may_block(), async move {
1166                dev.delete_model(&mut *dev.model.write().await).await;
1167                Ok(())
1168            }).await
1169
1170        })
1171    }
1172
1173    fn serve(&self) -> Result<Arc<str>> {
1174        let backend = self.server().served_backend()?;
1175        let dev = DevImpl::from_arc(self.arc()) as Arc<dyn BackendDev>;
1176        let itr = backend.add(&self.name, Arc::clone(&dev))?;
1177        if self.server().local {
1178            let local_handle = local::register(&dev, Arc::clone(&itr), backend.host(), backend.port(), Arc::clone(&self.name));
1179            *self.local_handle.lock().unwrap() = Some(local_handle);
1180        }
1181        Ok(itr)
1182    }
1183
1184}
1185
1186impl<M: Model> Debug for Dev<M> {
1187    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1188        f.debug_struct("Dev").field("name", &self.name).finish_non_exhaustive()
1189    }
1190}
1191
1192/// The interface of a single device, which every device owns its own copy of because it
1193/// can be altered device by device.
1194struct DevMutable<M: Model> {
1195    black_box: VecDeque<String>,
1196    commands: HashMap<ArcName, Arc<Command<M>>>,
1197    attrs: HashMap<ArcName, Arc<Attr<M>>>,
1198    /// The State and the Status of the device, kept out of the interface since every device
1199    /// has them whatever its class, see [`Dev::state_attr`].
1200    state_attr: Arc<Attr<M>>,
1201    status_attr: Arc<Attr<M>>,
1202    /// The states in which the device is put in ALARM when one of its attributes is in
1203    /// alarm, see [`Dev::set_auto_alarm_states`].
1204    auto_alarm_states: Arc<[DevState]>,
1205}
1206
1207/// What a request reading a device learns of it as it goes, so that it reads nothing twice:
1208/// what may put the device in ALARM, along with what the request read of it, and the state
1209/// the state function gave, see [`Dev::set_auto_alarm_states`].
1210struct ReadCtx<M: Model> {
1211    /// What may put the device in ALARM, which only a request involving the state or the
1212    /// status takes, and only when anything may, see [`ReadCtx::new`].
1213    alarm: Option<AlarmCtx<M>>,
1214    /// The state the state function gave, once called, so that the state and the status
1215    /// asked for together call it once.
1216    state: Option<DevState>,
1217}
1218
1219/// What may put a device in ALARM, taken out of the interface store once for a whole
1220/// request, so that what the request borrows the model for and what it reads are the same:
1221/// the states in which the device may be put in ALARM, and the attributes that have any
1222/// alarm configured, by name.
1223struct AlarmCtx<M: Model> {
1224    states: Arc<[DevState]>,
1225    attrs: Vec<AlarmAttr<M>>,
1226}
1227
1228/// An attribute that may put a device in ALARM, see [`AlarmCtx`].
1229struct AlarmAttr<M: Model> {
1230    attr: Arc<Attr<M>>,
1231    /// What the request found reading the attribute, so that it is read only once:
1232    /// - `None`: not read yet;
1233    /// - `Some(None)`: read, and in no alarm, or could not be read;
1234    /// - `Some(Some(alarm))`: read, and in that alarm.
1235    read: Option<Option<AttrAlarm>>,
1236}
1237
1238impl<M: Model> ReadCtx<M> {
1239
1240    /// The context of a request on that device, which takes what may put the device in
1241    /// ALARM out of its interface store only if the request involves its state or its
1242    /// status, and only keeps it if the device has states to be put in ALARM in and
1243    /// attributes that have any alarm configured.
1244    fn new(dev: &Dev<M>, involves_state: bool) -> Self {
1245
1246        let alarm = involves_state.then(|| {
1247
1248            let mutable = dev.mutable.lock().unwrap();
1249            if mutable.auto_alarm_states.is_empty() {
1250                return None;
1251            }
1252
1253            let mut attrs = mutable.attrs.values()
1254                .filter(|attr| attr.has_alarms())
1255                .map(|attr| AlarmAttr {
1256                    attr: Arc::clone(attr),
1257                    read: None,
1258                })
1259                .collect::<Vec<_>>();
1260
1261            if attrs.is_empty() {
1262                return None;
1263            }
1264
1265            attrs.sort_by(|a, b| a.attr.name().cmp(b.attr.name()));
1266            Some(AlarmCtx {
1267                states: Arc::clone(&mutable.auto_alarm_states),
1268                attrs,
1269            })
1270
1271        }).flatten();
1272
1273        Self { 
1274            alarm, 
1275            state: None,
1276        }
1277
1278    }
1279
1280    /// Whether anything may put the device in ALARM, in any state.
1281    fn has_alarm(&self) -> bool {
1282        self.alarm.is_some()
1283    }
1284
1285    /// Whether anything may put the device in ALARM when the state function gave that
1286    /// state, see [`Dev::set_auto_alarm_states`].
1287    fn may_alarm(&self, state: DevState) -> bool {
1288        self.alarm.as_ref().is_some_and(|alarm| alarm.states.contains(&state))
1289    }
1290
1291    /// Keep the alarm the request found that attribute in, if it may put the device in
1292    /// ALARM, so that it is not read again.
1293    fn record(&mut self, attr: &Arc<Attr<M>>, alarm: Option<AttrAlarm>) {
1294        
1295        let alarm_attr = self.alarm.iter_mut()
1296            .flat_map(|alarm| &mut alarm.attrs)
1297            .find(|alarm_attr| Arc::ptr_eq(&alarm_attr.attr, attr));
1298
1299        if let Some(alarm_attr) = alarm_attr {
1300            alarm_attr.read = Some(alarm);
1301        }
1302        
1303    }
1304
1305    /// The access reading the attributes that may put the device in ALARM needs to the
1306    /// model.
1307    fn access(&self) -> Access {
1308        self.alarm.iter()
1309            .flat_map(|alarm| &alarm.attrs)
1310            .fold(Access::Shared, |access, alarm_attr| access.merge(alarm_attr.attr.read_access()))
1311    }
1312
1313    /// Whether reading the attributes that may put the device in ALARM may block, see
1314    /// [`pool::run`].
1315    fn may_block(&self) -> bool {
1316        self.alarm.iter()
1317            .flat_map(|alarm| &alarm.attrs)
1318            .any(|alarm_attr| alarm_attr.attr.read_may_block())
1319    }
1320
1321}
1322
1323/// What a name a client asked an attribute of resolves to on a device: one of the two
1324/// attributes every Tango device has, whatever its class defines, or an attribute of its
1325/// interface, taken out of the interface store so that it is read with the store unlocked.
1326enum AttrTarget<M: Model> {
1327    State(Arc<Attr<M>>),
1328    Status(Arc<Attr<M>>),
1329    Attr(Arc<Attr<M>>),
1330}
1331
1332impl<M: Model> AttrTarget<M> {
1333
1334    /// Whether the request may have to derive the state of the device for that target,
1335    /// see [`ReadCtx::new`].
1336    fn involves_state(&self) -> bool {
1337        matches!(self, Self::State(_) | Self::Status(_))
1338    }
1339
1340    /// The attribute of the device that target is, see [`Self::into_attr`].
1341    fn attr(&self) -> &Arc<Attr<M>> {
1342        match self {
1343            Self::State(attr) | 
1344            Self::Status(attr) | 
1345            Self::Attr(attr) => attr,
1346        }
1347    }
1348
1349    /// The attribute of the device that target is, which holds its configuration.
1350    fn into_attr(self) -> Arc<Attr<M>> {
1351        match self {
1352            Self::State(attr) | 
1353            Self::Status(attr) | 
1354            Self::Attr(attr) => attr,
1355        }
1356    }
1357
1358    /// What that attribute is named, which the entries answered for it are named by.
1359    fn name(&self) -> &str {
1360        match self {
1361            Self::State(attr) | 
1362            Self::Status(attr) | 
1363            Self::Attr(attr) => attr.name(),
1364        }
1365    }
1366
1367    /// What a client is told of that attribute, the two every device has being read-only
1368    /// whatever their definitions, see [`Attr::info_as`].
1369    fn info(&self) -> Result<AttrInfo> {
1370        match self {
1371            Self::State(attr) | 
1372            Self::Status(attr) => attr.info_as(AttrMode::Read),
1373            Self::Attr(attr) => attr.info(),
1374        }
1375    }
1376
1377}
1378
1379/// What a name a client asked a command of resolves to on a device, the counterpart of
1380/// [`AttrTarget`] for the commands: the three every Tango device has, whatever its class, or a
1381/// command of its interface.
1382enum CommandTarget<M: Model> {
1383    State(Arc<Attr<M>>),
1384    Status(Arc<Attr<M>>),
1385    Init,
1386    Command(Arc<Command<M>>),
1387}
1388
1389impl<M: Model> CommandTarget<M> {
1390
1391    /// Whether the request may have to derive the state of the device for that target,
1392    /// see [`ReadCtx::new`].
1393    fn involves_state(&self) -> bool {
1394        matches!(self, Self::State(_) | Self::Status(_))
1395    }
1396
1397    /// What that command is named, which the entries answered for it are named by.
1398    fn name(&self) -> &str {
1399        match self {
1400            Self::State(attr) | 
1401            Self::Status(attr) => attr.name(),
1402            Self::Init => INIT_NAME,
1403            Self::Command(command) => command.name(),
1404        }
1405    }
1406
1407    /// What a client is told of that command, the three every device has being described by
1408    /// the server itself.
1409    fn info(&self) -> CommandInfo {
1410        match self {
1411            Self::State(_) => CommandInfo {
1412                display_level: DisplayLevel::Operator,
1413                in_kind: CommandDataKind::Void,
1414                out_kind: CommandDataKind::State,
1415                in_doc: None,
1416                out_doc: Some(Cow::Borrowed("The state of the device")),
1417            },
1418            Self::Status(_) => CommandInfo {
1419                display_level: DisplayLevel::Operator,
1420                in_kind: CommandDataKind::Void,
1421                out_kind: CommandDataKind::String,
1422                in_doc: None,
1423                out_doc: Some(Cow::Borrowed("The status of the device")),
1424            },
1425            Self::Init => CommandInfo {
1426                display_level: DisplayLevel::Operator,
1427                in_kind: CommandDataKind::Void,
1428                out_kind: CommandDataKind::Void,
1429                in_doc: None,
1430                out_doc: None,
1431            },
1432            Self::Command(command) => command.info(),
1433        }
1434    }
1435
1436}
1437
1438/// The error writing one of the two attributes every device has fails with: they are what
1439/// the device says of itself, not something a client tells it.
1440/// A reading of a value of a valid quality, made now, which is what a device pushes most.
1441fn read_now(value: impl IntoValue) -> AttrRead<Value> {
1442    AttrRead {
1443        value: Some(value.into_value()),
1444        w_value: None,
1445        quality: AttrQuality::Valid,
1446        time: SystemTime::now(),
1447    }
1448}
1449
1450fn not_writable_err<M: Model>(dev: &Dev<M>, name: &str) -> Error {
1451    Error::new(ErrorKind::AttrNotWritable)
1452        .with_append_description(format_args!("Attribute {name:?} of the device {:?}",
1453            dev.name()))
1454}
1455
1456/// Refuse to answer a request from the polling buffer, there being none: a client asking
1457/// for the cache alone is told that nothing is polled, and one that accepts both the cache
1458/// and the device is served by the device itself.
1459/// 
1460/// TODO: Answer from the polling buffer, once the server polls.
1461fn check_polled(source: DevSource, what: fmt::Arguments<'_>) -> Result<()> {
1462    match source {
1463        DevSource::Dev | DevSource::CacheDev => Ok(()),
1464        DevSource::Cache => Err(Error::new(ErrorKind::Reason(reason::API_DeviceNotPolled))
1465            .with_description(format!("Cannot answer from the polling cache, this server \
1466                polls nothing yet ({what})"))),
1467    }
1468}
1469
1470/// The access a request needs to the model of a device: shared when every handler it runs
1471/// takes the model by reference, so that such requests run in parallel, and exclusive as
1472/// soon as one of them takes it mutably.
1473#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1474pub enum Access {
1475    Shared,
1476    Exclusive,
1477}
1478
1479impl Access {
1480
1481    /// The access covering both, which is exclusive as soon as either is: a request
1482    /// touching several attributes at once borrows the model once, for what the most
1483    /// demanding of its handlers needs.
1484    pub fn merge(self, other: Self) -> Self {
1485        match (self, other) {
1486            (Self::Shared, Self::Shared) => Self::Shared,
1487            _ => Self::Exclusive,
1488        }
1489    }
1490
1491}
1492
1493/// The lock of the model of a device, held for the duration of a request with the access
1494/// that request asked for.
1495pub enum ModelGuard<'a, M> {
1496    Shared(RwLockReadGuard<'a, Option<Result<M>>>),
1497    Exclusive(RwLockWriteGuard<'a, Option<Result<M>>>),
1498}
1499
1500impl<M> ModelGuard<'_, M> {
1501
1502    /// The model of the device if it has one, or the error of its failed initialization.
1503    #[inline]
1504    fn get(&self) -> &Option<Result<M>> {
1505        match self {
1506            Self::Shared(guard) => guard,
1507            Self::Exclusive(guard) => guard,
1508        }
1509    }
1510
1511    /// The model, borrowed with the access the lock was taken with.
1512    /// 
1513    /// # Panics
1514    /// 
1515    /// If the device has no model, which [`Dev::lock_model`] checks beforehand.
1516    fn model(&mut self) -> ModelRef<'_, M> {
1517        match self {
1518            Self::Shared(guard) => match &**guard {
1519                Some(Ok(model)) => ModelRef::Shared(model),
1520                _ => panic!("the device has no model"),
1521            }
1522            Self::Exclusive(guard) => match &mut **guard {
1523                Some(Ok(model)) => ModelRef::Exclusive(model),
1524                _ => panic!("the device has no model"),
1525            }
1526        }
1527    }
1528
1529}
1530
1531/// The model of a device, borrowed for the duration of a request with the access that
1532/// request asked for, which is what lets every handler of a single request run under one
1533/// borrow of the model.
1534pub enum ModelRef<'m, M> {
1535    Shared(&'m M),
1536    Exclusive(&'m mut M),
1537}
1538
1539impl<M> ModelRef<'_, M> {
1540
1541    /// The model, shared, which either access gives.
1542    #[inline]
1543    pub fn shared(&self) -> &M {
1544        match self {
1545            Self::Shared(model) => model,
1546            Self::Exclusive(model) => model,
1547        }
1548    }
1549
1550    /// The model, exclusively, which only an exclusive access gives.
1551    /// 
1552    /// Failing here is a bug of the server and not of the device: the access is computed
1553    /// from the very handlers the request then runs, see [`Access::merge`], so a handler
1554    /// asking for the model mutably has been counted before it is called.
1555    #[inline]
1556    pub fn exclusive(&mut self) -> Result<&mut M> {
1557        match self {
1558            Self::Exclusive(model) => Ok(model),
1559            Self::Shared(_) => Err(Error::new(ErrorKind::Internal)
1560                .with_description("The model was borrowed shared while a handler of that \
1561                    request needs it exclusively")),
1562        }
1563    }
1564
1565}
1566
1567/// The status of a device whose initialization failed: the error it failed with, which is
1568/// what a client reads to know why the device is not running.
1569fn make_failed_status(err: &Error) -> String {
1570    format!("The initialization of the device failed:\n{err}")
1571}
1572
1573/// The error every request on a device that has no model fails with, given the error
1574/// its initialization failed with, if it failed at all.
1575fn init_err(failure: Option<&Error>, name: &str) -> Error {
1576    match failure {
1577        Some(err) => Error::new(ErrorKind::DevInitFailed)
1578            .with_append_description(format_args!("Device {name:?}"))
1579            .with_append_description(err),
1580        None => Error::new(ErrorKind::DevNotConnected)
1581            .with_description(format!("The device {name} is not initialized")),
1582    }
1583}
1584
1585/// The documentation of a definition as a client is told it, an empty one being none.
1586pub fn some_doc(doc: &Cow<'static, str>) -> Option<Cow<'static, str>> {
1587    (!doc.is_empty()).then(|| doc.clone())
1588}
1589
1590// =================== //
1591//   Device backend    //
1592// =================== //
1593
1594/// The backend of a device, which is the device itself seen through a transparent wrapper,
1595/// so that the backend methods are not methods of [`Dev`] itself. The backend serving a
1596/// device holds it as such, and a proxy made in this process to a device of this server
1597/// could talk to it directly, without going through any protocol.
1598#[repr(transparent)]
1599struct DevImpl<M: Model>(Dev<M>);
1600
1601impl<M: Model> DevImpl<M> {
1602
1603    /// See a device as its backend.
1604    #[inline]
1605    fn from_arc(dev: Arc<Dev<M>>) -> Arc<Self> {
1606        // SAFETY: DevImpl is a repr(transparent) wrapper around Dev, so both have the same
1607        // layout and an Arc of one is an Arc of the other.
1608        unsafe { Arc::from_raw(Arc::into_raw(dev) as *const Self) }
1609    }
1610
1611}
1612
1613impl<M: Model> Debug for DevImpl<M> {
1614    #[inline]
1615    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1616        Debug::fmt(&self.0, f)
1617    }
1618}
1619
1620/// What touches the model is run on the pool of the server when one of the handlers it
1621/// runs may block, and polled by the executor of the backend otherwise, see [`pool::run`];
1622/// what only reads the definitions and the interface is answered on the call itself.
1623impl<M: Model> BackendDev for DevImpl<M> {
1624
1625    fn name(&self) -> BoxFuture<'_, Result<Arc<str>>> {
1626        Box::pin(ready(Ok(Arc::clone(&self.0.name))))
1627    }
1628
1629    fn admin_dev_name(&self) -> BoxFuture<'_, Result<Arc<str>>> {
1630        Box::pin(ready(Ok(Arc::clone(&self.0.server().admin_dev_name))))
1631    }
1632
1633    fn description(&self) -> BoxFuture<'_, Result<Arc<str>>> {
1634        Box::pin(ready(Ok(Arc::from(&*self.0.class.def().doc))))
1635    }
1636
1637    /// None of this is the device's own: the class it is an instance of, and the server
1638    /// running it, are what a client is told here, so all of it is read off the definition
1639    /// of its class and off the server it belongs to.
1640    fn info(&self) -> BoxFuture<'_, Result<DevInfo>> {
1641        let def = self.0.class.def();
1642        let server = self.0.server();
1643        let backend = match server.served_backend() {
1644            Ok(backend) => backend,
1645            Err(err) => return Box::pin(ready(Err(err))),
1646        };
1647        Box::pin(ready(Ok(DevInfo {
1648            class: def.name.to_string(),
1649            server_id: server.name().to_string(),
1650            server_host: backend.host().to_string(),
1651            server_version: backend.version(),
1652            doc_url: def.doc_url.clone(),
1653            // The description of the class, this crate having the one string where Tango
1654            // has two: what the device *is* and what it says of itself are the same here.
1655            dev_type: Some(def.doc.clone()),
1656            version_info: vec![
1657                (Cow::Borrowed("rstango"), Cow::Borrowed(env!("CARGO_PKG_VERSION"))),
1658            ],
1659        })))
1660    }
1661
1662    fn ping(&self) -> BoxFuture<'_, Result<()>> {
1663        Box::pin(ready(Ok(())))
1664    }
1665
1666    fn state(&self) -> BoxFuture<'_, Result<DevState>> {
1667        let dev = self.0.arc();
1668        let mut ctx = ReadCtx::new(&dev, true);
1669        pool::run(dev.state_may_block(&ctx), async move { dev.state(&mut ctx).await })
1670    }
1671
1672    fn status(&self) -> BoxFuture<'_, Result<String>> {
1673        let dev = self.0.arc();
1674        let mut ctx = ReadCtx::new(&dev, true);
1675        pool::run(dev.status_may_block(&ctx), async move { dev.status(&mut ctx).await })
1676    }
1677
1678    fn black_box(&self, max: Option<usize>) -> BoxFuture<'_, Result<Vec<String>>> {
1679
1680        let mutable = self.0.mutable.lock().unwrap();
1681        let black_box = mutable.black_box.iter()
1682            .take(max.unwrap_or(usize::MAX))
1683            .cloned()
1684            .collect();
1685
1686        Box::pin(ready(Ok(black_box)))
1687
1688    }
1689
1690    fn command(&self, name: Scalar<str>, input: Value, source: DevSource) -> BoxFuture<'_, Result<Value>> {
1691        
1692        if let Err(err) = check_polled(source, format_args!("the command {} of the device {}", name.value(), self.0.name)) {
1693            return Box::pin(ready(Err(err)));
1694        }
1695
1696        let dev = self.0.arc();
1697        let target = dev.resolve_command(name.value());
1698        let ctx = ReadCtx::new(&dev, target.as_ref().is_ok_and(CommandTarget::involves_state));
1699
1700        let blocking = target.as_ref().is_ok_and(|target| dev.command_may_block(target, &ctx));
1701        pool::run(blocking, async move {
1702            let res = dev.exec_command(target, input, ctx).await;
1703            if let Err(err) = &res {
1704                debug!(dev = %&*dev.name, command = %name.value(), %err, "Failed to execute the command");
1705            }
1706            res
1707        })
1708
1709    }
1710
1711    fn read_attr(&self, names: Option<Spectrum<str>>, source: DevSource) -> BoxFuture<'_, Result<Vec<NamedResult<AttrRead<Value>>>>> {
1712        
1713        if let Err(err) = check_polled(source, format_args!("the attributes of the device {}", self.0.name)) {
1714            return Box::pin(ready(Err(err)));
1715        }
1716
1717        let dev = self.0.arc();
1718        let targets = dev.attr_targets(names);
1719        let ctx = ReadCtx::new(&dev, targets.iter().flatten().any(AttrTarget::involves_state));
1720
1721        let blocking = targets.iter().flatten().any(|target| dev.read_may_block(target, &ctx));
1722        pool::run(blocking, async move { dev.exec_read_attr(targets, ctx).await })
1723
1724    }
1725
1726    fn write_attr(&self, values: Vec<Named<Value>>) -> BoxFuture<'_, Result<Vec<Result<()>>>> {
1727        
1728        let dev = self.0.arc();
1729        let targets = values.into_iter()
1730            .map(|write| (dev.resolve_writable_attr(write.name.value()), write.value))
1731            .collect::<Vec<_>>();
1732        
1733        let blocking = targets.iter()
1734            .filter_map(|(target, _)| target.as_ref().ok())
1735            .any(|attr| attr.write_may_block());
1736        pool::run(blocking, async move { dev.exec_write_attr(targets).await })
1737        
1738    }
1739
1740    fn write_read_attr(&self, values: Vec<Named<Value>>) -> BoxFuture<'_, Result<Vec<NamedResult<AttrRead<Value>>>>> {
1741        
1742        let dev = self.0.arc();
1743        let targets = values.into_iter()
1744            .map(|write| {
1745                let target = dev.resolve_writable_attr(write.name.value());
1746                (resolved(write.name, target), write.value)
1747            })
1748            .collect::<Vec<_>>();
1749        
1750        let blocking = targets.iter()
1751            .filter_map(|(target, _)| target.as_ref().ok())
1752            .any(|attr| attr.write_may_block() || attr.read_may_block());
1753        pool::run(blocking, async move { dev.exec_write_read_attr(targets).await })
1754
1755    }
1756
1757    /// The definitions and nothing else, so this borrows no model: a device that failed to
1758    /// initialize still describes the interface of its class, which is how a client knows
1759    /// to ask it for the state and the status that say it failed.
1760    fn command_info(&self, names: Option<Spectrum<str>>) -> BoxFuture<'_, Result<Vec<NamedResult<CommandInfo>>>> {
1761        
1762        let infos = self.0.command_targets(names).into_iter()
1763            .map(|target| match target {
1764                Ok(target) => Named::new(Scalar::from(target.name()), Ok(target.info())),
1765                Err(unresolved) => unresolved.map(Err),
1766            })
1767            .collect();
1768        
1769        Box::pin(ready(Ok(infos)))
1770
1771    }
1772
1773    fn attr_info(&self, names: Option<Spectrum<str>>) -> BoxFuture<'_, Result<Vec<NamedResult<AttrInfo>>>> {
1774        
1775        let infos = self.0.attr_targets(names).into_iter()
1776            .map(|target| match target {
1777                Ok(target) => Named::new(Scalar::from(target.name()), target.info()),
1778                Err(unresolved) => unresolved.map(Err),
1779            })
1780            .collect();
1781
1782        Box::pin(ready(Ok(infos)))
1783
1784    }
1785
1786    /// The counterpart of [`Self::command_info`], and the same absence of any model.
1787    fn set_attr_config(&self, configs: Vec<Named<AttrConfig>>) -> BoxFuture<'_, Result<Vec<Result<()>>>> {
1788        Box::pin(async move { Ok(self.0.exec_set_attr_config(configs).await) })
1789    }
1790
1791    fn command_history<'a>(&'a self, _name: &'a str, _max: usize) -> BoxFuture<'a, Result<Vec<(SystemTime, Result<Value>)>>> {
1792        Box::pin(ready(Err(Error::not_implemented()
1793            .with_append_description("The recorded history of a command"))))
1794    }
1795
1796    fn attr_history<'a>(&'a self, _name: &'a str, _max: usize) -> BoxFuture<'a, Result<Vec<Result<AttrRead<Value>>>>> {
1797        Box::pin(ready(Err(Error::not_implemented()
1798            .with_append_description("The recorded history of an attribute"))))
1799    }
1800
1801    // The subscriptions are the server's, which keeps them for as long as the device is
1802    // served under that name, see [`Server::events`]. Only an attribute the device has can
1803    // be subscribed to, the state and the status included, as cppTango allows, and only to
1804    // an event something sends, see [`Attr::check_push_event`].
1805
1806    fn subscribe_attr_value<'a>(&'a self, _admin: Arc<dyn BackendDev>, name: &'a str, event: AttrValueEvent) -> BoxFuture<'a, Result<BoxStream<'static, Result<AttrRead<Value>>>>> {
1807        Box::pin(ready(self.0.resolve_attr(name).and_then(|target| {
1808            target.attr().check_push_event(&self.0, event)?;
1809            Ok(self.0.server().subscribe_attr_value(&self.0.name, target.name(), event))
1810        })))
1811    }
1812
1813    fn subscribe_attr_ready<'a>(&'a self, _admin: Arc<dyn BackendDev>, name: &'a str) -> BoxFuture<'a, Result<BoxStream<'static, Result<()>>>> {
1814        Box::pin(ready(self.0.resolve_attr(name).map(|target| {
1815            self.0.server().subscribe_attr_ready(&self.0.name, target.name())
1816        })))
1817    }
1818
1819    fn subscribe_attr_conf<'a>(&'a self, _admin: Arc<dyn BackendDev>, name: &'a str) -> BoxFuture<'a, Result<BoxStream<'static, Result<AttrInfo>>>> {
1820        Box::pin(ready(self.0.resolve_attr(name).map(|target| {
1821            self.0.server().subscribe_attr_conf(&self.0.name, target.name())
1822        })))
1823    }
1824
1825}
1826
1827/// What a name a request gave resolved to, which names itself, or the name itself when it
1828/// resolved to nothing, along with the reason: the very name the request gave then.
1829type Resolved<T> = std::result::Result<T, Named<Error>>;
1830
1831fn resolved<T>(name: Scalar<str>, res: Result<T>) -> Resolved<T> {
1832    res.map_err(|err| Named::new(name, err))
1833}
1834
1835/// Every name a request gave, each a scalar of its own sharing them.
1836fn scalars(names: &Spectrum<str>) -> impl Iterator<Item = Scalar<str>> + '_ {
1837    (0..names.len()).map(|index| names.get_scalar([index]).expect("a name at every index"))
1838}
1839
1840
1841#[cfg(test)]
1842mod tests {
1843
1844    use std::sync::Mutex;
1845    use std::thread;
1846
1847    use futures::channel::oneshot;
1848    use futures::executor::block_on;
1849    use futures::{FutureExt, StreamExt};
1850
1851    use crate::dev::{ToNames, WriteAttrSpec};
1852    use crate::value::FromValue;
1853
1854    use super::*;
1855    use super::super::def::{AttrDef, ClassDef, CommandDef};
1856    use super::super::server::ServerBuilder;
1857    use crate::testing::TestContext;
1858
1859    /// A server with a single device of that class, which is added but not synchronized
1860    /// yet, on a database listing no other device, the server being served by the context.
1861    fn serve<M: Model>(def: ClassDef<M>) -> (TestContext, Arc<DevImpl<M>>) {
1862        let ctx = TestContext::new().unwrap();
1863        ctx.database().add_server("Test/test", &[]).unwrap();
1864        ctx.database().add_dev("test/dev/1", &def.name, "Test/test").unwrap();
1865        let server = ctx.serve(ServerBuilder::new("Test", "test")).unwrap();
1866        let class = server.add_class(def).unwrap();
1867        let dev = class.add_dev("test/dev/1").unwrap();
1868        let dev = DevImpl::from_arc(Arc::clone(&dev.inner));
1869        drop(class);
1870        (ctx, dev)
1871    }
1872
1873    #[test]
1874    fn push_event() {
1875
1876        let (ctx, dev) = serve(model_def());
1877        let server = ctx.server("Test/test").unwrap();
1878        server.sync_blocking().unwrap();
1879        let mut state = server.subscribe_attr_value("test/dev/1", "State", AttrValueEvent::Change);
1880        let mut count = server.subscribe_attr_value("test/dev/1", "Count", AttrValueEvent::Change);
1881
1882        thread::scope(|scope| {
1883            scope.spawn(|| dev.0.push_change_event("state", DevState::Moving).unwrap());
1884        });
1885
1886        let read = block_on(state.next()).unwrap().unwrap();
1887        assert_eq!(read.value, Some(Value::from(DevState::Moving)));
1888        assert_eq!(read.w_value, None);
1889        assert_eq!(read.quality, AttrQuality::Valid);
1890
1891        // A writable attribute is pushed with its set point, as it is read.
1892        dev.0.set_attr_w_value("Count", 5).unwrap();
1893        dev.0.push_change_event("Count", 3).unwrap();
1894        let read = block_on(count.next()).unwrap().unwrap();
1895        assert_eq!(read.value, Some(Value::from(3)));
1896        assert_eq!(read.w_value, Some(Value::from(5)));
1897
1898        assert!(dev.0.push_change_event("Missing", 1.0).is_err());
1899
1900        // An event the attribute does not declare it pushes is refused.
1901        let err = dev.0.push_archive_event("Count", 3).unwrap_err();
1902        assert_eq!(err.kind(), ErrorKind::Reason(reason::API_AttributePollingNotStarted));
1903        dev.0.push_user_event("Count", 3).unwrap();
1904
1905    }
1906
1907    #[test]
1908    fn set_attr_config() {
1909
1910        let (ctx, dev) = serve(model_def());
1911        let server = ctx.server("Test/test").unwrap();
1912        server.sync_blocking().unwrap();
1913        let mut conf = server.subscribe_attr_conf("test/dev/1", "Count");
1914
1915        let mut config = dev.0.get_attr("Count").unwrap().config();
1916        config.label = Some("Counter".into());
1917        dev.0.set_attr_config("count", &config).unwrap();
1918
1919        assert_eq!(dev.0.get_attr("Count").unwrap().config().label.as_deref(), Some("Counter"));
1920        let info = block_on(conf.next()).unwrap().unwrap();
1921        assert_eq!(info.config.label.as_deref(), Some("Counter"));
1922
1923        // Nothing changed, nothing pushed.
1924        dev.0.set_attr_config("Count", &config).unwrap();
1925        assert!(conf.next().now_or_never().is_none());
1926
1927    }
1928
1929    fn thread_name() -> String {
1930        thread::current().name().unwrap_or_default().to_string()
1931    }
1932
1933    struct Motor {
1934        count: i32,
1935    }
1936
1937    impl Motor {
1938
1939        async fn init(_dev: &Dev<Self>) -> Result<Self> {
1940            Ok(Self { count: 0 })
1941        }
1942
1943        async fn incr(&mut self, _dev: &Dev<Self>, arg: i32) -> Result<i32> {
1944            self.count += arg;
1945            Ok(self.count)
1946        }
1947
1948        async fn count(&self, _dev: &Dev<Self>) -> Result<i32> {
1949            Ok(self.count)
1950        }
1951
1952        async fn set_count(&mut self, _dev: &Dev<Self>, arg: i32) -> Result<()> {
1953            self.count = arg;
1954            Ok(())
1955        }
1956
1957        async fn state(&self, _dev: &Dev<Self>) -> Result<DevState> {
1958            Ok(if self.count == 0 { DevState::On } else { DevState::Moving })
1959        }
1960
1961        fn thread(&self, _dev: &Dev<Self>) -> Result<String> {
1962            Ok(thread_name())
1963        }
1964
1965        async fn thread_async(&self, _dev: &Dev<Self>) -> Result<String> {
1966            Ok(thread_name())
1967        }
1968
1969    }
1970
1971    fn model_def() -> ClassDef<Motor> {
1972        ClassDef::new_async("Motor", Motor::init)
1973            .state_async(Motor::state)
1974            .push_state_events(Some(false), None)
1975            .command(CommandDef::new("Incr").exec_exclusive_async(Motor::incr))
1976            .attr(AttrDef::new("Count").read_async(Motor::count).write_exclusive_async(Motor::set_count)
1977                .push_change_event(false))
1978            .attr(AttrDef::new("Thread").read(Motor::thread))
1979            .attr(AttrDef::new("ThreadAsync").read_async(Motor::thread_async))
1980    }
1981
1982    fn read_one<T: FromValue>(dev: &DevImpl<Motor>, name: &str) -> T {
1983        let mut reads = block_on(dev.read_attr(name.to_names(), DevSource::Dev)).unwrap();
1984        let read = reads.pop().unwrap().value;
1985        T::from_value(read.unwrap().value.unwrap()).unwrap()
1986    }
1987
1988    /// Every asynchronous handler, from the initialization to the state, run as a client
1989    /// asks for it.
1990    #[test]
1991    fn async_handlers() {
1992
1993        let (_ctx, dev) = serve(model_def());
1994        dev.0.server().sync_blocking().unwrap();
1995
1996        assert_eq!(block_on(dev.state()).unwrap(), DevState::On);
1997        let count = block_on(dev.command(Scalar::from("Incr"), Value::from(3), DevSource::Dev)).unwrap();
1998        assert_eq!(i32::from_value(count).unwrap(), 3);
1999        assert_eq!(block_on(dev.state()).unwrap(), DevState::Moving);
2000
2001        let writes = block_on(dev.write_attr(("Count", 7).into_values())).unwrap();
2002        assert!(writes.into_iter().all(|write| write.is_ok()));
2003        assert_eq!(read_one::<i32>(&dev, "Count"), 7);
2004
2005        // The Init command builds the model again.
2006        block_on(dev.command(Scalar::from("Init"), Value::Void, DevSource::Dev)).unwrap();
2007        assert_eq!(read_one::<i32>(&dev, "Count"), 0);
2008
2009    }
2010
2011    /// A name that resolves to nothing is answered with the very name the request gave,
2012    /// sharing its octets, and a known one with the name of its definition.
2013    #[test]
2014    fn unknown_attr_name() {
2015
2016        let (_ctx, dev) = serve(model_def());
2017        dev.0.server().sync_blocking().unwrap();
2018
2019        let names = Spectrum::from(&["count", "Nothing"][..]);
2020        let reads = block_on(dev.read_attr(Some(names.clone()), DevSource::Dev)).unwrap();
2021
2022        assert_eq!(reads[0].name.value(), "Count");
2023        assert!(reads[0].value.is_ok());
2024
2025        assert_eq!(reads[1].name.value().as_ptr(), names.get([1]).unwrap().as_ptr());
2026        assert_eq!(reads[1].value.as_ref().unwrap_err().kind(), ErrorKind::AttrNotFound);
2027
2028    }
2029
2030    /// A request runs on the pool as soon as one of its handlers is synchronous, the
2031    /// asynchronous ones being blocked on there, and is polled where it is awaited
2032    /// otherwise.
2033    #[test]
2034    fn request_threads() {
2035
2036        let (_ctx, dev) = serve(model_def());
2037        dev.0.server().sync_blocking().unwrap();
2038
2039        let on_pool = |name: &str| name.starts_with("pool-");
2040        assert!(on_pool(&read_one::<String>(&dev, "Thread")));
2041        assert!(!on_pool(&read_one::<String>(&dev, "ThreadAsync")));
2042
2043        let reads = block_on(dev.read_attr(["ThreadAsync", "Thread"].to_names(), DevSource::Dev)).unwrap();
2044        for read in reads {
2045            assert!(on_pool(&String::from_value(read.value.unwrap().value.unwrap()).unwrap()));
2046        }
2047
2048    }
2049
2050    /// The model stays locked across the awaits of an asynchronous handler: a request
2051    /// arriving meanwhile waits for it.
2052    #[test]
2053    fn lock_across_await() {
2054
2055        let (tx, rx) = oneshot::channel::<()>();
2056        let gate = Mutex::new(Some(rx));
2057        let def = model_def()
2058            .command(CommandDef::new("Wait").exec_exclusive_async_with(move |_model: &mut Motor, _dev, _input| {
2059                let rx = gate.lock().unwrap().take();
2060                Box::pin(async move {
2061                    if let Some(rx) = rx {
2062                        let _ = rx.await;
2063                    }
2064                    Ok(Value::Void)
2065                })
2066            }));
2067
2068        let (_ctx, dev) = serve(def);
2069        dev.0.server().sync_blocking().unwrap();
2070
2071        let mut wait = dev.command(Scalar::from("Wait"), Value::Void, DevSource::Dev);
2072        assert!((&mut wait).now_or_never().is_none());
2073        let mut read = dev.read_attr("Count".to_names(), DevSource::Dev);
2074        assert!((&mut read).now_or_never().is_none());
2075
2076        tx.send(()).unwrap();
2077        block_on(wait).unwrap();
2078        assert!(block_on(read).unwrap().pop().unwrap().value.is_ok());
2079
2080    }
2081
2082    /// A device whose asynchronous initialization failed keeps the error, and gives it
2083    /// instead of running anything.
2084    #[test]
2085    fn async_init_failed() {
2086
2087        let def = ClassDef::<Motor>::new_async_with("Motor", |_dev| Box::pin(async {
2088            Err(Error::new(ErrorKind::Internal).with_description("No hardware"))
2089        }));
2090
2091        let (_ctx, dev) = serve(def);
2092        assert_eq!(block_on(dev.state()).unwrap(), DevState::Unknown);
2093        dev.0.server().sync_blocking().unwrap();
2094
2095        assert_eq!(block_on(dev.state()).unwrap(), DevState::Fault);
2096        assert!(block_on(dev.status()).unwrap().contains("No hardware"));
2097        assert!(block_on(dev.command(Scalar::from("Init"), Value::Void, DevSource::Dev)).is_err());
2098
2099    }
2100
2101}