Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Avoid using futures'
block_on
in the request database guard
The request guard works by sending on a channel when it is dropped. Since we can't do async code in `Drop::drop`, I was using `futures::executor::block_on` under the (false!) impression that this *specific* usecase would not be a problem as we are always pulling from that channel. However, sending on a channel can result in `Pending` when the Tokio worker's cooperative budget is exhausted, even if the queue is completely empty! A simple example: ```rust // Drain the budget while task::consume_budget().now_or_never().is_some() {} // Try to use more budget than we have and block forever futures::executor::block_on(tx.send(42u8)).unwrap(); ``` This `Pending` will never resolve because we are no longer running the Tokio runtime so it will never see an `.await` and replenish the budget. With enough bad luck, all the worker threads get stuck like this and the entire system becomes unavailable. There are a number of possible workarounds, but the least invasive is to punt the final logging off to a Tokio task and let it happen out-of-band. Technically this will make the timing a little bit less accurate, but I was never worried about exact nanoseconds anyway.
- Loading branch information