Skip to main content

BackendServer

Trait BackendServer 

Source
pub trait BackendServer:
    Debug
    + Send
    + Sync {
    // Required methods
    fn add(&self, name: &str, dev: Arc<dyn BackendDev>) -> Result<Arc<str>>;
    fn remove(&self, name: &str) -> bool;
    fn host(&self) -> Arc<str> ⓘ;
    fn port(&self) -> u16;
    fn version(&self) -> i32;
    fn stop(&self);
    fn wait(&self) -> BoxFuture<'_, ()>;

    // Provided methods
    fn zmq_event_subscription_change(
        &self,
        _args: Spectrum<str>,
    ) -> BoxFuture<'_, Result<(Spectrum<i32>, Spectrum<str>)>> { ... }
    fn event_confirm_subscription(
        &self,
        _args: Spectrum<str>,
    ) -> BoxFuture<'_, Result<()>> { ... }
}
Expand description

The backend for a server that is served, from the moment Backend::serve hands it over until it is stopped, see Self::stop, or dropped.

Nothing here waits but Self::wait: adding, removing a device and stopping are quick and never block, so they are called from anywhere, a request of one of the devices of the backend included. What they ask for happens at some point after, a device that was removed still answering the requests it was answering, for instance.

A backend holds the devices it serves, strongly, from Self::add, and, once they were removed or the backend stopped, until their requests in flight are answered, and never beyond Self::wait: once it resolves, no Arc to any device is left anywhere in the backend. This is what lets the owner of a device rely on the device being dropped with the last reference it has.

§Dropping

Dropping the last Arc to a backend server drops everything of it at once, with no side effect: every device it serves is let go of, and every request in flight is cancelled, its future dropped and nothing answered. A server that is to end properly is therefore stopped and waited for before it is dropped.

Required Methods§

Source

fn add(&self, name: &str, dev: Arc<dyn BackendDev>) -> Result<Arc<str>>

Add a device to be served, giving back its ITR, which it is reachable at from then on or shortly after. The name of the device is given with the device so the server doesn’t have to call the name() function on it. This is quick and never blocks, see the trait documentation.

Device names are not case sensitive: a backend lowercases the name as soon as it is given, which every later lookup of the device, from Self::remove to the requests of the clients, then relies on.

The server might return any error, but the error NotHandled should be ignored.

Source

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

Stop serving the device of that name, giving back whether one was being served. No new request reaches it from the call on, or shortly after, and the ones it was answering are still answered. This is quick and never blocks, see the trait documentation.

The device itself is not given back: the backend drops what it was holding of it once its requests are answered, which is what makes it stop being reachable.

Source

fn host(&self) -> Arc<str> ⓘ

The host, ip or hostname, where this server is listening.

Source

fn port(&self) -> u16

The TCP port this server is listening to.

Source

fn version(&self) -> i32

The version of the protocol the devices are served with, which is what a client is told of a device in its info and what the database is told when it is exported.

Source

fn stop(&self)

Stop serving, which nothing undoes: a backend that was stopped is one no client reaches again, whatever is added to it afterward. Every device is removed, all at once, as Self::remove does: no new request is taken, and the ones being answered are.

This does not wait for anything, and can therefore be called from anywhere, including from a request of one of its devices; see Self::wait for that.

Source

fn wait(&self) -> BoxFuture<'_, ()>

Resolve once this backend was stopped, see Self::stop, and holds nothing of any of its devices anymore, see the trait documentation, after which dropping it is dropping nothing of them.

This waits until every request in flight is answered, so it may not be awaited from a future the backend is driving, that is from a request of one of its devices: at best that request is left hanging, at worst it waits for itself. Waiting is all it does, the future it gives back never blocking the thread polling it, as for every future of a backend.

Provided Methods§

Source

fn zmq_event_subscription_change( &self, _args: Spectrum<str>, ) -> BoxFuture<'_, Result<(Spectrum<i32>, Spectrum<str>)>>

Answer the ZmqEventSubscriptionChange command of the admin device, which a client sends to have an event published and to be told where it is published. The argument and the result are those of the command, as a client sends and expects them.

A backend that publishes no event this way answers that it is not implemented, which is what this does by default.

Source

fn event_confirm_subscription( &self, _args: Spectrum<str>, ) -> BoxFuture<'_, Result<()>>

Answer the EventConfirmSubscription command of the admin device, which a client sends periodically to keep the events it subscribed to published. The argument is that of the command, a list of device name, attribute name and event name triplets.

A backend that publishes no event this way answers that it is not implemented, which is what this does by default.

Dyn Compatibility§

This trait is dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety".

Implementors§