diff --git a/src/db.c b/src/db.c index 8511135c6..e397183c9 100644 --- a/src/db.c +++ b/src/db.c @@ -783,6 +783,8 @@ void keysCommand(client *c) { } decrRefCount(keyobj); } + if (c->flags & CLIENT_CLOSE_ASAP) + break; } dictReleaseIterator(di); setDeferredArrayLen(c,replylen,numkeys); diff --git a/src/t_hash.c b/src/t_hash.c index 9ebd99ccc..757ccd4b3 100644 --- a/src/t_hash.c +++ b/src/t_hash.c @@ -956,6 +956,8 @@ void hrandfieldWithCountCommand(client *c, long l, int withvalues) { addReplyBulkCBuffer(c, key, sdslen(key)); if (withvalues) addReplyBulkCBuffer(c, value, sdslen(value)); + if (c->flags & CLIENT_CLOSE_ASAP) + break; } } else if (hash->encoding == OBJ_ENCODING_LISTPACK) { listpackEntry *keys, *vals = NULL; @@ -970,6 +972,8 @@ void hrandfieldWithCountCommand(client *c, long l, int withvalues) { count -= sample_count; lpRandomPairs(hash->ptr, sample_count, keys, vals); hrandfieldReplyWithListpack(c, sample_count, keys, vals); + if (c->flags & CLIENT_CLOSE_ASAP) + break; } zfree(keys); zfree(vals); diff --git a/src/t_set.c b/src/t_set.c index 6a4840676..6d8023f31 100644 --- a/src/t_set.c +++ b/src/t_set.c @@ -1028,6 +1028,8 @@ void srandmemberWithCountCommand(client *c) { else addReplyBulkLongLong(c, entries[i].lval); } + if (c->flags & CLIENT_CLOSE_ASAP) + break; } zfree(entries); return; @@ -1040,6 +1042,8 @@ void srandmemberWithCountCommand(client *c) { } else { addReplyBulkCBuffer(c, str, len); } + if (c->flags & CLIENT_CLOSE_ASAP) + break; } return; } diff --git a/src/t_zset.c b/src/t_zset.c index e0d8509cf..a5627f031 100644 --- a/src/t_zset.c +++ b/src/t_zset.c @@ -4154,6 +4154,8 @@ void zrandmemberWithCountCommand(client *c, long l, int withscores) { addReplyBulkCBuffer(c, key, sdslen(key)); if (withscores) addReplyDouble(c, *(double*)dictGetVal(de)); + if (c->flags & CLIENT_CLOSE_ASAP) + break; } } else if (zsetobj->encoding == OBJ_ENCODING_LISTPACK) { listpackEntry *keys, *vals = NULL; @@ -4167,6 +4169,8 @@ void zrandmemberWithCountCommand(client *c, long l, int withscores) { count -= sample_count; lpRandomPairs(zsetobj->ptr, sample_count, keys, vals); zrandmemberReplyWithListpack(c, sample_count, keys, vals); + if (c->flags & CLIENT_CLOSE_ASAP) + break; } zfree(keys); zfree(vals); diff --git a/tests/unit/obuf-limits.tcl b/tests/unit/obuf-limits.tcl index 38048935a..7eb6def58 100644 --- a/tests/unit/obuf-limits.tcl +++ b/tests/unit/obuf-limits.tcl @@ -211,4 +211,20 @@ start_server {tags {"obuf-limits external:skip"}} { assert_equal "v2" [r get k2] assert_equal "v3" [r get k3] } + + test "Obuf limit, HRANDFIELD with huge count stopped mid-run" { + r config set client-output-buffer-limit {normal 1000000 0 0} + r hset myhash a b + catch {r hrandfield myhash -999999999} e + assert_match "*I/O error*" $e + reconnect + } + + test "Obuf limit, KEYS stopped mid-run" { + r config set client-output-buffer-limit {normal 100000 0 0} + populate 1000 "long-key-name-prefix-of-100-chars-------------------------------------------------------------------" + catch {r keys *} e + assert_match "*I/O error*" $e + reconnect + } }