WAITAOF: Try to wake blocked clients ASAP in the next beforeSleep (#12627)

In case server.fsynced_reploff changed (e.g. flushAppendOnly set it to
server.master_repl_offset in case there was nothing to fsync) we want to
avoid sleeping before the next beforeSleep so we can call
blockedBeforeSleep ASAP.
without that, in case there's no incoming traffic, we could be waiting
for the next cron timer event to wake us up.
This commit is contained in:
guybe7 2023-12-28 16:27:58 +07:00 committed by GitHub
parent 99c468c38c
commit 12b611b374
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 12 additions and 1 deletions

View File

@ -1724,7 +1724,7 @@ void beforeSleep(struct aeEventLoop *eventLoop) {
connTypeProcessPendingData();
/* If any connection type(typical TLS) still has pending unread data don't sleep at all. */
aeSetDontWait(server.el, connTypeHasPendingData());
int dont_sleep = connTypeHasPendingData();
/* Call the Redis Cluster before sleep function. Note that this function
* may change the state of Redis Cluster (from ok to fail or vice versa),
@ -1786,6 +1786,8 @@ void beforeSleep(struct aeEventLoop *eventLoop) {
monotime aof_start_time = getMonotonicUs();
/* Record cron time in beforeSleep. This does not include the time consumed by AOF writing and IO writing below. */
monotime duration_before_aof = aof_start_time - cron_start_time_before_aof;
/* Record the fsync'd offset before flushAppendOnly */
long long prev_fsynced_reploff = server.fsynced_reploff;
/* Write the AOF buffer on disk,
* must be done before handleClientsWithPendingWritesUsingThreads,
@ -1803,6 +1805,11 @@ void beforeSleep(struct aeEventLoop *eventLoop) {
long long fsynced_reploff_pending;
atomicGet(server.fsynced_reploff_pending, fsynced_reploff_pending);
server.fsynced_reploff = fsynced_reploff_pending;
/* If we have blocked [WAIT]AOF clients, and fsynced_reploff changed, we want to try to
* wake them up ASAP. */
if (listLength(server.clients_waiting_acks) && prev_fsynced_reploff != server.fsynced_reploff)
dont_sleep = 1;
}
/* Handle writes with pending output buffers. */
@ -1841,6 +1848,10 @@ void beforeSleep(struct aeEventLoop *eventLoop) {
}
}
/* Don't sleep at all before the next beforeSleep() if needed (e.g. a
* connection has pending data) */
aeSetDontWait(server.el, dont_sleep);
/* Before we are going to sleep, let the threads access the dataset by
* releasing the GIL. Redis main thread will not touch anything at this
* time. */