File valkey-fake-client-flag.patch of Package valkey.39739
From 2f09b48e766c899addd241ea14f8a7b7606807a9 Mon Sep 17 00:00:00 2001
From: Binbin <binloveplay1314@qq.com>
Date: Wed, 27 Nov 2024 18:02:07 +0800
Subject: [PATCH] Use fake client flag to replace not conn check (#1198)
The fake client flag was introduced in #1063,
we want this to replace all !conn fake client checks.
Signed-off-by: Binbin <binloveplay1314@qq.com>
Signed-off-by: Jacob Murphy <jkmurphy@google.com>
---
src/module.c | 1 +
src/networking.c | 12 ++++++++++--
src/server.c | 3 ++-
src/server.h | 7 ++++---
4 files changed, 17 insertions(+), 6 deletions(-)
diff --git a/src/module.c b/src/module.c
index 938ae6ba70..0149676ef2 100644
--- a/src/module.c
+++ b/src/module.c
@@ -685,6 +685,7 @@ void moduleReleaseTempClient(client *c) {
c->bufpos = 0;
c->raw_flag = 0;
c->flag.module = 1;
+ c->flag.fake = 1;
c->user = NULL; /* Root user */
c->cmd = c->lastcmd = c->realcmd = c->io_parsed_cmd = NULL;
if (c->bstate.async_rm_call_handle) {
diff --git a/src/networking.c b/src/networking.c
index ed4f3582bc..9f4506c5fe 100644
--- a/src/networking.c
+++ b/src/networking.c
@@ -308,7 +308,11 @@ int prepareClientToWrite(client *c) {
* is set. */
if (c->flag.primary && !c->flag.primary_force_reply) return C_ERR;
- if (!c->conn) return C_ERR; /* Fake client for AOF loading. */
+ /* Skip the fake client, such as the fake client for AOF loading.
+ * But CLIENT_ID_CACHED_RESPONSE is allowed since it is a fake client
+ * but has a connection to cache the response. */
+ if (c->flag.fake && c->id != CLIENT_ID_CACHED_RESPONSE) return C_ERR;
+ serverAssert(c->conn);
/* Schedule the client to write the output buffers to the socket, unless
* it should already be setup to do so (it has already pending data). */
@@ -342,6 +346,9 @@ sds aggregateClientOutputBuffer(client *c) {
* It needs be paired with `deleteCachedResponseClient` function to stop caching. */
client *createCachedResponseClient(int resp) {
struct client *recording_client = createClient(NULL);
+ /* It is a fake client but with a connection, setting a special client id,
+ * so we can identify it's a fake cached response client. */
+ recording_client->id = CLIENT_ID_CACHED_RESPONSE;
recording_client->resp = resp;
/* Allocating the `conn` allows to prepare the caching client before adding
* data to the clients output buffer by `prepareClientToWrite`. */
@@ -4422,7 +4429,8 @@ int checkClientOutputBufferLimits(client *c) {
*
* Returns 1 if client was (flagged) closed. */
int closeClientOnOutputBufferLimitReached(client *c, int async) {
- if (!c->conn) return 0; /* It is unsafe to free fake clients. */
+ if (c->flag.fake) return 0; /* It is unsafe to free fake clients. */
+ serverAssert(c->conn);
serverAssert(c->reply_bytes < SIZE_MAX - (1024 * 64));
/* Note that c->reply_bytes is irrelevant for replica clients
* (they use the global repl buffers). */
diff --git a/src/server.c b/src/server.c
index 1bdf2dd9e2..4243185b47 100644
--- a/src/server.c
+++ b/src/server.c
@@ -894,9 +894,10 @@ void updateClientMemoryUsage(client *c) {
}
int clientEvictionAllowed(client *c) {
- if (server.maxmemory_clients == 0 || c->flag.no_evict || !c->conn) {
+ if (server.maxmemory_clients == 0 || c->flag.no_evict || c->flag.fake) {
return 0;
}
+ serverAssert(c->conn);
int type = getClientType(c);
return (type == CLIENT_TYPE_NORMAL || type == CLIENT_TYPE_PUBSUB);
}
diff --git a/src/server.h b/src/server.h
index fceb2894a2..82cec6c7f5 100644
--- a/src/server.h
+++ b/src/server.h
@@ -1102,9 +1102,10 @@ typedef struct {
* Clients are taken in a linked list. */
#define CLIENT_ID_AOF \
- (UINT64_MAX) /* Reserved ID for the AOF client. If you \
- need more reserved IDs use UINT64_MAX-1, \
- -2, ... and so forth. */
+ (UINT64_MAX) /* Reserved ID for the AOF client. If you \
+ need more reserved IDs use UINT64_MAX-1, \
+ -2, ... and so forth. */
+#define CLIENT_ID_CACHED_RESPONSE (UINT64_MAX - 1) /* Client for cached response, see createCachedResponseClient. */
/* Replication backlog is not a separate memory, it just is one consumer of
* the global replication buffer. This structure records the reference of