From f5160ed0aa3aa6f9cff9dad5f595ab0927a66406 Mon Sep 17 00:00:00 2001 From: tzongw Date: Wed, 6 Oct 2021 15:15:03 +0800 Subject: [PATCH] improve latency when a client is unblocked by module timer (#9593) Scenario: 1. client block on command `XREAD BLOCK 0 STREAMS mystream $` 2. in a module, calling `XADD mystream * field value` via lua from a timer callback 3. client will receive response after some latency up to 100ms Reason: When `XADD` signal the key `mystream` as ready, `beforeSleep` in next eventloop will call `handleClientsBlockedOnKeys` to unblock the client and add pending data to write but not actually install a write handler, so next redis will block in `aeApiPoll` up to 100ms given `hz` config as default 10, pending data will be sent in another next eventloop by `handleClientsWithPendingWritesUsingThreads`. Calling `handleClientsBlockedOnKeys` before `handleClientsWithPendingWritesUsingThreads` in `beforeSleep` solves the problem. --- src/server.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/server.c b/src/server.c index 2ae3768c8..8ce96a876 100644 --- a/src/server.c +++ b/src/server.c @@ -2941,17 +2941,17 @@ void beforeSleep(struct aeEventLoop *eventLoop) { if (server.aof_state == AOF_ON) flushAppendOnlyFile(0); + /* Try to process blocked clients every once in while. Example: A module + * calls RM_SignalKeyAsReady from within a timer callback (So we don't + * visit processCommand() at all). */ + handleClientsBlockedOnKeys(); + /* Handle writes with pending output buffers. */ handleClientsWithPendingWritesUsingThreads(); /* Close clients that need to be closed asynchronous */ freeClientsInAsyncFreeQueue(); - /* Try to process blocked clients every once in while. Example: A module - * calls RM_SignalKeyAsReady from within a timer callback (So we don't - * visit processCommand() at all). */ - handleClientsBlockedOnKeys(); - /* Disconnect some clients if they are consuming too much memory. */ evictClients();