pub struct Server { /* private fields */ }Expand description
The shared state of a server, co-owned by the ServerHandle and by every class of it.
Implementations§
Source§impl Server
impl Server
Sourcepub fn name(&self) -> &str
pub fn name(&self) -> &str
The exe/inst name of that server, under which it is registered in the database.
pub fn admin_dev_name(&self) -> &str
pub fn database(&self) -> &DatabaseProxy
Sourcepub fn backend(&self) -> Option<Arc<dyn BackendServer>>
pub fn backend(&self) -> Option<Arc<dyn BackendServer>>
The backend serving the devices of that server, None once its handle is
dropped, see ServerHandle.
Sourcepub fn add_class<M: Model>(&self, def: ClassDef<M>) -> Result<Ref<'_, Class<M>>>
pub fn add_class<M: Model>(&self, def: ClassDef<M>) -> Result<Ref<'_, Class<M>>>
Register a new class in this server, from its definition.
Sourcepub fn get_class(&self, name: &str) -> Option<Ref<'_, dyn AnyClass>>
pub fn get_class(&self, name: &str) -> Option<Ref<'_, dyn AnyClass>>
Get a class of this server from its name.
Sourcepub fn add_dev(&self, class: &str, name: &str) -> Result<Ref<'_, dyn AnyDev>>
pub fn add_dev(&self, class: &str, name: &str) -> Result<Ref<'_, dyn AnyDev>>
Add a device to this server, as an instance of the class of that name, which is how
the devices listed by the database are added, the database giving the class of each
by its name. See Class::add_dev for the typed form.
The device is only registered: it is initialized, served and exported by the next
Self::sync.
Sourcepub fn remove_dev(&self, name: &str) -> bool
pub fn remove_dev(&self, name: &str) -> bool
Remove the device of that name from this server, giving back whether it had one.
Its name is free again right away, but the device itself is only unexported, no
longer served and deleted by the next Self::sync. A device removed before any
synchronization reached it is simply dropped.
Sourcepub async fn sync(&self) -> Result<()>
pub async fn sync(&self) -> Result<()>
Apply what was done to the devices of this server since the last synchronization: the devices removed are unexported, no longer served and deleted, then the devices added are initialized, served and exported, which is what makes them reachable.
The devices added are initialized one after the other, class by class in the order the classes were made, and in the order they were added within a class. A device whose initialization adds devices has them initialized by this same synchronization, which is how the admin device boots a server. Each device is then served and exported on its own, which is what a Tango server always tells the database.
A device whose initialization failed is still served and exported, in FAULT, so that a client can ask it what went wrong. A device that could not be served or exported is retried by the next synchronization, and the first such error is given back once every other device is done.
Synchronizations never interleave: one waits for the one running to be done, so that everything done before calling it is applied once it returns. This is also why an init function must never call it, since it would wait for itself.
Sourcepub fn sync_blocking(&self) -> Result<()>
pub fn sync_blocking(&self) -> Result<()>
The blocking form of Self::sync, which must therefore never run on the executor
of a backend, in an asynchronous handler in particular.
Sourcepub fn classes(&self) -> Vec<Ref<'_, dyn AnyClass>>
pub fn classes(&self) -> Vec<Ref<'_, dyn AnyClass>>
Every class of this server, in the order they were made, the admin one first, see
AnyClass::index.
Sourcepub fn devs(&self) -> Vec<Ref<'_, dyn AnyDev>>
pub fn devs(&self) -> Vec<Ref<'_, dyn AnyDev>>
Every device of this server, class by class in the order of Self::classes, and
by name within a class.
Sourcepub fn get_dev(&self, name: &str) -> Option<Ref<'_, dyn AnyDev>>
pub fn get_dev(&self, name: &str) -> Option<Ref<'_, dyn AnyDev>>
Get a device of this server from its name.
Sourcepub async fn stop(&self) -> Result<()>
pub async fn stop(&self) -> Result<()>
Stop this server, which is only ever done once: it is unexported as a whole, so
that clients stop finding it, then its backend is stopped, the requests in flight
still being answered. The thread waiting on the server then deletes the models, see
ServerHandle::wait. No synchronization runs after this, the devices still
waiting for one never being served.
This does not wait for the backend, and can therefore be called from anywhere, a
request handler included, which is what the Kill command of the admin device does.
The backend is stopped even if the server could not be unexported, which is the
error then given back.