From a4a412ef5da72e943a04322e05de484ebb7f035a Mon Sep 17 00:00:00 2001 From: Spencer Ferris <3319370+spencewenski@users.noreply.github.com> Date: Wed, 24 Apr 2024 22:16:08 -0700 Subject: [PATCH] Add a yield to prevent `Processor` from hogging redis connections Problem ------- When there are no sidekiq jobs available in redis, there are no `await`s between when `brpop`returns and when the next connection is acquired from the pool. This means tokio's task scheduler doesn't have a chance to switch to another task that's waiting for a connection. Solution -------- Add a `tokio::task::yield_now().await` in the case where there is no actual job to handle. This allows tokio's task scheduler to wake up a different task that's waiting for a connection. https://github.com/film42/sidekiq-rs/issues/43 --- src/processor.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/processor.rs b/src/processor.rs index 2d183d5..0d5f450 100644 --- a/src/processor.rs +++ b/src/processor.rs @@ -122,6 +122,11 @@ impl Processor { let work = self.fetch().await?; if work.is_none() { + // If there is no job to handle, we need to add a `yield_now` in order to allow tokio's + // scheduler to wake up another task that may be waiting to acquire a connection from + // the Redis connection pool. See the following issue for more details: + // https://github.com/film42/sidekiq-rs/issues/43 + tokio::task::yield_now().await; return Ok(WorkFetcher::NoWorkFound); } let mut work = work.expect("polled and found some work");