I'm using r2d2 to pool LDAP connections. Due to oxide-auth not supporting async yet, I'm forced to use blocking version of ldap3 API. I'm using tokio::task::spawn_blocking() to call the code that uses the connection to avoid tokio panicking with: "Cannot start a runtime from within a runtime."
The pool is created in tokio::main() and when the program ends, I'm hit with the panick and the backtrace shows me that it's when the LDAP connections are drop. Which makes sense because the sync connection have a tokio runtime in them which seems to block.
This situation is temporary while waiting for proper async support by oxide-auth, but in the meantime I'd like to avoid the panick because it hides the cause of exiting the program (using anyhow::bail!()).
It is not possible to block in the destructor while inside the Tokio runtime, besides stuff like spawning a thread, doing the blocking there, and joining on that thread, which is super ugly. Tokio makes it difficult for a reason.
When I either bail out or reaching the end of main() (by hitting Ctlr-C to quit gracefully), I have this:
thread 'main' panicked at 'Cannot start a runtime from within a runtime. This happens because a function (like `block_on`) attempted to block the current thread while the thread is being used to drive asynchronous tasks.', C:\Users\geobe\.cargo\registry\src\github.com-1ecc6299db9ec823\tokio-0.2.21\src\runtime\enter.rs:38:5
Not in an orderly manner, but the kernel will reap all open file descriptors and force-close the connections.
LDAP servers are not particularly sensitive to abrupt client connection loss. In a protocol exchange, a complete modification message must be received before any change, and atomicity is guaranteed with entry-level granularity, so partial modification is not an issue (multiple-entry changes are another matter). An operation result message may be lost.