This commit adds support for the "touches-arbitrary-keys" command flag
in Redis modules, allowing module commands to be properly marked when
they modify keys not explicitly provided as arguments, to avoid wrapping
replicated commands with MULTI/EXEC.
Changes:
- Added "touches-arbitrary-keys" flag parsing in
commandFlagsFromString()
- Updated module command documentation to describe the new flag
- Added test implementation in zset module with zset.delall command to
demonstrate and verify the flag functionality
The zset.delall command serves as a test case that scans the keyspace
and deletes all zset-type keys, properly using the new flag since it
modifies keys not provided via argv.
This commit adds a new `zset.delall` command to the zset test module
that iterates through the keyspace and deletes all keys of type "zset".
Key changes:
- Added zset_delall() function that uses RedisModule_Scan to iterate
through all keys in the keyspace
- Added zset_delall_callback() that checks each key's type and deletes
zset keys using RedisModule_Call with "DEL" command
- Registered the new command with "write touches-arbitrary-keys" flags
since it modifies arbitrary keys not provided via argv
- Added support for "touches-arbitrary-keys" flag in module command
parsing
- Added comprehensive tests for the new functionality
The command returns the number of deleted zset keys and properly handles
replication by using the "s!" format specifier with RedisModule_Call to
ensure DEL commands are replicated to slaves and AOF.
Usage: ZSET.DELALL
Returns: Integer count of deleted zset keys
This bug was introduced by https://github.com/redis/redis/pull/14130
found by @oranagra
### Summary
Because `s->cgroup_ref` is created at runtime the first time a consumer
group is linked with a message, but it is not released when all
references are removed.
However, after `debug reload` or restart, if the PEL is empty (meaning
no consumer group is referencing any message), `s->cgroup_ref` will not
be recreated.
As a result, when executing XADD or XTRIM with `ACKED` option and
checking whether a message that is being read but has not been ACKed can
be deleted, the cgroup_ref being NULL will cause a crash.
### Code Path
```
xaddCommand -> streamTrim -> streamEntryIsReferenced
```
### Solution
Check if `s->cgroup_ref` is NULL in streamEntryIsReferenced().
Fix https://github.com/redis/redis/issues/14267
This bug was introduced by https://github.com/redis/redis/pull/13495
### Summary
When a replica clears a large database, it periodically calls
processEventsWhileBlocked() in the replicationEmptyDbCallback() callback
during the key deletion process.
If defragmentation is enabled, this means that active defrag can be
triggered while the database is being deleted.
The defragmentation process may also modify the database at this time,
which could lead to crashes when the database is accessed after
defragmentation.
Code Path:
```
replicationEmptyDbCallback() -> processEventsWhileBlocked() -> whileBlockedCron() -> defragWhileBlocked()
```
### Solution
This PR temporarily disables active defrag before emptying the database,
then restores the active defrag setting after the empty is complete.
---------
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
### Description
This PR introduces support for using the processor clock
(USE_PROCESSOR_CLOCK) for the RISC-V architecture in the
`src/monotonic.c`. The change adds conditional compilation code enabling
Redis to utilize the RISC-V processor clock for monotonic timing,
improving time measurement accuracy and consistency on RISC-V platforms.
### Motivation
Currently, Redis's monotonic clock implementation lacks explicit
handling for RISC-V processor clocks, adding USE_PROCESSOR_CLOCK support
helps Redis better leverage hardware capabilities on RISC-V, enhancing
portability and performance.
### Changes
- Added `USE_PROCESSOR_CLOCK` macro and related support code guarded by
RISC-V specific macros in `src/monotonic.c`.
- No existing functionality is changed for other architectures.
### Testing
- Build success, redis-server and redis-benchmark run all well on
**Sophgo SG2042 RISC-V CPU**.
- It is not easy to test the performance improvement brought by
`USE_PROCESSOR_CLOCK` using redis-benchmark, so we wrote a
micro-benchmark `monotonic_bench.c` test on RISC-V.
From `monotonic_bench` on **Sophgo SG2042 RISC-V CPU**, we can see that
the RISC-V processor clock implementation is approximately **2.78 times
faster** than the POSIX monotonic clock method on this platform.
### Notes
- No impact on existing Redis platforms. Enables improved timing for
RISC-V users which is critical for latency measurements, timeouts, and
other internal Redis timing logic.
- This change aligns with Redis’s strategy of supporting diverse
hardware platforms with minimal footprint, and it preserves backward
compatibility with existing code.
- To use `USE_PROCESSOR_CLOCK` on RISC-V, complie redis with `make
CFLAGS="-DUSE_PROCESSOR_CLOCK"`.
Signed-off-by: Huang Zheng <huang.zheng@sanechips.com.cn>
When Redis is shut down uncleanly (e.g., due to power loss), invalid
bytes may remain at the end of the AOF file. Currently, Redis detects
such corruption only after parsing most of the AOF, leading to delayed
error detection and increased downtime. Manual recovery via
`redis-check-aof --fix` is also time-consuming.
This fix introduces two new options to improve resilience and reduce
downtime:
- `aof-load-broken`: Enables automatic detection and repair of broken
AOF tails.
- `aof-load-broken-max-size`: Sets a maximum threshold (in bytes) for
the corrupted tail size that Redis will attempt to fix automatically
without requiring user intervention.
Hi, this PR implements the following changes:
1. The EPSILON option of VSIM is now documented.
2. The EPSILON behavior was fixed: the score was incorrectly divided by
two in the meaning, with a 0-2 interval provided by the underlying
cosine similarity, instead of the 0-1 interval. So an EPSILON of 0.2
only returned elements with a distance between 1 and 0.9 instead of 1
and 0.8. This is a *breaking change* but the command was not documented
so far, and it is a fix, as the user sees the similarity score so was a
total mismatch. I believe this fix should definitely be back ported as
soon as possible.
3. There are now tests.
Thanks for checking,
Salvatore
Fix https://github.com/redis/redis/issues/14208
As mentioned in the above issue, RM_GetCommandKeysWithFlags could have
memory leak when the number of keys is larger than MAX_KEYS_BUFFER. This
PR fixes it by calling getKeysFreeResult before the function's return. A
TCL testcase is created to verify the fix.
getSlotOrReply() is used by the `CLUSTER SLOT-STATS` command but is
defined
in cluster_legacy.c which might not be present in all build
configurations.
CI / build-libc-malloc (push) Has been cancelledDetails
CI / build-centos-jemalloc (push) Has been cancelledDetails
CI / build-old-chain-jemalloc (push) Has been cancelledDetails
Codecov / code-coverage (push) Has been cancelledDetails
External Server Tests / test-external-standalone (push) Has been cancelledDetails
External Server Tests / test-external-cluster (push) Has been cancelledDetails
External Server Tests / test-external-nodebug (push) Has been cancelledDetails
Spellcheck / Spellcheck (push) Has been cancelledDetails
Noticed we assume there are at least 3 arguments since we access to
index 2 in the if and only later check the argc.
Moved the argc check to the start of the if so the code will be a bit
safer.
CI / build-libc-malloc (push) Has been cancelledDetails
CI / build-centos-jemalloc (push) Has been cancelledDetails
CI / build-old-chain-jemalloc (push) Has been cancelledDetails
Codecov / code-coverage (push) Has been cancelledDetails
External Server Tests / test-external-standalone (push) Has been cancelledDetails
External Server Tests / test-external-cluster (push) Has been cancelledDetails
External Server Tests / test-external-nodebug (push) Has been cancelledDetails
Spellcheck / Spellcheck (push) Has been cancelledDetails
In cluster mode with modules, for a given key, the slot resolution for
the KEYSIZES histogram update was incorrect. As a result, the histogram
might gracefully ignored those keys instead or update the wrong slot
histogram.
CI / build-libc-malloc (push) Waiting to runDetails
CI / build-centos-jemalloc (push) Waiting to runDetails
CI / build-old-chain-jemalloc (push) Waiting to runDetails
Codecov / code-coverage (push) Waiting to runDetails
External Server Tests / test-external-standalone (push) Waiting to runDetails
External Server Tests / test-external-cluster (push) Waiting to runDetails
External Server Tests / test-external-nodebug (push) Waiting to runDetails
Spellcheck / Spellcheck (push) Waiting to runDetails
Introduced by https://github.com/redis/redis/issues/13806
Fixed a crash in the MOVE command when moving hash objects that have
both key expiration and field expiration.
The issue occurred in the following scenario:
1. A hash has both key expiration and field expiration.
2. During MOVE command, `setExpireByLink()` is called to set the
expiration time for the target hash, which may reallocate the kvobj of
hash.
3. Since the hash has field expiration, `hashTypeAddToExpires()` is
called to update the minimum field expiration time
Issue:
However, the kvobj pointer wasn't updated with the return value from
`setExpireByLink()`, causing `hashTypeAddToExpires()` to use freed
memory.
CI / build-libc-malloc (push) Has been cancelledDetails
CI / build-centos-jemalloc (push) Has been cancelledDetails
CI / build-old-chain-jemalloc (push) Has been cancelledDetails
Codecov / code-coverage (push) Has been cancelledDetails
External Server Tests / test-external-standalone (push) Has been cancelledDetails
External Server Tests / test-external-cluster (push) Has been cancelledDetails
External Server Tests / test-external-nodebug (push) Has been cancelledDetails
Spellcheck / Spellcheck (push) Has been cancelledDetails
Fixes#14218
Before, we replicate HINCRBYFLOAT as an HSET command with the final
value in order to make sure that differences in float precision or
formatting will not create differences in replicas or after an AOF
restart.
However, on the replica side, if the field has an expiration time, HSET
will remove it, even though the master retains it. This leads to
inconsistencies between the master and the replica.
To address this, we now use the HSETEX command with the KEEPTTL flag
instead of HSET, ensuring that the field’s TTL is preserved.
This bug was introduced in version 7.4, but the HSETEX command was only
implemented from version 8.0. Therefore, this patch does not fix the
issue in the 7.4 branch, a separate commit is needed to address it in
7.4.
Fixed bug where SET key value after SET key value EX seconds would not
remove the TTL as expected. The issue was in dbSetValue()'s optimization
path which was missing TTL handling logic.
This API complements module subscribe by enabling modules to unsubscribe
from specific keyspace event notifications when they are no longer
needed.
This helps reduce performance overhead and unnecessary callback
invocations.
The function matches subscriptions based on event mask, callback
pointer,
and module identity. If a matching subscription is found, it is removed.
Returns REDISMODULE_OK if a subscription was successfully removed,
otherwise REDISMODULE_ERR.
CI / build-libc-malloc (push) Waiting to runDetails
CI / build-centos-jemalloc (push) Waiting to runDetails
CI / build-old-chain-jemalloc (push) Waiting to runDetails
Codecov / code-coverage (push) Waiting to runDetails
External Server Tests / test-external-standalone (push) Waiting to runDetails
External Server Tests / test-external-cluster (push) Waiting to runDetails
External Server Tests / test-external-nodebug (push) Waiting to runDetails
Spellcheck / Spellcheck (push) Waiting to runDetails
1) Fix the timeout of `Active defrag big keys: standalone`
Using a pipe to write commands may cause the write to block if the read
buffer becomes full.
2) Fix the failure of `Main db not affected when fail to diskless load`
test
If the master was killed in slow environment, then after
`cluster-node-timeout` (3s in our test), running keyspace commands on
the replica will get a CLUSTERDOWN error.
3) Fix the failure of `Test shutdown hook` test
ASAN can intercept a signal, so I guess that when we send SIGCONT after
SIGTERM to kill the server, it might start doing some work again,
causing the process to close very slowly.
CI / build-libc-malloc (push) Has been cancelledDetails
CI / build-centos-jemalloc (push) Has been cancelledDetails
CI / build-old-chain-jemalloc (push) Has been cancelledDetails
Codecov / code-coverage (push) Has been cancelledDetails
External Server Tests / test-external-standalone (push) Has been cancelledDetails
External Server Tests / test-external-cluster (push) Has been cancelledDetails
External Server Tests / test-external-nodebug (push) Has been cancelledDetails
Spellcheck / Spellcheck (push) Has been cancelledDetails
This PR is based on https://github.com/valkey-io/valkey/pull/2117
When a client is blocked by something like `CLIENT PAUSE`, we should not
allow `CLIENT UNBLOCK timeout` to unblock it, since some blocking types
does not has the timeout callback, it will trigger a panic in the core,
people should use `CLIENT UNPAUSE` to unblock it.
Also using `CLIENT UNBLOCK error` is not right, it will return a
UNBLOCKED error to the command, people don't expect a `SET` command to
get an error.
So in this commit, in these cases, we will return 0 to `CLIENT UNBLOCK`
to indicate the unblock is fail. The reason is that we assume that if a
command doesn't expect to be timedout, it also doesn't expect to be
unblocked by `CLIENT UNBLOCK`.
The old behavior of the following command will trigger panic in timeout
and get UNBLOCKED error in error. Under the new behavior, client unblock
will get the result of 0.
```
client 1> client pause 100000 write
client 2> set x x
client 1> client unblock 2 timeout
or
client 1> client unblock 2 error
```
---------
Signed-off-by: Binbin <binloveplay1314@qq.com>
Co-authored-by: Binbin <binloveplay1314@qq.com>
Refactor use of `dictGetIterator()/dictSafeGetIterator()/listGetIterator()` to
`dictInitIterator()/dictInitSafeIterator()/listRewind()` respectively which
don't allocate memory.
CI / build-libc-malloc (push) Has been cancelledDetails
CI / build-centos-jemalloc (push) Has been cancelledDetails
CI / build-old-chain-jemalloc (push) Has been cancelledDetails
Codecov / code-coverage (push) Has been cancelledDetails
External Server Tests / test-external-standalone (push) Has been cancelledDetails
External Server Tests / test-external-cluster (push) Has been cancelledDetails
External Server Tests / test-external-nodebug (push) Has been cancelledDetails
Spellcheck / Spellcheck (push) Has been cancelledDetails
For security vulnerability patches released under Redis Open Source 7.4
and thereafter, Redis permits users of earlier versions (7.2 and prior)
to access patches under the BSD3 license noted in REDISCONTRIBUTIONS.txt
instead of the full license requirements described in LICENSE.txt.
After #13816, we added defragmentation support for moduleDict, which
significantly increased global data size.
As a result, the defragmentation tests for non-global data were
affected.
Now, we move the creation of global data to before the global data test
to avoid it interfering with other tests.
Fixed the simple key test failure due to forgetting to reset stats.
CI / build-libc-malloc (push) Waiting to runDetails
CI / build-centos-jemalloc (push) Waiting to runDetails
CI / build-old-chain-jemalloc (push) Waiting to runDetails
Codecov / code-coverage (push) Waiting to runDetails
External Server Tests / test-external-standalone (push) Waiting to runDetails
External Server Tests / test-external-cluster (push) Waiting to runDetails
External Server Tests / test-external-nodebug (push) Waiting to runDetails
Spellcheck / Spellcheck (push) Has been cancelledDetails
This PR is based on https://github.com/valkey-io/valkey/pull/2109
When we refactored the blocking framework we introduced the client
reprocessing infrastructure. In cases the client was blocked on keys, it
will attempt to reprocess the command. One challenge was to keep track
of the command timeout, since we are reprocessing and do not want to
re-register the client with a fresh timeout each time. The solution was
to consider the client reprocessing flag when the client is
blockedOnKeys:
```c
if (!(c->flags & CLIENT_REPROCESSING_COMMAND)) {
/* If the client is re-processing the command, we do not set the timeout
* because we need to retain the client's original timeout. */
c->bstate.timeout = timeout;
}
```
However, this introduced a new issue. There are cases where the client
will consecutive blocking of different types for example:
```
CLIENT PAUSE 10000 ALL
BZPOPMAX zset 1
```
would have the client blocked on the zset endlessly if nothing will be
written to it.
**Credits to @uriyage for locating this with his fuzzer testing**
The suggested solution is to only flag the client when it is
specifically unblocked on keys.
Signed-off-by: Ran Shidlansik <ranshid@amazon.com>
Co-authored-by: Ran Shidlansik <ranshid@amazon.com>
Co-authored-by: Binbin <binloveplay1314@qq.com>
CI / build-libc-malloc (push) Has been cancelledDetails
CI / build-centos-jemalloc (push) Has been cancelledDetails
CI / build-old-chain-jemalloc (push) Has been cancelledDetails
Codecov / code-coverage (push) Has been cancelledDetails
External Server Tests / test-external-standalone (push) Has been cancelledDetails
External Server Tests / test-external-cluster (push) Has been cancelledDetails
External Server Tests / test-external-nodebug (push) Has been cancelledDetails
Spellcheck / Spellcheck (push) Has been cancelledDetails
Since INFO command can create a large amount of memory usage, it may
further increase the peak memory.
Therefore, we should get the peak memory after deleting the large
string.
VRANDMEMBER had a bug when exactly two elements where present in the
vector set: we selected a fixed number of random paths to take, and this
will lead always to the same element. This PR should be kindly
back-ported to Redis 8.x.
CI / build-libc-malloc (push) Waiting to runDetails
CI / build-centos-jemalloc (push) Waiting to runDetails
CI / build-old-chain-jemalloc (push) Waiting to runDetails
Codecov / code-coverage (push) Waiting to runDetails
External Server Tests / test-external-standalone (push) Waiting to runDetails
External Server Tests / test-external-cluster (push) Waiting to runDetails
External Server Tests / test-external-nodebug (push) Waiting to runDetails
Spellcheck / Spellcheck (push) Waiting to runDetails
Hello, this is a patch that improves vector sets in two ways:
1. It makes the RDB format compatible with big endian machines: yeah,
they are non existent nowadays, but still it is better to be correct.
The behavior remains unchanged in little endian systems, it only changes
what happens in big endian systems in order for it to load and emit the
exact same format produced by little endian. The implementation was
*already largely safe* but for one detail.
2. More importantly, this PR saves nodes worst link score / index in a
backward compatible way, introducing also versioning information for the
serialized node encoding, that could be useful in the future. With this
information, that in the past was not saved for a programming error
(mine), there is no longer need to compute the worst link info at
runtime when loading data. This results in a speed improvement of about
30% when loading data from disk / RESTORE. The saving performance is
unaffected.
The patch was tested with care to be sure that data produced with old
vector sets implementations are loaded without issues (that is, the
backward compatibility was hand-tested). The new code is tested by the
persistence test already in the test suite, so no new test was added.
CI / build-libc-malloc (push) Waiting to runDetails
CI / build-centos-jemalloc (push) Waiting to runDetails
CI / build-old-chain-jemalloc (push) Waiting to runDetails
Codecov / code-coverage (push) Waiting to runDetails
External Server Tests / test-external-standalone (push) Waiting to runDetails
External Server Tests / test-external-cluster (push) Waiting to runDetails
External Server Tests / test-external-nodebug (push) Waiting to runDetails
Spellcheck / Spellcheck (push) Waiting to runDetails
## What
Add new keyspace notification event types
- OVERWRITTEN - emitted when the value of a key is completely
overwritten
- TYPE_CHANGED - when the value of a key's type changes
Used in Pub/Sub KSN mechanism. Also added module hooks for the new
types.
## Motivation
Many commands overwrite the value of a key. F.e SET completely
overwrites the value of any key, even its type. Other commands that have
the REPLACE parameter also do so.
This commit gives more granularity over following such events.
Specific use-case at hand was module that is subscribed to string events
for the sole purpose of checking if hash keys get converted to strings
via the `SET` command. Subscribing to `type_changed` event not only
removes the need to subscribe to string events but is also more correct
as not only `SET` can change the type of a key.
## List of commands emitting the new events
* SET
* MSET
* COPY
* RESTORE
* RENAME
* BITOP
Each type with STORE operation:
* SORT
* S*STORE
* Z*STORE
* GEORADIUS
* GEOSEARCHSTORE
## Usage example
### pub-sub
Emit overwritten and type-changed events...
```
$ redis-server --notify-keyspace-events KEoc
```
Generate an overwritten event that also changes the type of a key...
```
$ redis-cli
127.0.0.1:6379> lpush l 1 2 3
(integer) 3
127.0.0.1:6379> set l x
OK
```
Subscribe to the events...
```
$ ./src/redis-cli
127.0.0.1:6379> psubscribe *
1) "psubscribe"
2) "*"
3) (integer) 1
1) "pmessage"
2) "*"
3) "__keyspace@0__:l"
4) "overwritten"
1) "pmessage"
2) "*"
3) "__keyevent@0__:overwritten"
4) "l"
1) "pmessage"
2) "*"
3) "__keyspace@0__:l"
4) "type_changed"
1) "pmessage"
2) "*"
3) "__keyevent@0__:type_changed"
4) "l"
```
### Modules
As with any other KSN type subscribe to the appropriate events
```
RedisModule_SubscribeToKeyspaceEvents(
ctx,
REDISMODULE_NOTIFY_OVERWRITTEN | REDISMODULE_NOTIFY_TYPE_CHANGED | ...
notificationCallback
);
```
## Implementation notes
Most of the cases are handled in `setKeyByLink` but for some commands
overwriting had to be manually checked - specifically `RESTORE`, `COPY`
and `RENAME` manually call `dbAddInternal`
CI / build-libc-malloc (push) Waiting to runDetails
CI / build-centos-jemalloc (push) Waiting to runDetails
CI / build-old-chain-jemalloc (push) Waiting to runDetails
Codecov / code-coverage (push) Waiting to runDetails
External Server Tests / test-external-standalone (push) Waiting to runDetails
External Server Tests / test-external-cluster (push) Waiting to runDetails
External Server Tests / test-external-nodebug (push) Waiting to runDetails
Spellcheck / Spellcheck (push) Waiting to runDetails
This PR is based on: https://github.com/valkey-io/valkey/pull/2229
When calling the command `EVAL error{} 0`, Redis crashes with the
following stack trace. This patch ensures we never leave the
`err_info.msg` field null when we fail to extract a proper error
message.
---------
Signed-off-by: Fusl <fusl@meo.ws>
Signed-off-by: Binbin <binloveplay1314@qq.com>
Co-authored-by: Fusl <fusl@meo.ws>
Co-authored-by: Binbin <binloveplay1314@qq.com>
CI / build-libc-malloc (push) Waiting to runDetails
CI / build-centos-jemalloc (push) Waiting to runDetails
CI / build-old-chain-jemalloc (push) Waiting to runDetails
Codecov / code-coverage (push) Waiting to runDetails
External Server Tests / test-external-standalone (push) Waiting to runDetails
External Server Tests / test-external-cluster (push) Waiting to runDetails
External Server Tests / test-external-nodebug (push) Waiting to runDetails
Spellcheck / Spellcheck (push) Waiting to runDetails
The SHA256 checksums for Rust 1.88.0 were incorrect, causing checksum
verification failures during installation. Updated with the correct
official checksums from https://static.rust-lang.org/dist/:
- x86_64-unknown-linux-gnu:
7b5437c1d18a174faae253a18eac22c32288dccfc09ff78d5ee99b7467e21bca
- x86_64-unknown-linux-musl:
200bcf3b5d574caededba78c9ea9d27e7afc5c6df4154ed0551879859be328e1
- aarch64-unknown-linux-gnu:
d5decc46123eb888f809f2ee3b118d13586a37ffad38afaefe56aa7139481d34
- aarch64-unknown-linux-musl:
f8b3a158f9e5e8cc82e4d92500dd2738ac7d8b5e66e0f18330408856235dec35
CI / build-libc-malloc (push) Waiting to runDetails
CI / build-centos-jemalloc (push) Waiting to runDetails
CI / build-old-chain-jemalloc (push) Waiting to runDetails
Codecov / code-coverage (push) Waiting to runDetails
External Server Tests / test-external-standalone (push) Waiting to runDetails
External Server Tests / test-external-cluster (push) Waiting to runDetails
External Server Tests / test-external-nodebug (push) Waiting to runDetails
Spellcheck / Spellcheck (push) Waiting to runDetails
Recent [PR](https://github.com/redis/redis/pull/14051) causes MSan to
fail during daily CI with uninitialized value warning.
It is not a bug per se as the uninitialized member is dependent on
another member not being NULL.
With this PR now MSan does not complain.
CI / build-libc-malloc (push) Waiting to runDetails
CI / build-centos-jemalloc (push) Waiting to runDetails
CI / build-old-chain-jemalloc (push) Waiting to runDetails
Codecov / code-coverage (push) Waiting to runDetails
External Server Tests / test-external-standalone (push) Waiting to runDetails
External Server Tests / test-external-cluster (push) Waiting to runDetails
External Server Tests / test-external-nodebug (push) Waiting to runDetails
Spellcheck / Spellcheck (push) Waiting to runDetails
# Problem
Some redis modules need to call `CONFIG GET/SET` commands. Server may be
ran with `rename-command CONFIG ""`(or something similar) which leads to
the module being unable to access the config.
# Solution
Added new API functions for use by modules
```
RedisModuleConfigIterator* RedisModule_GetConfigIterator(RedisModuleCtx *ctx, const char *pattern);
void RedisModule_ReleaseConfigIterator(RedisModuleCtx *ctx, RedisModuleConfigIterator *iter);
const char *RedisModule_ConfigIteratorNext(RedisModuleConfigIterator *iter);
int RedisModule_GetConfigType(const char *name, RedisModuleConfigType *res);
int RedisModule_GetBoolConfig(RedisModuleCtx *ctx, const char *name, int *res);
int RedisModule_GetConfig(RedisModuleCtx *ctx, const char *name, RedisModuleString **res);
int RedisModule_GetEnumConfig(RedisModuleCtx *ctx, const char *name, RedisModuleString **res);
int RedisModule_GetNumericConfig(RedisModuleCtx *ctx, const char *name, long long *res);
int RedisModule_SetBoolConfig(RedisModuleCtx *ctx, const char *name, int value, RedisModuleString **err);
int RedisModule_SetConfig(RedisModuleCtx *ctx, const char *name, RedisModuleString *value, RedisModuleString **err);
int RedisModule_SetEnumConfig(RedisModuleCtx *ctx, const char *name, RedisModuleString *value, RedisModuleString **err);
int RedisModule_SetNumericConfig(RedisModuleCtx *ctx, const char *name, long long value, RedisModuleString **err);
```
## Implementation
The work is mostly done inside `config.c` as I didn't want to expose the
config dict outside of it. That means each of these module functions has
a corresponding method in `config.c` that actually does the job. F.e
`RedisModule_SetEnumConfig` calls `moduleSetEnumConfig` which is
implemented in `config.c`
## Notes
Also, refactored `configSetCommand` and `restoreBackupConfig` functions
for the following reasons:
- code and logic is now way more clear in `configSetCommand`. Only
caveat here is removal of an optimization that skipped running apply
functions that already have ran in favour of code clarity.
- Both functions needlessly separated logic for module configs and
normal configs whereas no such separation is needed. This also had the
side effect of removing some allocations.
- `restoreBackupConfig` now has clearer interface and can be reused with
ease. One of the places I reused it is for the individual
`moduleSet*Config` functions, each of which needs the restoration
functionality but for a single config only.
## Future
Additionally, a couple considerations were made for potentially
extending the API in the future
- if need be an API for atomically setting multiple config values can be
added - `RedisModule_SetConfigsTranscationStart/End` or similar that can
be put around `RedisModule_Set*Config` calls.
- if performance is an issue an API
`RedisModule_GetConfigIteratorNextWithTypehint` or similar may be added
in order not to incur the additional cost of calling
`RedisModule_GetConfigType`.
---------
Co-authored-by: Oran Agra <oran@redislabs.com>
This PR fixes
https://github.com/redis/redis/issues/14056#issuecomment-3026114590
## Summary
Because evport uses `eventLoop->events[fd].mask` to determine whether to
remove the event, but in ae.c we call `aeApiDelEvent()` before updating
`eventLoop->events[fd].mask`, this causes evport to always see the old
value, and as a result, `port_dissociate()` is never called to remove
the fd.
This issue may not surface easily in a non-multithreaded, but since in
the multi-threaded case we frequently reassign fds to different threads,
it makes the crash much more likely to occur.