1use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering};
11use std::collections::hash_map::Entry;
12use std::sync::{Arc, Mutex, Weak};
13use std::task::{Context, Poll};
14use std::collections::HashMap;
15use std::time::Duration;
16use std::borrow::Cow;
17use std::pin::Pin;
18use std::mem;
19
20use futures::stream::{BoxStream, Stream, StreamExt};
21use futures::executor::block_on;
22use tracing::{debug, info, warn};
23
24use crate::backend::{default_backend, Backend, BackendServer, BackendServerConfig};
25use crate::database::{DatabaseProxy, ExportDevInfo};
26use crate::dev::{AttrInfo, AttrRead, AttrValueEvent};
27use crate::error::{Error, ErrorKind, Result, reason};
28use crate::future::block_on_timeout;
29use crate::name::{ArcName, Name};
30use crate::value::Value;
31use crate::future::Slot;
32use crate::testing::TestContext;
33
34use super::class::{AnyClass, Class};
35use super::admin::{self, Admin};
36use super::def::ClassDef;
37use super::{Model, Ref};
38use super::dev::AnyDev;
39use super::signal;
40
41
42const ADMIN_DEV_PREFIX: &str = "dserver/";
44
45#[derive(Debug)]
47pub struct Server {
48 this: Weak<Self>,
50 pub(super) admin_dev_name: Arc<str>,
53 database: DatabaseProxy,
55 backend: Weak<dyn BackendServer>,
59 classes: Mutex<HashMap<ArcName, Arc<dyn AnyClass>>>,
61 class_count: AtomicUsize,
64 pub(super) devs: Mutex<HashMap<ArcName, Arc<dyn AnyDev>>>,
68 pub(super) pending: Mutex<Pending>,
70 sync_lock: async_lock::Mutex<()>,
73 stopped: AtomicBool,
75 events: Mutex<HashMap<ArcName, HashMap<ArcName, AttrEvents>>>,
88 pub(super) local: bool,
91}
92
93#[derive(Debug, Default)]
95struct AttrEvents {
96 values: HashMap<AttrValueEvent, Subscribers<AttrRead<Value>>>,
97 ready: Subscribers<()>,
98 conf: Subscribers<AttrInfo>,
99}
100
101type Subscribers<T> = Vec<Weak<Slot<Result<T>>>>;
105
106#[derive(Debug, Default)]
108pub struct Pending {
109 pub added: Vec<Arc<dyn AnyDev>>,
111 pub unexported: Vec<(Arc<dyn AnyDev>, Option<Arc<str>>)>,
115 pub removed: Vec<Arc<dyn AnyDev>>,
117}
118
119impl Server {
120
121 #[inline]
123 pub fn name(&self) -> &str {
124 &self.admin_dev_name[ADMIN_DEV_PREFIX.len()..]
125 }
126
127 #[inline]
128 pub fn admin_dev_name(&self) -> &str {
129 &self.admin_dev_name
130 }
131
132 #[inline]
133 pub fn database(&self) -> &DatabaseProxy {
134 &self.database
135 }
136
137 #[inline]
140 pub fn backend(&self) -> Option<Arc<dyn BackendServer>> {
141 self.backend.upgrade()
142 }
143
144 pub(super) fn served_backend(&self) -> Result<Arc<dyn BackendServer>> {
147 self.backend().ok_or_else(|| Error::new(ErrorKind::Reason(reason::API_ServerNotRunning))
148 .with_append_description(format_args!("Server {} is not served anymore", self.name())))
149 }
150
151 pub fn add_class<M: Model>(&self, def: ClassDef<M>) -> Result<Ref<'_, Class<M>>> {
153
154 let def = Arc::new(def);
155 let mut classes = self.classes.lock().unwrap();
156 let name = ArcName::from(Arc::from(&*def.name));
157
158 let Entry::Vacant(entry) = classes.entry(name) else {
159 return Err(Error::new(ErrorKind::ClassAlreadyDefined)
160 .with_append_description(format_args!("Class {:?}", def.name)));
161 };
162
163 let index = self.class_count.fetch_add(1, Ordering::Relaxed);
165 let class = Class::new(self.this.upgrade().unwrap(), def, index);
166 entry.insert(Arc::clone(&class) as Arc<dyn AnyClass>);
167 Ok(Ref::new(class))
168
169 }
170
171 pub fn get_class(&self, name: &str) -> Option<Ref<'_, dyn AnyClass>> {
173 self.classes.lock().unwrap().get(Name::new(name)).map(|class| Ref::new(Arc::clone(class)))
174 }
175
176 pub fn add_dev(&self, class: &str, name: &str) -> Result<Ref<'_, dyn AnyDev>> {
183
184 let class = self.classes.lock().unwrap().get(Name::new(class))
185 .map(Arc::clone)
186 .ok_or_else(|| Error::new(ErrorKind::ClassNotFound)
187 .with_append_description(format_args!("Class {class:?}")))?;
188
189 class.add_dev(name).map(Ref::new)
190
191 }
192
193 pub fn remove_dev(&self, name: &str) -> bool {
199
200 let Some(dev) = self.devs.lock().unwrap().remove(Name::new(name)) else {
201 return false;
202 };
203
204 let mut pending = self.pending.lock().unwrap();
208 if let Some(index) = pending.added.iter().position(|added| Arc::ptr_eq(added, &dev)) {
209 pending.added.remove(index);
210 } else {
211 pending.unexported.retain(|(unexported, _)| !Arc::ptr_eq(unexported, &dev));
212 pending.removed.push(dev);
213 }
214
215 true
216
217 }
218
219 pub async fn sync(&self) -> Result<()> {
239
240 let _sync = self.sync_lock.lock().await;
241 if self.stopped.load(Ordering::Acquire) {
242 return Ok(());
243 }
244
245 let mut first_err = None;
246
247 let removed = mem::take(&mut self.pending.lock().unwrap().removed);
250 for dev in removed {
251
252 if let Err(err) = self.database.unexport_dev_async(dev.name()).await {
253 warn!(dev = %dev.name(), %err, "Failed to unexport the removed device");
254 first_err.get_or_insert(err);
255 }
256
257 if let Err(err) = dev.withdraw().await {
258 warn!(dev = %dev.name(), %err, "Failed to delete the removed device");
259 first_err.get_or_insert(err);
260 }
261
262 if !self.devs.lock().unwrap().contains_key(Name::new(dev.name())) {
265 self.end_dev_events(dev.name());
266 }
267
268 debug!(dev = %dev.name(), "Removed the device");
269
270 }
271
272 loop {
275
276 let mut added = mem::take(&mut self.pending.lock().unwrap().added);
277 if added.is_empty() {
278 break;
279 }
280
281 added.sort_by_key(|dev| dev.class().index());
282 for dev in added {
283 if let Err(err) = dev.init().await {
286 warn!(dev = %dev.name(), %err, "Failed to complete the initialization of the device");
287 }
288 self.pending.lock().unwrap().unexported.push((dev, None));
289 }
290
291 }
292
293 let unexported = mem::take(&mut self.pending.lock().unwrap().unexported);
295 let mut failed = Vec::new();
296 for (dev, itr) in unexported {
297
298 let served = match itr {
299 Some(itr) => Ok(itr),
300 None => dev.serve(),
301 };
302
303 let itr = match served {
304 Ok(itr) => itr,
305 Err(err) => {
306 warn!(dev = %dev.name(), %err, "Failed to serve the device");
307 first_err.get_or_insert(err);
308 failed.push((dev, None));
309 continue;
310 }
311 };
312
313 if let Err(err) = self.export_dev(&*dev, &itr).await {
314 warn!(dev = %dev.name(), %err, "Failed to export the device");
315 first_err.get_or_insert(err);
316 failed.push((dev, Some(itr)));
317 continue;
318 }
319
320 debug!(dev = %dev.name(), "Exported the device");
321
322 }
323
324 self.pending.lock().unwrap().unexported.extend(failed);
325 first_err.map_or(Ok(()), Err)
326
327 }
328
329 pub fn sync_blocking(&self) -> Result<()> {
332 block_on(self.sync())
333 }
334
335 async fn export_dev(&self, dev: &dyn AnyDev, itr: &str) -> Result<()> {
338 let backend = self.served_backend()?;
339 self.database.export_dev_async(ExportDevInfo {
340 name: Cow::Borrowed(dev.name()),
341 itr: Cow::Borrowed(itr),
342 host: Cow::Borrowed(&backend.host()),
343 version: Cow::Owned(backend.version().to_string()),
344 pid: std::process::id() as i32,
345 }).await
346 }
347
348 pub fn classes(&self) -> Vec<Ref<'_, dyn AnyClass>> {
351 let mut classes = self.classes.lock().unwrap().values().map(Arc::clone).collect::<Vec<_>>();
352 classes.sort_by_key(|class| class.index());
353 classes.into_iter().map(Ref::new).collect()
354 }
355
356 pub fn devs(&self) -> Vec<Ref<'_, dyn AnyDev>> {
359 let mut devs = self.devs.lock().unwrap().values().map(Arc::clone).collect::<Vec<_>>();
360 devs.sort_by(|a, b| a.class().index().cmp(&b.class().index()).then_with(|| a.name().cmp(b.name())));
361 devs.into_iter().map(Ref::new).collect()
362 }
363
364 pub fn get_dev(&self, name: &str) -> Option<Ref<'_, dyn AnyDev>> {
366 self.devs.lock().unwrap().get(Name::new(name)).map(|dev| Ref::new(Arc::clone(dev)))
367 }
368
369 pub async fn stop(&self) -> Result<()> {
380
381 let _sync = self.sync_lock.lock().await;
382 if self.stopped.swap(true, Ordering::AcqRel) {
383 return Ok(());
384 }
385
386 info!(server = %self.name(), "Stopping the server");
387
388 let unexported = self.database.unexport_server_async(self.name()).await;
389 if let Err(err) = &unexported {
390 warn!(server = %self.name(), %err, "Failed to unexport the server");
391 }
392
393 if let Some(backend) = self.backend() {
394 backend.stop();
395 }
396
397 self.end_events();
398
399 unexported
400
401 }
402
403 async fn delete_devs(&self) -> Result<()> {
408
409 let mut devs = mem::take(&mut *self.devs.lock().unwrap())
410 .into_values()
411 .collect::<Vec<_>>();
412
413 devs.sort_by_key(|dev| std::cmp::Reverse(dev.class().index()));
414 *self.pending.lock().unwrap() = Pending::default();
415
416 let mut first_err = None;
417 for dev in devs {
418 if let Err(err) = dev.withdraw().await {
419 warn!(dev = %dev.name(), %err, "Failed to delete the device");
420 first_err.get_or_insert(err);
421 }
422 }
423
424 first_err.map_or(Ok(()), Err)
425
426 }
427
428 fn clear(&self) {
431 let devs = std::mem::take(&mut *self.devs.lock().unwrap());
432 drop(devs);
433 let classes = std::mem::take(&mut *self.classes.lock().unwrap());
434 drop(classes);
435 self.end_events();
437 }
438
439 pub(super) fn subscribe_attr_value(&self, dev: &str, attr: &str, event: AttrValueEvent) -> BoxStream<'static, Result<AttrRead<Value>>> {
442 self.subscribe_event(dev, attr, |events| events.values.entry(event).or_default()).boxed()
443 }
444
445 pub(super) fn subscribe_attr_ready(&self, dev: &str, attr: &str) -> BoxStream<'static, Result<()>> {
447 self.subscribe_event(dev, attr, |events| &mut events.ready).boxed()
448 }
449
450 pub(super) fn subscribe_attr_conf(&self, dev: &str, attr: &str) -> BoxStream<'static, Result<AttrInfo>> {
452 self.subscribe_event(dev, attr, |events| &mut events.conf).boxed()
453 }
454
455 pub(super) fn push_attr_value(&self, dev: &str, attr: &str, event: AttrValueEvent, read: Result<AttrRead<Value>>) {
457 self.push_event(dev, attr, |events| events.values.entry(event).or_default(), read);
458 }
459
460 pub(super) fn push_attr_ready(&self, dev: &str, attr: &str, ready: Result<()>) {
462 self.push_event(dev, attr, |events| &mut events.ready, ready);
463 }
464
465 pub(super) fn push_attr_conf(&self, dev: &str, attr: &str, info: Result<AttrInfo>) {
467 self.push_event(dev, attr, |events| &mut events.conf, info);
468 }
469
470 fn subscribe_event<T>(&self, dev: &str, attr: &str, select: impl FnOnce(&mut AttrEvents) -> &mut Subscribers<T>) -> EventStream<T> {
471
472 let slot = Arc::new(Slot::new());
473
474 let mut devs = self.events.lock().unwrap();
475 let attrs = devs.entry(ArcName::from(Arc::<str>::from(dev))).or_default();
476 let events = attrs.entry(ArcName::from(Arc::<str>::from(attr))).or_default();
477 let subscribers = select(events);
478 subscribers.retain(|slot| slot.strong_count() != 0);
479 subscribers.push(Arc::downgrade(&slot));
480
481 EventStream {
482 slot,
483 ended: false,
484 }
485
486 }
487
488 fn push_event<T: Clone>(&self, dev: &str, attr: &str, select: impl FnOnce(&mut AttrEvents) -> &mut Subscribers<T>, event: Result<T>) {
489
490 let mut devs = self.events.lock().unwrap();
491 let Some(attrs) = devs.get_mut(Name::new(dev)) else { return };
492 let Some(events) = attrs.get_mut(Name::new(attr)) else { return };
493
494 let subscribers = select(events);
496 subscribers.retain(|slot| slot.strong_count() != 0);
497
498 if let Some((last, others)) = subscribers.split_last() {
500
501 for slot in others.iter().filter_map(Weak::upgrade) {
502 slot.push(match &event {
503 Ok(value) => Ok(value.clone()),
504 Err(err) => Err(err.duplicate()),
505 });
506 }
507
508 if let Some(slot) = last.upgrade() {
509 slot.push(event);
510 }
511
512 }
513
514 events.values.retain(|_, subscribers| !subscribers.is_empty());
516 if events.values.is_empty() && events.ready.is_empty() && events.conf.is_empty() {
517 attrs.remove(Name::new(attr));
518 if attrs.is_empty() {
519 devs.remove(Name::new(dev));
520 }
521 }
522
523 }
524
525 fn end_dev_events(&self, dev: &str) {
527 let attrs = self.events.lock().unwrap().remove(Name::new(dev));
528 for events in attrs.into_iter().flat_map(HashMap::into_values) {
529 events.end();
530 }
531 }
532
533 fn end_events(&self) {
535 let devs = mem::take(&mut *self.events.lock().unwrap());
536 for events in devs.into_values().flat_map(HashMap::into_values) {
537 events.end();
538 }
539 }
540
541}
542
543impl AttrEvents {
544
545 fn end(self) {
547 for subscribers in self.values.into_values() {
548 end_subscribers(subscribers);
549 }
550 end_subscribers(self.ready);
551 end_subscribers(self.conf);
552 }
553
554}
555
556fn end_subscribers<T>(subscribers: Subscribers<T>) {
557 for slot in subscribers.iter().filter_map(Weak::upgrade) {
558 slot.end();
559 }
560}
561
562struct EventStream<T> {
564 slot: Arc<Slot<Result<T>>>,
565 ended: bool,
567}
568
569impl<T> Stream for EventStream<T> {
570
571 type Item = Result<T>;
572
573 fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
574
575 let this = self.get_mut();
576 if this.ended {
577 return Poll::Ready(None);
578 }
579
580 this.slot.poll_take(cx).map(|event| event.or_else(|| {
582 this.ended = true;
583 Some(Err(Error::new(ErrorKind::DevNotConnected)
584 .with_append_description("The device is no longer served")))
585 }))
586
587 }
588
589}
590
591pub struct ServerBuilder {
593 exe: String,
594 inst: String,
595 backend: Option<Arc<dyn Backend>>,
596 database: Option<DatabaseProxy>,
597 config: BackendServerConfig,
599 local: bool,
601 stop_on_signal: bool,
603 pub(super) test_context: Option<TestContext>,
606 classes: Vec<(ArcName, Arc<dyn AnyClassDef>)>,
610}
611
612trait AnyClassDef: Send + Sync {
614 fn new_class(self: Arc<Self>, server: Arc<Server>, index: usize) -> Arc<dyn AnyClass>;
615}
616
617impl<M: Model> AnyClassDef for ClassDef<M> {
618 fn new_class(self: Arc<Self>, server: Arc<Server>, index: usize) -> Arc<dyn AnyClass> {
619 Class::new(server, self, index)
620 }
621}
622
623impl ServerBuilder {
624
625 pub fn new(exe: &str, inst: &str) -> Self {
628 Self {
629 exe: exe.to_string(),
630 inst: inst.to_string(),
631 backend: None,
632 database: None,
633 config: BackendServerConfig::default(),
634 local: true,
635 stop_on_signal: true,
636 test_context: None,
637 classes: Vec::new(),
638 }
639 }
640
641 pub fn backend(mut self, backend: Arc<dyn Backend>) -> Self {
644 self.backend = Some(backend);
645 self
646 }
647
648 pub fn database(mut self, database: DatabaseProxy) -> Self {
650 self.database = Some(database);
651 self
652 }
653
654 pub fn host(mut self, host: &str) -> Self {
656 self.config.host = Some(host.to_string());
657 self
658 }
659
660 pub fn port(mut self, port: u16) -> Self {
662 self.config.port = Some(port);
663 self
664 }
665
666 pub fn local(mut self, local: bool) -> Self {
670 self.local = local;
671 self
672 }
673
674 pub fn class<M: Model>(mut self, def: ClassDef<M>) -> Result<Self> {
676
677 if def.name.eq_ignore_ascii_case(admin::CLASS_NAME) {
678 return Err(Error::new(ErrorKind::ClassAlreadyDefined)
679 .with_append_description(format_args!("Class {:?} is reserved to the admin device", def.name)));
680 }
681
682 if self.classes.iter().any(|(name, _)| **name == *Name::new(&def.name)) {
683 return Err(Error::new(ErrorKind::ClassAlreadyDefined)
684 .with_append_description(format_args!("Class {:?}", def.name)));
685 }
686
687 self.classes.push((ArcName::from(Arc::from(&*def.name)), Arc::new(def)));
688 Ok(self)
689
690 }
691
692 pub fn stop_on_signal(mut self, stop_on_signal: bool) -> Self {
702 self.stop_on_signal = stop_on_signal;
703 self
704 }
705
706 pub fn serve(self) -> Result<ServerHandle> {
714 block_on(self.serve_async())
715 }
716
717 pub fn run(self) -> Result<()> {
721 block_on(self.run_async())
722 }
723
724 pub async fn run_async(self) -> Result<()> {
726 self.serve_async().await?.wait_async().await
727 }
728
729 pub async fn serve_async(self) -> Result<ServerHandle> {
731
732 if self.stop_on_signal {
734 signal::install()?;
735 }
736
737 let backend = self.backend.unwrap_or_else(default_backend);
738 let database = self.database
739 .unwrap_or_else(|| DatabaseProxy::new_from_env_with_backend(Arc::clone(&backend)));
740
741 let admin_dev_name = Arc::<str>::from(format!("{ADMIN_DEV_PREFIX}{}/{}", self.exe, self.inst));
744 let (tango_host, tango_port) = database.host_and_port_async().await?;
745 let config = self.config.clone()
746 .with_admin_name(Arc::clone(&admin_dev_name))
747 .with_tango_host(tango_host, tango_port);
748
749 let backend = backend.serve(&config).await?;
750
751 let server = Arc::new_cyclic(|this| Server {
752 this: this.clone(),
753 admin_dev_name,
754 database,
755 backend: Arc::downgrade(&backend),
756 classes: Mutex::new(HashMap::new()),
757 class_count: AtomicUsize::new(1 + self.classes.len()),
758 devs: Mutex::new(HashMap::new()),
759 pending: Mutex::new(Pending::default()),
760 sync_lock: async_lock::Mutex::new(()),
761 stopped: AtomicBool::new(false),
762 events: Mutex::new(HashMap::new()),
763 local: self.local,
764 });
765
766 let admin = Class::new(Arc::clone(&server), Arc::new(Admin::def()), 0);
769 let mut classes = HashMap::new();
770 classes.insert(ArcName::from(Arc::from(admin::CLASS_NAME)), Arc::clone(&admin) as Arc<dyn AnyClass>);
771 for (index, (name, def)) in self.classes.into_iter().enumerate() {
772 classes.insert(name, def.new_class(Arc::clone(&server), 1 + index));
773 }
774 *server.classes.lock().unwrap() = classes;
775
776 let handle = ServerHandle { server, backend, _test_context: self.test_context };
778 let admin_dev = admin.add_dev(handle.server.admin_dev_name())?;
779
780 let booted = match handle.server.sync().await {
781 Ok(()) => admin_dev.check_model().await,
782 Err(err) => Err(err),
783 };
784
785 if let Err(err) = booted {
786 let _ = handle.server.stop().await;
789 let _ = handle.wait_async().await;
790 return Err(err);
791 }
792
793 drop(admin_dev);
794
795 if self.stop_on_signal {
796 signal::register(&handle.server);
797 }
798
799 info!(server = %handle.server.name(), host = %handle.backend.host(), port = handle.backend.port(),
800 devs = handle.server.devs.lock().unwrap().len() - 1, "Serving");
801 Ok(handle)
802
803 }
804
805}
806
807#[derive(Debug)]
814pub struct ServerHandle {
815 server: Arc<Server>,
816 backend: Arc<dyn BackendServer>,
820 _test_context: Option<TestContext>,
823}
824
825impl ServerHandle {
826
827 #[inline]
828 pub fn server(&self) -> &Server {
829 &self.server
830 }
831
832 pub(crate) fn server_arc(&self) -> Arc<Server> {
835 Arc::clone(&self.server)
836 }
837
838 pub fn wait(&self) -> Result<()> {
845 block_on(self.wait_async())
846 }
847
848 pub fn wait_timeout(&self, timeout: Duration) -> Result<()> {
858 block_on_timeout(self.backend.wait(), timeout)
859 .map_err(|err| err.with_append_description(format_args!("Server {} is still answering requests", self.server.name())))?;
860 block_on(self.server.delete_devs())
861 }
862
863 pub async fn wait_async(&self) -> Result<()> {
870 self.backend.wait().await;
871 let deleted = self.server.delete_devs().await;
872 info!(server = %self.server.name(), "Stopped the server");
873 deleted
874 }
875
876}
877
878impl Drop for ServerHandle {
879
880 fn drop(&mut self) {
885 self.server.clear();
886 }
887
888}
889
890#[cfg(test)]
891mod tests {
892
893 use futures::executor::block_on;
894 use futures::FutureExt;
895
896 use crate::dev::AttrQuality;
897 use crate::testing::TestContext;
898
899 use super::super::def::ClassDef;
900 use super::*;
901
902
903 fn serve() -> (TestContext, Arc<Server>) {
905
906 let ctx = TestContext::new().unwrap();
907 ctx.database().add_server("Test/test", &[("a/b/c", "A")]).unwrap();
908
909 let server = ctx.serve(ServerBuilder::new("Test", "test")
910 .class(ClassDef::<()>::new_default("A")).unwrap())
911 .unwrap();
912
913 (ctx, server)
914
915 }
916
917 fn read(value: f64) -> AttrRead<Value> {
918 AttrRead {
919 value: Some(Value::from(value)),
920 w_value: None,
921 quality: AttrQuality::Valid,
922 time: std::time::SystemTime::UNIX_EPOCH + Duration::from_secs(1),
923 }
924 }
925
926 fn now<T>(stream: &mut BoxStream<'static, T>) -> Option<Option<T>> {
928 stream.next().now_or_never()
929 }
930
931 #[test]
932 fn latest_only() {
933
934 let (_ctx, server) = serve();
935 let mut sub = server.subscribe_attr_value("a/b/c", "Attr", AttrValueEvent::Change);
936
937 assert!(now(&mut sub).is_none());
938
939 server.push_attr_value("a/b/c", "attr", AttrValueEvent::Change, Ok(read(1.0)));
940 server.push_attr_value("A/B/C", "ATTR", AttrValueEvent::Change, Ok(read(2.0)));
941
942 server.push_attr_value("a/b/c", "attr", AttrValueEvent::Archive, Ok(read(3.0)));
944 server.push_attr_value("a/b/c", "other", AttrValueEvent::Change, Ok(read(4.0)));
945
946 assert_eq!(now(&mut sub).unwrap().unwrap().unwrap(), read(2.0));
947 assert!(now(&mut sub).is_none());
948
949 }
950
951 #[test]
952 fn every_subscriber() {
953
954 let (_ctx, server) = serve();
955 let mut first = server.subscribe_attr_value("a/b/c", "attr", AttrValueEvent::Change);
956 let mut second = server.subscribe_attr_value("a/b/c", "attr", AttrValueEvent::Change);
957
958 server.push_attr_value("a/b/c", "attr", AttrValueEvent::Change, Err(Error::new(ErrorKind::Reason(reason::API_AttrNotAllowed))));
959
960 for sub in [&mut first, &mut second] {
961 let err = now(sub).unwrap().unwrap().unwrap_err();
962 assert_eq!(err.kind(), ErrorKind::Reason(reason::API_AttrNotAllowed));
963 }
964
965 }
966
967 #[test]
968 fn unsubscribe() {
969
970 let (_ctx, server) = serve();
971 let sub = server.subscribe_attr_ready("a/b/c", "attr");
972 drop(sub);
973
974 server.push_attr_ready("a/b/c", "attr", Ok(()));
976 assert!(server.events.lock().unwrap().is_empty());
977
978 }
979
980 #[test]
981 fn restart() {
982
983 let (_ctx, server) = serve();
984 let mut sub = server.subscribe_attr_conf("a/b/c", "attr");
985
986 assert!(server.remove_dev("a/b/c"));
988 server.add_dev("A", "a/b/c").unwrap();
989 server.sync_blocking().unwrap();
990 assert!(now(&mut sub).is_none());
991
992 assert!(server.remove_dev("a/b/c"));
994 server.sync_blocking().unwrap();
995 assert_eq!(now(&mut sub).unwrap().unwrap().unwrap_err().kind(), ErrorKind::DevNotConnected);
996 assert!(now(&mut sub).unwrap().is_none());
997
998 }
999
1000 #[test]
1001 fn stop() {
1002
1003 let (_ctx, server) = serve();
1004 let mut sub = server.subscribe_attr_ready("a/b/c", "attr");
1005
1006 server.push_attr_ready("a/b/c", "attr", Ok(()));
1008 block_on(server.stop()).unwrap();
1009
1010 assert!(now(&mut sub).unwrap().unwrap().is_ok());
1011 assert_eq!(now(&mut sub).unwrap().unwrap().unwrap_err().kind(), ErrorKind::DevNotConnected);
1012 assert!(now(&mut sub).unwrap().is_none());
1013
1014 }
1015
1016 #[test]
1017 fn weak() {
1018
1019 let (_ctx, server) = serve();
1020 let weak = Ref::downgrade(&server.get_dev("a/b/c").unwrap());
1021 assert_eq!(weak.upgrade().unwrap().name(), "a/b/c");
1022
1023 assert!(server.remove_dev("a/b/c"));
1025 server.add_dev("A", "a/b/c").unwrap();
1026 server.sync_blocking().unwrap();
1027 assert!(weak.upgrade().is_none());
1028
1029 }
1030
1031 #[test]
1032 fn dropped() {
1033
1034 let (ctx, server) = serve();
1035 let mut sub = server.subscribe_attr_ready("a/b/c", "attr");
1036 drop(ctx);
1037
1038 assert_eq!(block_on(sub.next()).unwrap().unwrap_err().kind(), ErrorKind::DevNotConnected);
1039
1040 }
1041
1042}