Skip to main content

drop_database_off_runtime

Function drop_database_off_runtime 

Source
pub fn drop_database_off_runtime(
    db: Arc<RwLock<ObjectDatabase>>,
) -> Option<JoinHandle<()>>
Expand description

Let go of a handle on an object database without parking an async runtime’s worker thread (#1513).

The last handle to go drops every object, and a durable object (a Notification Forwarder, Notification Class, Access Rights object or Audit Log with storage) waits as it drops for the saves it has queued, after putting storage back to the state it serves if a write is still staged (#1363). Dropped in async code, that wait would hold a Tokio worker for as long as storage takes. So if db is the last handle and a Tokio runtime is current, the database drops on the runtime’s blocking pool, and the returned task finishes once it has. Any other handle just lets go and returns None, as does a last one with no runtime current, which drops the database on this thread. A runtime that is shutting down runs nothing more on its blocking pool: Tokio shuts the new task down at once, and the database drops on this thread then too.

A dropped server lets go of its own handle this way once its tasks are done, whether or not it was stopped, and so do the tasks a stop() leaves to settle staged writes and end runs once the application lets go of the database. Any of them may still hold a handle when the application lets go of its clone of BACnetServer::database, so None is the usual outcome. What waits until storage holds the state each object serves is stop, not this. This keeps the application’s own handle, should it be the last, from dropping the objects on a runtime worker: in async code, release it here rather than dropping it.

use bacnet_server::server::drop_database_off_runtime;

let db = std::sync::Arc::clone(server.database());
// ... use the database while the server runs ...
// stop() waits until storage holds what each object serves.
let _ = server.stop().await;
drop(server);
// The server's own tasks may still hold the database; whichever handle
// goes last, it drops off the runtime.
drop(drop_database_off_runtime(db));