Skip to main content

ServerHandle

Struct ServerHandle 

Source
pub struct ServerHandle { /* private fields */ }
Expand description

The handle to a server being served, which is what owns it on behalf of its caller, and derefs to it.

A server ends by being stopped, see Server::stop_async, which deletes its devices, by its owner or by a client through the Kill command of its admin device, and is waited for by its owner, see Server::wait. A server is always stopped: dropping the handle of a server that was not only stops its backend, with no other side effect, see Drop.

Implementations§

Source§

impl ServerHandle

Source

pub fn server(&self) -> &Server

The server this handle serves.

Methods from Deref<Target = Server>§

Source

pub fn name(&self) -> &str

The exe/inst name of that server, under which it is registered in the database.

Source

pub fn admin_dev_name(&self) -> &str

The name of the admin device of that server, dserver/exe/inst.

Source

pub fn database(&self) -> &DatabaseProxy

The database that server is registered in.

Source

pub fn backend(&self) -> Option<Arc<dyn BackendServer>>

The backend serving the devices of that server, None once it is not served anymore, see ServerHandle.

Source

pub fn add_class<M: Model>(&self, def: ClassDef<M>) -> Result<Arc<Class<M>>>

Register a new class in this server, from its definition.

Source

pub fn get_class<M: Model>(&self, name: &str) -> Option<Arc<Class<M>>>

Get a class of this server from its name, if it is one of that model.

Source

pub fn add_dev(&self, class: &str, name: &str) -> Result<()>

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_async.

Source

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_async. A device removed before any synchronization reached it is simply dropped.

Source

pub async fn sync_async(&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.

Source

pub fn sync(&self) -> Result<()>

The blocking form of Self::sync_async, which must therefore never run on the executor of a backend, in an asynchronous handler in particular.

Source

pub fn class_names(&self) -> Vec<Arc<str>>

The names of every class of this server, in the order they were made, the admin one first.

Source

pub fn dev_names(&self) -> Vec<Arc<str>>

The names of every device of this server, class by class in the order of Self::class_names, and by name within a class.

Source

pub fn has_dev(&self, name: &str) -> bool

Whether this server has a device of that name.

Source

pub fn get_dev<M: Model>(&self, name: &str) -> Option<Arc<Dev<M>>>

Get a device of this server from its name, if its class is one of that model.

Source

pub async fn stop_async(&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, and its devices are deleted, see Self::wait for what waits for the backend to be through. No synchronization runs after this, the devices still waiting for one never being served.

The devices are deleted one after the other, the classes in the reverse of their order, the admin device last, each once the requests still running on it are through, see Dev::is_withdrawn: a request that never ends therefore keeps this from ever returning. This is also why a request handler must never call it, since it would wait for itself; the Kill command of the admin device stops its server from the pool instead.

The backend is stopped and the devices deleted even if the server could not be unexported, and the first error met is given back.

Source

pub fn stop(&self) -> Result<()>

The blocking form of Self::stop_async, which must therefore never run on the executor of a backend, in an asynchronous handler in particular.

Source

pub async fn wait_async(&self)

Wait for this server to be stopped, see Self::stop_async, which is what the thread running a server spends its life in: for its backend to be through with every request, and for its devices to be deleted. A server that is not served anymore, see ServerHandle, is not waited for.

The backend is waited for first, which is only through once stopped, see BackendServer::wait, then the stop itself, which deletes the devices under the lock of the synchronizations. This waits for every request in flight, and must therefore never be called from a request handler, which would wait for itself.

Source

pub fn wait(&self)

The blocking form of Self::wait_async, which must therefore never run on the executor of a backend, in an asynchronous handler in particular. See Self::wait_timeout for a wait that gives up.

Source

pub fn wait_timeout(&self, timeout: Duration) -> Result<()>

Wait for this server to be stopped, see Self::wait_async, giving up with ErrorKind::TimedOut if the backend is still answering requests once the timeout has run out, which a request that never ends makes it, or a server never stopped.

The timeout only bounds the backend: once it is through, the deletion of the devices is waited for, however long that takes.

Trait Implementations§

Source§

impl Debug for ServerHandle

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Deref for ServerHandle

Source§

type Target = Server

The resulting type after dereferencing.
Source§

fn deref(&self) -> &Server

Dereferences the value.
Source§

impl Drop for ServerHandle

Source§

fn drop(&mut self)

Stop the backend and end the subscriptions, with no other side effect: a server that was not stopped, see Server::stop_async, is not unexported, and its models are not deleted. The requests in flight are not waited for, and everything of the server is let go of once they end, see BackendServer, a request still holding it for the time of a Server::sync_async or a Server::stop_async it runs.

Source§

fn pin_drop(self: Pin<&mut Self>)

🔬This is a nightly-only experimental API. (pin_ergonomics)
Execute the destructor for this type, but different to Drop::drop, it requires self to be pinned. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self> ⓘ

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self> ⓘ

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Model for T
where T: Send + Sync + 'static,

Source§

impl<P, T> Receiver for P
where P: Deref<Target = T> + ?Sized, T: ?Sized,

Source§

type Target = T

🔬This is a nightly-only experimental API. (arbitrary_self_types)
The target type on which the method may be called.
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self> ⓘ
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self> ⓘ

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more