1. 02 Feb, 2023 2 commits
    • Harkrishn Patro's avatar
      Propagate message to a node only if the cluster link is healthy. (#11752) · fd397568
      Harkrishn Patro authored
      Currently while a sharded pubsub message publish tries to propagate the message across the cluster, a NULL check is missing for clusterLink. clusterLink could be NULL if the link is causing memory beyond the set threshold cluster-link-sendbuf-limit and server terminates the link.
      
      This change introduces two things:
      
      Avoids the engine crashes on the publishing node if a message is tried to be sent to a node and the link is NULL.
      Adds a debugging tool CLUSTERLINK KILL to terminate the clusterLink between two nodes.
      fd397568
    • Florian Weimer's avatar
      deps/jemalloc: Do not force building in gnu99 mode (#11583) · 023ff42f
      Florian Weimer authored
      
      
      Previously, jemalloc was explicitly configured to build in `gnu99` mode. As a result, `<stdatomic.h>` was presumed to be unavailable and never used.
      
      This commit removes explicit build flags configuration and lets `autoconf` determine the supported build flags. In addition, we also no longer build C++ jemalloc code.
      Co-authored-by: default avatarYossi Gottlieb <yossigo@gmail.com>
      023ff42f
  2. 01 Feb, 2023 2 commits
    • Binbin's avatar
      Fix handshake timeout replication test race (#11773) · ffb691f6
      Binbin authored
      Test on x86 + TLS fail with this error:
      ```
      *** [err]: Slave is able to detect timeout during handshake in tests/integration/replication.tcl
      Replica is not able to detect timeout
      ```
      
      The replica logs is:
      ```
       ### Starting test Slave is able to detect timeout during handshake in tests/integration/replication.tcl
      7681:S 05 Jan 2023 00:21:56.635 * Non blocking connect for SYNC fired the event.
      7681:S 05 Jan 2023 00:21:56.638 * Master replied to PING, replication can continue...
      7681:S 05 Jan 2023 00:21:56.638 * Trying a partial resynchronization (request ef70638885500aad12dd673c68ca1541116a59fe:1).
      7681:S 05 Jan 2023 00:22:56.894 # Failed to read response from the server: error:0A000126:SSL routines::unexpected eof while reading
      7681:S 05 Jan 2023 00:22:56.894 # Master did not reply to PSYNC, will try later
      ```
      
      This is another issue that appeared after #11640 was merged. This PR try to fix it.
      The idea is to make it stable in `wait_bgsave`, for example, it may wait until the
      next psync retry in the following situation: `Master did not reply to PSYNC, will try later`
      
      Other than that, the change will make the test more consistent / predictable since
      it'll mean the master is always frozen in the desired state (waiting for repl-diskless-sync-delay
      to happen, rather than earlier stages of the handshake).
      ffb691f6
    • Binbin's avatar
      Document some fields history of CLIENT LIST command (#11729) · e7f35edb
      Binbin authored
      Change history:
      - `user` added in 6.0.0, 0f42447a
      - `argv-mem` and `tot-mem` added in 6.2.0, bea40e6a
      - `redir` added in 6.2.0, dd1f20ed
      - `resp` added in 7.0.0, 7c376398
      - `multi-mem` added in 7.0.0, 2753429c
      - `rbs` and `rbp` added in 7.0.0, 47c51d0c
      - `ssub` added in 7.0.3, 35c2ee87
      e7f35edb
  3. 31 Jan, 2023 1 commit
    • uriyage's avatar
      Optimization: sdsRemoveFreeSpace to avoid realloc on noop (#11766) · 46393f98
      uriyage authored
      
      
      In #7875 (Redis 6.2), we changed the sds alloc to be the usable allocation
      size in order to:
      
      > reduce the need for realloc calls by making the sds implicitly take over
      the internal fragmentation
      
      This change was done most sds functions, excluding `sdsRemoveFreeSpace` and
      `sdsResize`, the reason is that in some places (e.g. clientsCronResizeQueryBuffer)
      we call sdsRemoveFreeSpace when we see excessive free space and want to trim it.
      so if we don't trim it exactly to size, the caller may still see excessive free space and
      call it again and again.
      
      However, this resulted in some excessive calls to realloc, even when there's no need
      and it's gonna be a no-op (e.g. when reducing 15 bytes allocation to 13).
      
      It turns out that a call for realloc with jemalloc can be expensive even if it ends up
      doing nothing, so this PR adds a check using `je_nallocx`, which is cheap to avoid
      the call for realloc.
      
      in addition to that this PR unifies sdsResize and sdsRemoveFreeSpace into common
      code. the difference between them was that sdsResize would avoid using SDS_TYPE_5,
      since it want to keep the string ready to be resized again, while sdsRemoveFreeSpace
      would permit using SDS_TYPE_5 and get an optimal memory consumption.
      now both methods take a `would_regrow` argument that makes it more explicit.
      
      the only actual impact of that is that in clientsCronResizeQueryBuffer we call both sdsResize
      and sdsRemoveFreeSpace for in different cases, and we now prevent the use of SDS_TYPE_5 in both.
      
      The new test that was added to cover this concern used to pass before this PR as well,
      this PR is just a performance optimization and cleanup.
      
      Benchmark:
      `redis-benchmark -c 100 -t set  -d 512 -P 10  -n  100000000`
      on i7-9850H with jemalloc, shows improvement from 1021k ops/sec to 1067k (average of 3 runs).
      some 4.5% improvement.
      Co-authored-by: default avatarOran Agra <oran@redislabs.com>
      46393f98
  4. 30 Jan, 2023 2 commits
    • Madelyn Olson's avatar
      Optimize the performance of cluster slots for non-continuous slots (#11745) · e74a1f3b
      Madelyn Olson authored
      This change improves the performance of cluster slots by removing the deferring lengths that are used. Deferring lengths are used in two contexts, the first is for determining the number of replicas that serve a slot (Added in 6.2 as part of a different performance improvement) and the second is for determining the extra networking options for each node (Added in 7.0). For continuous slots, (e.g. 0-8196) this improvement is very negligible, however it becomes more significant when slots are not continuous (e.g. 0 2 4 6 etc) which can happen in production for various users.
      
      The `cluster slots` command is deprecated in favor of `cluster shards`, but since most clients don't support the new command yet I think it's important to not degrade performance here.
      
      Benchmarking shows about 2x improvement, however I wasn't able to get a coherent TPS number since the benchmark process was being saturated long before Redis was, so had to run with multiple benchmarks and merge results. If needed I can add this to our memtier framework. Instead the next section shows the number of usec per call from the benchmark results, which shows significant improvement as well as having a more coherent response in the CoB.
      
      | | New Code | Old Code | % Improvements
      |----|----|----- |-----
      | Uniform slots| usec_per_call=10.46 | usec_per_call=11.03 | 5.7%
      | Worst case (Only even slots)| usec_per_call=963.80 | usec_per_call=2950.99 | 307%
      
      This change also removes some extra white space that I added a when making a code change for adding hostnames.
      e74a1f3b
    • Qu Chen's avatar
      Fix master client check in expireIfNeeded() for read only replica (#11761) · 6444214c
      Qu Chen authored
      Redis 7.0 introduced new logic in expireIfNeeded() where a read-only replica would never consider a key as expired when replicating commands from the master. See acf3495e. This was done by checking server.current_client with server.master. However, we should instead check for CLIENT_MASTER flag for this logic to be more robust and consistent with the rest of the Redis code base.
      6444214c
  5. 26 Jan, 2023 1 commit
    • Wen Hui's avatar
      update sentinel config condition (#11751) · cc97f4cf
      Wen Hui authored
      The command:
      sentinel config set option value
      and
      sentinel config get option
      
      They should include at least 4 arguments instead of 3,
      This PR fixes this issue.
      the only impact on the client is a different error message 
      cc97f4cf
  6. 25 Jan, 2023 2 commits
  7. 22 Jan, 2023 2 commits
  8. 20 Jan, 2023 2 commits
    • 王卿's avatar
      Remove duplicate code in listAddNodeTail (#11733) · c95ff0f3
      王卿 authored
      Remove duplicate code that removes a node from the tail of a list.
      c95ff0f3
    • Viktor Söderqvist's avatar
      Key as dict entry - memory optimization for sets (#11595) · f3f6f7c0
      Viktor Söderqvist authored
      If a dict has only keys, and no use of values, then a key can be stored directly in a
      dict's hashtable. The key replaces the dictEntry. To distinguish between a key and
      a dictEntry, we only use this optimization if the key is odd, i.e. if the key has the least
      significant bit set. This is true for sds strings, since the sds header is always an odd
      number of bytes.
      
      Dict entries are used as a fallback when there is a hash collision. A special dict entry
      without a value (only key and next) is used so we save one word in this case too.
      
      This saves 24 bytes per set element for larges sets, and also gains some speed improvement
      as a side effect (less allocations and cache misses).
      
      A quick test adding 1M elements to a set using the command below resulted in memory
      usage of 28.83M, compared to 46.29M on unstable.
      That's 18 bytes per set element on average.
      
          eval 'for i=1,1000000,1 do redis.call("sadd", "myset", "x"..i) end' 0
      
      Other changes:
      
      Allocations are ensured to have at least 8 bits alignment on all systems. This affects 32-bit
      builds compiled without HAVE_MALLOC_SIZE (not jemalloc or glibc) in which Redis
      stores the size of each allocation, after this change in 8 bytes instead of previously 4 bytes
      per allocation. This is done so we can reliably use the 3 least significant bits in a pointer to
      encode stuff.
      f3f6f7c0
  9. 16 Jan, 2023 3 commits
    • Oran Agra's avatar
      Obuf limit, exit during loop in *RAND* commands and KEYS (#11676) · b4123663
      Oran Agra authored
      Related to the hang reported in #11671
      Currently, redis can disconnect a client due to reaching output buffer limit,
      it'll also avoid feeding that output buffer with more data, but it will keep
      running the loop in the command (despite the client already being marked for
      disconnection)
      
      This PR is an attempt to mitigate the problem, specifically for commands that
      are easy to abuse, specifically: KEYS, HRANDFIELD, SRANDMEMBER, ZRANDMEMBER.
      The RAND family of commands can take a negative COUNT argument (which is not
      bound to the number of elements in the key), so it's enough to create a key
      with one field, and then these commands can be used to hang redis.
      For KEYS the caller can use the existing keyspace in redis (if big enough).
      b4123663
    • Oran Agra's avatar
      Fix range issues in ZRANDMEMBER and HRANDFIELD (CVE-2023-22458) (#11674) · 16f408b1
      Oran Agra authored
      missing range check in ZRANDMEMBER and HRANDIFLD leading to panic due
      to protocol limitations
      16f408b1
    • Oran Agra's avatar
      Avoid integer overflows in SETRANGE and SORT (CVE-2022-35977) (#11720) · 1ec82e6e
      Oran Agra authored
      Authenticated users issuing specially crafted SETRANGE and SORT(_RO)
      commands can trigger an integer overflow, resulting with Redis attempting
      to allocate impossible amounts of memory and abort with an OOM panic.
      1ec82e6e
  10. 12 Jan, 2023 1 commit
  11. 11 Jan, 2023 6 commits
    • Oran Agra's avatar
      Make dictEntry opaque (#11465) · 12826fa3
      Oran Agra authored
      This PR refactors the abstraction of the dictEntry by making it opaque. This enables future optimizations of the dict implementation without affecting the code using it.
      
      The PR contains 5 commits. More detailed commit messages are found in each commit.
      
      * Make dictEntry opaque
      * Let active expire cycle use dictScan instead of messing with internals
      * activeDefragSdsDict use scan instead of iterator and drop dictSetNext
      * Remove the bucket-cb from dictScan and move dictEntry defrag to dictScanDefrag
      * Move stat_active_defrag_hits increment to activeDefragAlloc
      12826fa3
    • Viktor Söderqvist's avatar
      Move stat_active_defrag_hits increment to activeDefragAlloc · 2bbc8919
      Viktor Söderqvist authored
      instead of passing it around to every defrag function
      2bbc8919
    • Viktor Söderqvist's avatar
      Remove the bucket-cb from dictScan and move dictEntry defrag to dictScanDefrag · b60d33c9
      Viktor Söderqvist authored
      This change deletes the dictGetNext and dictGetNextRef functions, so the
      dict API doesn't expose the next field at all.
      
      The bucket function in dictScan is deleted. A separate dictScanDefrag function
      is added which takes a defrag alloc function to defrag-reallocate the dict entries.
      
      "Dirty" code accessing the dict internals in active defrag is removed.
      
      An 'afterReplaceEntry' is added to dictType, which allows the dict user
      to keep the dictEntry metadata up to date after reallocation/defrag/move.
      
      Additionally, for updating the cluster slot-to-key mapping, after a dictEntry
      has been reallocated, we need to know which db a dict belongs to, so we store
      a pointer to the db in a new metadata section in the dict struct, which is
      a new mechanism similar to dictEntry metadata. This adds some complexity but
      provides better isolation.
      b60d33c9
    • Viktor Söderqvist's avatar
      activeDefragSdsDict use scan instead of iterator and drop dictSetNext · d4e9e0ae
      Viktor Söderqvist authored
      Also delete unused function activeDefragSdsListAndDict
      d4e9e0ae
    • Viktor Söderqvist's avatar
    • Viktor Söderqvist's avatar
      Make dictEntry opaque · c84248b5
      Viktor Söderqvist authored
      Use functions for all accesses to dictEntry (except in dict.c). Dict abuses
      e.g. in defrag.c have been replaced by support functions provided by dict.
      c84248b5
  12. 10 Jan, 2023 3 commits
  13. 08 Jan, 2023 1 commit
  14. 05 Jan, 2023 3 commits
  15. 04 Jan, 2023 4 commits
    • Binbin's avatar
      Make redis-cli support PSYNC command (#11647) · 4ef4c4a6
      Binbin authored
      
      
      The current redis-cli does not support the real PSYNC command, the older
      version of redis-cli can support PSYNC is because that we actually issue
      the SYNC command instead of PSYNC, so it act like SYNC (always full-sync).
      Noted that in this case we will send the SYNC first (triggered by sendSync),
      then send the PSYNC (the one in redis-cli input).
      
      Didn't bother to find which version that the order changed, we send PSYNC
      first (the one in redis-cli input), and then send the SYNC (the one triggered
      by sendSync). So even full-sync is not working anymore, and it will result
      this output (mentioned in issue #11246):
      ```
      psync dummy 0
      Entering replica output mode...  (press Ctrl-C to quit)
      SYNC with master, discarding bytes of bulk transfer until EOF marker...
      Error reading RDB payload while SYNCing
      ```
      
      This PR adds PSYNC support to redis-cli, which can handle +FULLRESYNC and
      +CONTINUE responses, and some examples will follow.
      Co-authored-by: default avatarOran Agra <oran@redislabs.com>
      4ef4c4a6
    • Oran Agra's avatar
      Fix potential issue with Lua argv caching, module command filter and libc realloc (#11652) · c8052122
      Oran Agra authored
      TLDR: solve a problem introduced in Redis 7.0.6 (#11541) with
      RM_CommandFilterArgInsert being called from scripts, which can
      lead to memory corruption.
      
      Libc realloc can return the same pointer even if the size was changed. The code in
      freeLuaRedisArgv had an assumption that if the pointer didn't change, then the
      allocation didn't change, and the cache can still be reused.
      However, if rewriteClientCommandArgument or RM_CommandFilterArgInsert were
      used, it could be that we realloced the argv array, and the pointer didn't change, then
      a consecutive command being executed from Lua can use that argv cache reaching
      beyond its size.
      This was actually only possible with modules, since the decision to realloc was based
      on argc, rather than argv_len.
      c8052122
    • Oran Agra's avatar
      fix handshake timeout replication test race (#11640) · 0ecf6cdc
      Oran Agra authored
      Test on ARM + TLS often fail with this error:
      ```
      *** [err]: Slave is able to detect timeout during handshake in tests/integration/replication.tcl
      Replica is not able to detect timeout
      ```
      https://github.com/redis/redis-extra-ci/actions/runs/3727554226/jobs/6321797837
      
      The replica logs show that in this case the replica got timeout before even getting a response to the PING command (instead of the SYNC command).
      
      it should have shown these:
      ```
      * MASTER <-> REPLICA sync started
      * REPLICAOF 127.0.0.1:22112 enabled ....
      ### Starting test Slave enters handshake in tests/integration/replication.tcl
      * Non blocking connect for SYNC fired the event.
      ```
      then:
      ```
      * Master replied to PING, replication can continue...
      * Trying a partial resynchronization (request 50da9eff70d774f4e6cb723eb4b091440f215772:1).
      ```
      and then hang for 5 seconds:
      ```
      # Timeout connecting to the MASTER...
      * Reconnecting to MASTER 127.0.0.1:21112 after failure
      ```
      
      but instead it got this (looks like it disconnected too early, and then tried to re-connect):
      ```
      10890:M 19 Dec 2022 01:32:54.794 * Ready to accept connections tls
      10890:M 19 Dec 2022 01:32:54.809 - Accepted 127.0.0.1:41047
      10890:M 19 Dec 2022 01:32:54.878 - Reading from client: error:0A000126:SSL routines::unexpected eof while reading
      10890:M 19 Dec 2022 01:32:54.925 - Accepted 127.0.0.1:39207
      10890:S 19 Dec 2022 01:32:55.463 * Before turning into a replica, using my own master parameters to synthesize a cached master: I may be able to synchronize with the new master with just a partial transfer.
      10890:S 19 Dec 2022 01:32:55.463 * Connecting to MASTER 127.0.0.1:24126
      10890:S 19 Dec 2022 01:32:55.463 * MASTER <-> REPLICA sync started
      10890:S 19 Dec 2022 01:32:55.463 * REPLICAOF 127.0.0.1:24126 enabled (user request from 'id=4 addr=127.0.0.1:39207 laddr=127.0.0.1:24125 fd=8 name= age=1 idle=0 flags=N db=9 sub=0 psub=0 ssub=0 multi=-1 qbuf=43 qbuf-free=20431 argv-mem=21 multi-mem=0 rbs=1024 rbp=5 obl=0 oll=0 omem=0 tot-mem=22317 events=r cmd=slaveof user=default redir=-1 resp=2')
      ### Starting test Slave enters handshake in tests/integration/replication.tcl
      10890:S 19 Dec 2022 01:32:55.476 * Non blocking connect for SYNC fired the event.
      10890:S 19 Dec 2022 01:33:00.701 # Failed to read response from the server: (null)         <- note this!!
      10890:S 19 Dec 2022 01:33:00.701 # Master did not respond to command during SYNC handshake
      10890:S 19 Dec 2022 01:33:01.002 * Connecting to MASTER 127.0.0.1:24126
      10890:S 19 Dec 2022 01:33:01.002 * MASTER <-> REPLICA sync started
      ### Starting test Slave is able to detect timeout during handshake in tests/integration/replication.tcl
      10890:S 19 Dec 2022 01:33:05.497 * Non blocking connect for SYNC fired the event.
      10890:S 19 Dec 2022 01:33:05.500 * Master replied to PING, replication can continue...
      10890:S 19 Dec 2022 01:33:05.510 * Trying a partial resynchronization (request 947e1956372a0e6c819cfec51c42cc7979b0c221:1).
      10890:S 19 Dec 2022 01:34:05.833 # Failed to read response from the server: error:0A000126:SSL routines::unexpected eof while reading
      10890:S 19 Dec 2022 01:34:05.833 # Master did not reply to PSYNC, will try later
      ```
      
      This PR sets enables the 5 seconds timeout at a later stage to try and prevent the early disconnection.
      0ecf6cdc
    • zhenwei pi's avatar
      Introduce .is_local method for connection layer (#11672) · dec529f4
      zhenwei pi authored
      
      
      Introduce .is_local method to connection, and implement for TCP/TLS/
      Unix socket, also drop 'int islocalClient(client *c)'. Then we can
      hide the detail into the specific connection types.
      Uplayer tests a connection is local or not by abstract method only.
      Signed-off-by: default avatarzhenwei pi <pizhenwei@bytedance.com>
      Signed-off-by: default avatarzhenwei pi <pizhenwei@bytedance.com>
      dec529f4
  16. 03 Jan, 2023 1 commit
  17. 02 Jan, 2023 1 commit
  18. 01 Jan, 2023 1 commit
    • ranshid's avatar
      reprocess command when client is unblocked on keys (#11012) · 383d902c
      ranshid authored
      *TL;DR*
      ---------------------------------------
      Following the discussion over the issue [#7551](https://github.com/redis/redis/issues/7551
      
      )
      We decided to refactor the client blocking code to eliminate some of the code duplications
      and to rebuild the infrastructure better for future key blocking cases.
      
      
      *In this PR*
      ---------------------------------------
      1. reprocess the command once a client becomes unblocked on key (instead of running
         custom code for the unblocked path that's different than the one that would have run if
         blocking wasn't needed)
      2. eliminate some (now) irrelevant code for handling unblocking lists/zsets/streams etc...
      3. modify some tests to intercept the error in cases of error on reprocess after unblock (see
         details in the notes section below)
      4. replace '$' on the client argv with current stream id. Since once we reprocess the stream
         XREAD we need to read from the last msg and not wait for new msg  in order to prevent
         endless block loop. 
      5. Added statistics to the info "Clients" section to report the:
         * `total_blocking_keys` - number of blocking keys
         * `total_blocking_keys_on_nokey` - number of blocking keys which have at least 1 client
            which would like
         to be unblocked on when the key is deleted.
      6. Avoid expiring unblocked key during unblock. Previously we used to lookup the unblocked key
         which might have been expired during the lookup. Now we lookup the key using NOTOUCH and
         NOEXPIRE to avoid deleting it at this point, so propagating commands in blocked.c is no longer needed.
      7. deprecated command flags. We decided to remove the CMD_CALL_STATS and CMD_CALL_SLOWLOG
         and make an explicit verification in the call() function in order to decide if stats update should take place.
         This should simplify the logic and also mitigate existing issues: for example module calls which are
         triggered as part of AOF loading might still report stats even though they are called during AOF loading.
      
      *Behavior changes*
      ---------------------------------------------------
      
      1. As this implementation prevents writing dedicated code handling unblocked streams/lists/zsets,
      since we now re-process the command once the client is unblocked some errors will be reported differently.
      The old implementation used to issue
      ``UNBLOCKED the stream key no longer exists``
      in the following cases:
         - The stream key has been deleted (ie. calling DEL)
         - The stream and group existed but the key type was changed by overriding it (ie. with set command)
         - The key not longer exists after we swapdb with a db which does not contains this key
         - After swapdb when the new db has this key but with different type.
         
      In the new implementation the reported errors will be the same as if the command was processed after effect:
      **NOGROUP** - in case key no longer exists, or **WRONGTYPE** in case the key was overridden with a different type.
      
      2. Reprocessing the command means that some checks will be reevaluated once the
      client is unblocked.
      For example, ACL rules might change since the command originally was executed and
      will fail once the client is unblocked.
      Another example is OOM condition checks which might enable the command to run and
      block but fail the command reprocess once the client is unblocked.
      
      3. One of the changes in this PR is that no command stats are being updated once the
      command is blocked (all stats will be updated once the client is unblocked). This implies
      that when we have many clients blocked, users will no longer be able to get that information
      from the command stats. However the information can still be gathered from the client list.
      
      **Client blocking**
      ---------------------------------------------------
      
      the blocking on key will still be triggered the same way as it is done today.
      in order to block the current client on list of keys, the call to
      blockForKeys will still need to be made which will perform the same as it is today:
      
      *  add the client to the list of blocked clients on each key
      *  keep the key with a matching list node (position in the global blocking clients list for that key)
         in the client private blocking key dict.
      *  flag the client with CLIENT_BLOCKED
      *  update blocking statistics
      *  register the client on the timeout table
      
      **Key Unblock**
      ---------------------------------------------------
      
      Unblocking a specific key will be triggered (same as today) by calling signalKeyAsReady.
      the implementation in that part will stay the same as today - adding the key to the global readyList.
      The reason to maintain the readyList (as apposed to iterating over all clients blocked on the specific key)
      is in order to keep the signal operation as short as possible, since it is called during the command processing.
      The main change is that instead of going through a dedicated code path that operates the blocked command
      we will just call processPendingCommandsAndResetClient.
      
      **ClientUnblock (keys)**
      ---------------------------------------------------
      
      1. Unblocking clients on keys will be triggered after command is
         processed and during the beforeSleep
      8. the general schema is:
      9. For each key *k* in the readyList:
      ```            
      For each client *c* which is blocked on *k*:
                  in case either:
      	          1. *k* exists AND the *k* type matches the current client blocking type
      	  	      OR
      	          2. *k* exists and *c* is blocked on module command
      	    	      OR
      	          3. *k* does not exists and *c* was blocked with the flag
      	             unblock_on_deleted_key
                       do:
                                        1. remove the client from the list of clients blocked on this key
                                        2. remove the blocking list node from the client blocking key dict
                                        3. remove the client from the timeout list
                                        10. queue the client on the unblocked_clients list
                                        11. *NEW*: call processCommandAndResetClient(c);
      ```
      *NOTE:* for module blocked clients we will still call the moduleUnblockClientByHandle
                    which will queue the client for processing in moduleUnblockedClients list.
      
      **Process Unblocked clients**
      ---------------------------------------------------
      
      The process of all unblocked clients is done in the beforeSleep and no change is planned
      in that part.
      
      The general schema will be:
      For each client *c* in server.unblocked_clients:
      
              * remove client from the server.unblocked_clients
              * set back the client readHandler
              * continue processing the pending command and input buffer.
      
      *Some notes regarding the new implementation*
      ---------------------------------------------------
      
      1. Although it was proposed, it is currently difficult to remove the
         read handler from the client while it is blocked.
         The reason is that a blocked client should be unblocked when it is
         disconnected, or we might consume data into void.
      
      2. While this PR mainly keep the current blocking logic as-is, there
         might be some future additions to the infrastructure that we would
         like to have:
         - allow non-preemptive blocking of client - sometimes we can think
           that a new kind of blocking can be expected to not be preempt. for
           example lets imagine we hold some keys on disk and when a command
           needs to process them it will block until the keys are uploaded.
           in this case we will want the client to not disconnect or be
           unblocked until the process is completed (remove the client read
           handler, prevent client timeout, disable unblock via debug command etc...).
         - allow generic blocking based on command declared keys - we might
           want to add a hook before command processing to check if any of the
           declared keys require the command to block. this way it would be
           easier to add new kinds of key-based blocking mechanisms.
      Co-authored-by: default avatarOran Agra <oran@redislabs.com>
      Signed-off-by: default avatarRan Shidlansik <ranshid@amazon.com>
      383d902c
  19. 28 Dec, 2022 1 commit
    • sundb's avatar
      Remove unnecessary updateClientMemUsageAndBucket() when feeding monitors (#11657) · af0a4fe2
      sundb authored
      This call is introduced in #8687, but became irrelevant in #11348, and is currently a no-op.
      The fact is that #11348 an unintended side effect, which is that even if the client eviction config
      is enabled, there are certain types of clients for which memory consumption is not accurately
      tracked, and so unlike normal clients, their memory isn't reported correctly in INFO.
      af0a4fe2
  20. 23 Dec, 2022 1 commit
    • Madelyn Olson's avatar
      Harden init-tests for cluster tests (#11635) · 7379d221
      Madelyn Olson authored
      Attempt to harden cluster init-tests by doing two things:
      * Retry up to 3 times to join the cluster. Cluster meet is entirely idempotent, so it should stabilize if we missed a node.
      * Validate the connection is actually established, not just exists in the cluster list. Nodes can exist in handshake, but might later get dropped.
      7379d221