redict/src
Meir Shpilraien (Spielrein) abc345ad28
Module API to allow writes after key space notification hooks (#11199)
### Summary of API additions

* `RedisModule_AddPostNotificationJob` - new API to call inside a key space
  notification (and on more locations in the future) and allow to add a post job as describe above.
* New module option, `REDISMODULE_OPTIONS_ALLOW_NESTED_KEYSPACE_NOTIFICATIONS`,
  allows to disable Redis protection of nested key-space notifications.
* `RedisModule_GetModuleOptionsAll` - gets the mask of all supported module options so a module
  will be able to check if a given option is supported by the current running Redis instance.

### Background

The following PR is a proposal of handling write operations inside module key space notifications.
After a lot of discussions we came to a conclusion that module should not perform any write
operations on key space notification.

Some examples of issues that such write operation can cause are describe on the following links:

* Bad replication oreder - https://github.com/redis/redis/pull/10969
* Used after free - https://github.com/redis/redis/pull/10969#issuecomment-1223771006
* Used after free - https://github.com/redis/redis/pull/9406#issuecomment-1221684054

There are probably more issues that are yet to be discovered. The underline problem with writing
inside key space notification is that the notification runs synchronously, this means that the notification
code will be executed in the middle on Redis logic (commands logic, eviction, expire).
Redis **do not assume** that the data might change while running the logic and such changes
can crash Redis or cause unexpected behaviour.

The solution is to state that modules **should not** perform any write command inside key space
notification (we can chose whether or not we want to force it). To still cover the use-case where
module wants to perform a write operation as a reaction to key space notifications, we introduce
a new API , `RedisModule_AddPostNotificationJob`, that allows to register a callback that will be
called by Redis when the following conditions hold:

* It is safe to perform any write operation.
* The job will be called atomically along side the operation that triggers it (in our case, key
  space notification).

Module can use this new API to safely perform any write operation and still achieve atomicity
between the notification and the write.

Although currently the API is supported on key space notifications, the API is written in a generic
way so that in the future we will be able to use it on other places (server events for example).

### Technical Details

Whenever a module uses `RedisModule_AddPostNotificationJob` the callback is added to a list
of callbacks (called `modulePostExecUnitJobs`) that need to be invoke after the current execution
unit ends (whether its a command, eviction, or active expire). In order to trigger those callback
atomically with the notification effect, we call those callbacks on `postExecutionUnitOperations`
(which was `propagatePendingCommands` before this PR). The new function fires the post jobs
and then calls `propagatePendingCommands`.

If the callback perform more operations that triggers more key space notifications. Those keys
space notifications might register more callbacks. Those callbacks will be added to the end
of `modulePostExecUnitJobs` list and will be invoke atomically after the current callback ends.
This raises a concerns of entering an infinite loops, we consider infinite loops as a logical bug
that need to be fixed in the module, an attempt to protect against infinite loops by halting the
execution could result in violation of the feature correctness and so **Redis will make no attempt
to protect the module from infinite loops**

In addition, currently key space notifications are not nested. Some modules might want to allow
nesting key-space notifications. To allow that and keep backward compatibility, we introduce a
new module option called `REDISMODULE_OPTIONS_ALLOW_NESTED_KEYSPACE_NOTIFICATIONS`.
Setting this option will disable the Redis key-space notifications nesting protection and will
pass this responsibility to the module.

### Redis infrastructure

This PR promotes the existing `propagatePendingCommands` to an "Execution Unit" concept,
which is called after each atomic unit of execution,

Co-authored-by: Oran Agra <oran@redislabs.com>
Co-authored-by: Yossi Gottlieb <yossigo@gmail.com>
Co-authored-by: Madelyn Olson <34459052+madolson@users.noreply.github.com>
2022-11-24 19:00:04 +02:00
..
commands Update Sentinel Debug command json file and add test case for it (#11513) 2022-11-24 13:10:41 +02:00
modules use $^ instead of $< for linker in module makefile (#10530) 2022-04-05 17:08:27 +03:00
.gitignore Ignore gcov/lcov artifacts 2012-04-13 17:52:33 -07:00
acl.c Retain ACL categories used to generate ACL for displaying them later (#11224) 2022-11-03 10:14:56 -07:00
adlist.c optimize unwatchAllKeys() (#11511) 2022-11-23 17:39:08 +02:00
adlist.h optimize unwatchAllKeys() (#11511) 2022-11-23 17:39:08 +02:00
ae_epoll.c Fail fast when systemic error occurs in poll (#8749) 2021-04-26 15:52:06 +03:00
ae_evport.c Fix cluster bus extensions backwards compatibility (#10206) 2022-01-30 19:43:37 +02:00
ae_kqueue.c Fix the timing of read and write events under kqueue (#9416) 2021-09-02 11:07:51 +03:00
ae_select.c fix unused argument warning in ae_select.c (#10824) 2022-06-07 14:47:09 +03:00
ae.c Don't process file events if AE_FILE_EVENTS isn't set. (#11428) 2022-10-29 16:24:12 -07:00
ae.h Add event loop support to the module API (#10001) 2022-01-18 13:10:07 +02:00
anet.c Introduce connAddr 2022-08-22 15:01:40 +08:00
anet.h Introduce connAddr 2022-08-22 15:01:40 +08:00
aof.c Add explicit error log message for AOF_TRUNCATED status when server load AOF file (#11484) 2022-11-22 16:18:36 +02:00
asciilogo.h Changes http to https in texts (#8495) 2021-03-10 19:11:16 +02:00
atomicvar.h Adding parentheses and do-while(0) to macros (#11080) 2022-08-03 19:38:08 +03:00
bio.c Removing old redundant code from bio.c (#11136) 2022-08-26 09:09:23 -07:00
bio.h Removing old redundant code from bio.c (#11136) 2022-08-26 09:09:23 -07:00
bitops.c Change compiler optimizations to -O3 -flto (#11207) 2022-10-02 15:15:14 +03:00
blocked.c Module API to allow writes after key space notification hooks (#11199) 2022-11-24 19:00:04 +02:00
call_reply.c Fix broken protocol in MISCONF error, RM_Yield bugs, RM_Call(EVAL) OOM check bug, and new RM_Call checks. (#10786) 2022-06-01 13:04:22 +03:00
call_reply.h Add new RM_Call flags for script mode, no writes, and error replies. (#10372) 2022-03-22 14:13:28 +02:00
childinfo.c fixes for fork child exit and test: #11463 (#11499) 2022-11-12 20:35:34 +02:00
cli_common.c Fix error/warning on Arm due to unsigned char. (#10572) 2022-04-12 18:55:11 +03:00
cli_common.h redis-cli: Better --json Unicode support and --quoted-json (#10286) 2022-03-05 21:25:52 +02:00
cluster.c Module API to allow writes after key space notification hooks (#11199) 2022-11-24 19:00:04 +02:00
cluster.h Introduce Shard IDs to logically group nodes in cluster mode (#10536) 2022-11-16 19:24:18 -08:00
commands.c Update Sentinel Debug command json file and add test case for it (#11513) 2022-11-24 13:10:41 +02:00
config.c Listpack encoding for sets (#11290) 2022-11-09 19:50:07 +02:00
config.h register debug support on illumos/solaris. (#11335) 2022-10-02 16:36:31 +03:00
connection.c Use cached value correctly inside connectionTypeTls() (#11236) 2022-09-06 09:04:33 +03:00
connection.h Introduce socket shutdown into connection type, used if a fork is active (#11376) 2022-11-04 18:46:37 +02:00
connhelpers.h Fixed some typos, add a spell check ci and others minor fix (#8890) 2021-06-10 15:39:33 +03:00
crc16_slottable.h Added basic support for clusters to redis-benchmark. 2019-03-01 17:53:14 +01:00
crc16.c RDMF (Redis/Disque merge friendlyness) refactoring WIP 1. 2015-07-26 15:17:18 +02:00
crc64.c Add --large-memory flag for REDIS_TEST to enable tests that consume more than 100mb (#9784) 2021-11-16 08:55:10 +02:00
crc64.h Add --large-memory flag for REDIS_TEST to enable tests that consume more than 100mb (#9784) 2021-11-16 08:55:10 +02:00
crcspeed.c Fixed some typos, add a spell check ci and others minor fix (#8890) 2021-06-10 15:39:33 +03:00
crcspeed.h Added crcspeed library 2020-04-24 17:11:21 -07:00
db.c Listpack encoding for sets (#11290) 2022-11-09 19:50:07 +02:00
debug.c optimizing d2string() and addReplyDouble() with grisu2: double to string conversion based on Florian Loitsch's Grisu-algorithm (#10587) 2022-10-15 12:17:41 +03:00
debugmacro.h Supplement define guards to prevent multiple inclusion (#10246) 2022-02-06 20:13:34 -08:00
defrag.c Add listpack encoding for list (#11303) 2022-11-16 20:29:46 +02:00
dict.c Added API to initialize dictionary iterators without memory allocation (#11245) 2022-09-07 20:57:43 -05:00
dict.h Added API to initialize dictionary iterators without memory allocation (#11245) 2022-09-07 20:57:43 -05:00
endianconv.c Avoid using unsafe C functions (#10932) 2022-07-18 10:56:26 +03:00
endianconv.h Add --large-memory flag for REDIS_TEST to enable tests that consume more than 100mb (#9784) 2021-11-16 08:55:10 +02:00
eval.c Add missing lua_pop in luaGetFromRegistry (#11097) 2022-08-14 11:50:18 +03:00
evict.c Module API to allow writes after key space notification hooks (#11199) 2022-11-24 19:00:04 +02:00
expire.c Module API to allow writes after key space notification hooks (#11199) 2022-11-24 19:00:04 +02:00
fmacros.h Fix failed tests on Linux Alpine and add a CI job. (#8532) 2021-02-23 12:57:45 +02:00
function_lua.c Add missing lua_pop in luaGetFromRegistry (#11097) 2022-08-14 11:50:18 +03:00
functions.c Explicitly send function commands to monitor (#11510) 2022-11-15 17:21:27 -08:00
functions.h Functions: Move library meta data to be part of the library payload. (#10500) 2022-04-05 10:27:24 +03:00
geo.c Fix some nonsense came from LGTM (#9962) 2021-12-19 17:52:23 +02:00
geo.h RDMF (Redis/Disque merge friendlyness) refactoring WIP 1. 2015-07-26 15:17:18 +02:00
geohash_helper.c GEOSEARCH BYBOX: Reduce wastefull computation on geohashGetDistanceIfInRectangle and geohashGetDistance (#11535) 2022-11-24 18:09:56 +02:00
geohash_helper.h Delete some unimplemented prototype. (#8882) 2021-04-29 08:25:10 +03:00
geohash.c Fix mistake / outdated doc comment (#10521) 2022-04-04 15:35:49 +03:00
geohash.h Remove duplicate header file include (#10264) 2022-02-08 16:49:47 +02:00
help.h Make PFMERGE source key optional in docs, add tests with one input key, add tests on missing source keys (#11205) 2022-10-22 20:41:17 +03:00
hyperloglog.c Adding parentheses and do-while(0) to macros (#11080) 2022-08-03 19:38:08 +03:00
intset.c Listpack encoding for sets (#11290) 2022-11-09 19:50:07 +02:00
intset.h Listpack encoding for sets (#11290) 2022-11-09 19:50:07 +02:00
latency.c Add warning for suspected slow system clocksource setting (#10636) 2022-05-22 17:10:31 +03:00
latency.h Add warning for suspected slow system clocksource setting (#10636) 2022-05-22 17:10:31 +03:00
lazyfree.c Add listpack encoding for list (#11303) 2022-11-16 20:29:46 +02:00
listpack_malloc.h Optimize listpack for stream usage to avoid repeated reallocs (#6281) 2021-02-16 16:17:38 +02:00
listpack.c Add listpack encoding for list (#11303) 2022-11-16 20:29:46 +02:00
listpack.h Add listpack encoding for list (#11303) 2022-11-16 20:29:46 +02:00
localtime.c fix typos (#10402) 2022-03-09 13:58:23 +02:00
lolwut5.c Fixed some typos, add a spell check ci and others minor fix (#8890) 2021-06-10 15:39:33 +03:00
lolwut6.c Fixed some typos, add a spell check ci and others minor fix (#8890) 2021-06-10 15:39:33 +03:00
lolwut.c Fixed some typos, add a spell check ci and others minor fix (#8890) 2021-06-10 15:39:33 +03:00
lolwut.h add include guard for lolwut.h 2020-05-05 23:35:08 -04:00
lzf_c.c Change lzf to handle values larger than UINT32_MAX (#9776) 2021-11-16 13:12:25 +02:00
lzf_d.c Change lzf to handle values larger than UINT32_MAX (#9776) 2021-11-16 13:12:25 +02:00
lzf.h Change lzf to handle values larger than UINT32_MAX (#9776) 2021-11-16 13:12:25 +02:00
lzfP.h Change lzf to handle values larger than UINT32_MAX (#9776) 2021-11-16 13:12:25 +02:00
Makefile Use jemalloc by default also on ARM (#11407) 2022-11-07 19:11:12 +02:00
memtest.c Add sanitizer support and clean up sanitizer findings (#9601) 2021-11-11 13:51:33 +02:00
mkreleasehdr.sh Build TLS as a loadable module 2022-08-23 12:37:56 +03:00
module.c Module API to allow writes after key space notification hooks (#11199) 2022-11-24 19:00:04 +02:00
monotonic.c Optimization: Use either monotonic or wall-clock to measure command execution time, to regain up to 4% execution time (#10502) 2022-04-20 14:00:30 +03:00
monotonic.h Optimization: Use either monotonic or wall-clock to measure command execution time, to regain up to 4% execution time (#10502) 2022-04-20 14:00:30 +03:00
mt19937-64.c Fix random element selection for large hash tables. (#8133) 2020-12-23 15:52:07 +02:00
mt19937-64.h Fix random element selection for large hash tables. (#8133) 2020-12-23 15:52:07 +02:00
multi.c optimize unwatchAllKeys() (#11511) 2022-11-23 17:39:08 +02:00
networking.c Introduce socket shutdown into connection type, used if a fork is active (#11376) 2022-11-04 18:46:37 +02:00
notify.c Add RM_PublishMessageShard (#10543) 2022-04-17 15:43:22 +03:00
object.c Add listpack encoding for list (#11303) 2022-11-16 20:29:46 +02:00
pqsort.c Fix null pointer subtraction warning (#10498) 2022-04-04 18:38:18 +03:00
pqsort.h BSD license added to every C source and header file. 2012-11-08 18:31:32 +01:00
pubsub.c Account sharded pubsub channels memory consumption (#10925) 2022-07-04 09:18:57 +03:00
quicklist.c Add listpack encoding for list (#11303) 2022-11-16 20:29:46 +02:00
quicklist.h Add listpack encoding for list (#11303) 2022-11-16 20:29:46 +02:00
rand.c Use 'void' for zero-argument functions 2014-08-08 10:05:32 +02:00
rand.h BSD license added to every C source and header file. 2012-11-08 18:31:32 +01:00
rax_malloc.h Cluster: hash slots tracking using a radix tree. 2017-03-27 16:37:22 +02:00
rax.c code, typo and comment cleanups (#11280) 2022-10-02 13:56:45 +03:00
rax.h Squash merging 125 typo/grammar/comment/doc PRs (#7773) 2020-09-10 13:43:38 +03:00
rdb.c sanitize dump payload: fix crash with empty set with listpack encoding (#11519) 2022-11-20 12:12:15 +02:00
rdb.h sanitize dump payload: fix crash with empty set with listpack encoding (#11519) 2022-11-20 12:12:15 +02:00
redis-benchmark.c Fix redis-benchmark hang when it fails to connect to redis (#11366) 2022-10-09 12:17:36 +03:00
redis-check-aof.c Unify repeated code in redis-check-aof (#11456) 2022-11-06 14:49:55 +02:00
redis-check-rdb.c Listpack encoding for sets (#11290) 2022-11-09 19:50:07 +02:00
redis-cli.c Add redis-cli hints to ACL DRYRUN, COMMAND GETKEYS, COMMAND GETKEYSANDFLAGS (#11232) 2022-09-29 09:49:53 +03:00
redis-trib.rb Redis-trib deprecated: it no longer works and it 2018-07-13 10:51:58 +02:00
redisassert.c Add sanitizer support and clean up sanitizer findings (#9601) 2021-11-11 13:51:33 +02:00
redisassert.h Fix a prototype inconsitency of _serverAssert between redisassert.h and redis.h (#10872) 2022-06-19 08:42:12 +03:00
redismodule.h Module API to allow writes after key space notification hooks (#11199) 2022-11-24 19:00:04 +02:00
release.c Build TLS as a loadable module 2022-08-23 12:37:56 +03:00
replication.c Refactor and (internally) rebrand from pause-clients to pause-actions (#11098) 2022-10-27 11:57:04 +03:00
resp_parser.c Unified Lua and modules reply parsing and added RESP3 support to RM_Call (#9202) 2021-08-04 16:28:07 +03:00
resp_parser.h Fix an mistake in comment (#10560) 2022-04-10 09:29:50 +03:00
rio.c optimizing d2string() and addReplyDouble() with grisu2: double to string conversion based on Florian Loitsch's Grisu-algorithm (#10587) 2022-10-15 12:17:41 +03:00
rio.h Adds isolated netstats for replication. (#10062) 2022-05-31 08:07:33 +03:00
script_lua.c Fix wrong tips when the user pass wrong # of arguments to redis.set_repl(). (#11415) 2022-10-23 15:06:58 +03:00
script_lua.h Protect any table which is reachable from globals and added globals white list. 2022-04-27 00:37:40 +03:00
script.c RM_Call - only enforce OOM on scripts if 'M' flag is sent (#11425) 2022-10-27 09:29:43 +03:00
script.h Expose script flags to processCommand for better handling (#10744) 2022-06-01 14:09:40 +03:00
sds.c Fix additional AOF filename issues. (#10110) 2022-01-18 12:52:27 +02:00
sds.h Fix additional AOF filename issues. (#10110) 2022-01-18 12:52:27 +02:00
sdsalloc.h Sanitize dump payload: fail RESTORE if memory allocation fails 2020-12-06 14:54:34 +02:00
sentinel.c Add CONFIG SET and GET loglevel feature in Sentinel (#11214) 2022-11-20 12:03:00 +02:00
server.c Module API to allow writes after key space notification hooks (#11199) 2022-11-24 19:00:04 +02:00
server.h Module API to allow writes after key space notification hooks (#11199) 2022-11-24 19:00:04 +02:00
setcpuaffinity.c cpu affinity: DragonFlyBSD support (#7956) 2020-10-25 14:14:05 +02:00
setproctitle.c Fix failed tests on Linux Alpine and add a CI job. (#8532) 2021-02-23 12:57:45 +02:00
sha1.c Ignore -Wstringop-overread warning for SHA1Transform() on GCC 12 (#11538) 2022-11-24 15:27:16 +02:00
sha1.h Add --large-memory flag for REDIS_TEST to enable tests that consume more than 100mb (#9784) 2021-11-16 08:55:10 +02:00
sha256.c Add sanitizer support and clean up sanitizer findings (#9601) 2021-11-11 13:51:33 +02:00
sha256.h fix explanation of sha256 (#9220) 2021-07-10 10:04:54 -05:00
siphash.c Add sanitizer support and clean up sanitizer findings (#9601) 2021-11-11 13:51:33 +02:00
slowlog.c slowlog get command supports passing in -1 to get all logs. (#9018) 2021-06-14 16:46:45 +03:00
slowlog.h Auto-generate the command table from JSON files (#9656) 2021-12-15 21:23:15 +02:00
socket.c Introduce socket shutdown into connection type, used if a fork is active (#11376) 2022-11-04 18:46:37 +02:00
solarisfixes.h Check for __sun macro in solarisfixes.h, not in includers. 2015-01-09 11:23:22 +01:00
sort.c Add listpack encoding for list (#11303) 2022-11-16 20:29:46 +02:00
sparkline.c Squash merging 125 typo/grammar/comment/doc PRs (#7773) 2020-09-10 13:43:38 +03:00
sparkline.h LATENCY GRAPH implemented. 2014-07-02 16:31:22 +02:00
stream.h Add stream consumer group lag tracking and reporting (#9127) 2022-02-23 22:34:58 +02:00
strl.c Avoid using unsafe C functions (#10932) 2022-07-18 10:56:26 +03:00
syncio.c syncWithMaster(): non blocking state machine. 2015-08-06 18:12:20 +02:00
syscheck.c Improve linux overcommit check and warning (#11357) 2022-10-13 13:05:20 +03:00
syscheck.h Add warning for suspected slow system clocksource setting (#10636) 2022-05-22 17:10:31 +03:00
t_hash.c fix hincrbyfloat not to create a key if the new value is invalid (#11149) 2022-08-28 11:33:41 +03:00
t_list.c Add listpack encoding for list (#11303) 2022-11-16 20:29:46 +02:00
t_set.c Fix set with duplicate elements causes sdiff to hang (#11530) 2022-11-22 11:20:24 +02:00
t_stream.c Fix XSETID with max_deleted_entry_id issue (#11444) 2022-11-02 16:16:16 +02:00
t_string.c Freeze time sampling during command execution, and scripts (#10300) 2022-10-09 08:18:34 +03:00
t_zset.c Listpack encoding for sets (#11290) 2022-11-09 19:50:07 +02:00
testhelp.h Add --large-memory flag for REDIS_TEST to enable tests that consume more than 100mb (#9784) 2021-11-16 08:55:10 +02:00
timeout.c Freeze time sampling during command execution, and scripts (#10300) 2022-10-09 08:18:34 +03:00
tls.c Introduce socket shutdown into connection type, used if a fork is active (#11376) 2022-11-04 18:46:37 +02:00
tracking.c code, typo and comment cleanups (#11280) 2022-10-02 13:56:45 +03:00
unix.c Introduce socket shutdown into connection type, used if a fork is active (#11376) 2022-11-04 18:46:37 +02:00
util.c optimizing d2string() and addReplyDouble() with grisu2: double to string conversion based on Florian Loitsch's Grisu-algorithm (#10587) 2022-10-15 12:17:41 +03:00
util.h optimizing d2string() and addReplyDouble() with grisu2: double to string conversion based on Florian Loitsch's Grisu-algorithm (#10587) 2022-10-15 12:17:41 +03:00
valgrind.sup Sanitize dump payload: fuzz tester and fixes for segfaults and leaks it exposed 2020-12-06 14:54:34 +02:00
version.h Add Module API for version and compatibility checks (#7865) 2020-10-11 17:21:58 +03:00
ziplist.c fix arm build warning due to new compiler optimizations (#11362) 2022-10-07 21:24:54 +03:00
ziplist.h Add --large-memory flag for REDIS_TEST to enable tests that consume more than 100mb (#9784) 2021-11-16 08:55:10 +02:00
zipmap.c Add --large-memory flag for REDIS_TEST to enable tests that consume more than 100mb (#9784) 2021-11-16 08:55:10 +02:00
zipmap.h Add --large-memory flag for REDIS_TEST to enable tests that consume more than 100mb (#9784) 2021-11-16 08:55:10 +02:00
zmalloc.c Avoid using unsafe C functions (#10932) 2022-07-18 10:56:26 +03:00
zmalloc.h zmalloc api set malloc attributes for api giving non aliased pointers. (#11196) 2022-09-05 16:09:28 +03:00