Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support Blocking a Client on Keyspace Event Notification #1819

Open
wants to merge 3 commits into
base: unstable
Choose a base branch
from

Conversation

yairgott
Copy link

@yairgott yairgott commented Mar 5, 2025

This change enhances user experience and consistency by allowing a module to block a client on keyspace event notifications. Consistency is improved by allowing that reads after writes on the same connection yield expected results. For example, in ValkeySearch, mutations processed earlier on the same connection will be available for search.

The implementation extends VM_BlockClient to support blocking clients on keyspace event notifications. Internal clients, LUA clients, clients issueing multi exec and those with the deny_blocking flag set are not blocked. Once blocked, a client’s reply is withheld until it is explicitly unblocked.

@yairgott yairgott changed the title Enable Blocking a Client on Keyspace Event Notification Support Blocking a Client on Keyspace Event Notification Mar 5, 2025
@yairgott yairgott force-pushed the client_block branch 4 times, most recently from a064f39 to 74cb5e4 Compare March 5, 2025 07:08
Copy link

codecov bot commented Mar 5, 2025

Codecov Report

Attention: Patch coverage is 80.66298% with 35 lines in your changes missing coverage. Please review.

Project coverage is 70.99%. Comparing base (3f6581b) to head (fde2e1f).
Report is 9 commits behind head on unstable.

Files with missing lines Patch % Lines
src/module.c 5.26% 18 Missing ⚠️
src/networking.c 48.00% 13 Missing ⚠️
src/geo.c 33.33% 2 Missing ⚠️
src/bitops.c 75.00% 1 Missing ⚠️
src/t_set.c 94.73% 1 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff              @@
##           unstable    #1819      +/-   ##
============================================
- Coverage     70.99%   70.99%   -0.01%     
============================================
  Files           123      123              
  Lines         65651    65707      +56     
============================================
+ Hits          46609    46648      +39     
- Misses        19042    19059      +17     
Files with missing lines Coverage Δ
src/cluster.c 89.17% <100.00%> (ø)
src/cluster_legacy.c 85.79% <100.00%> (-0.18%) ⬇️
src/db.c 89.49% <100.00%> (ø)
src/evict.c 98.47% <100.00%> (-0.39%) ⬇️
src/expire.c 96.59% <100.00%> (ø)
src/hyperloglog.c 92.23% <100.00%> (ø)
src/module.h 0.00% <ø> (ø)
src/notify.c 97.01% <100.00%> (ø)
src/rdb.c 76.72% <100.00%> (+0.41%) ⬆️
src/server.h 100.00% <ø> (ø)
... and 11 more

... and 12 files with indirect coverage changes

🚀 New features to boost your workflow:
  • Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@PingXie PingXie requested a review from enjoy-binbin March 6, 2025 00:44
@yairgott yairgott force-pushed the client_block branch 3 times, most recently from 2428ae0 to 7c9cff2 Compare March 6, 2025 23:06
@yairgott yairgott force-pushed the client_block branch 9 times, most recently from dd60c6a to 0445d46 Compare March 7, 2025 22:00
This change enhances user experience and consistency by allowing a
module to block a client on keyspace event notifications. Consistency
is improved by ensuring that reads after writes on the same connection
yield expected results. For example, in ValkeySearch, mutations processed
earlier on the same connection will be available for search.

The implementation extends `VM_BlockClient` to support blocking clients on
keyspace event notifications. Internal clients, LUA clients, clients issueing
multi exec and those with the `deny_blocking` flag set are not blocked.
Once blocked, a client’s reply is withheld until it is explicitly unblocked.

Signed-off-by: yairgott <[email protected]>
Copy link
Member

@madolson madolson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, I'm aligned with the design now. Just some other misc comments.

@madolson madolson added the major-decision-pending Major decision pending by TSC team label Mar 7, 2025
yairgott and others added 2 commits March 7, 2025 15:33
Co-authored-by: Madelyn Olson <[email protected]>
Signed-off-by: Yair Gottdenker <[email protected]>
Co-authored-by: Madelyn Olson <[email protected]>
Signed-off-by: Yair Gottdenker <[email protected]>
Signed-off-by: yairgott <[email protected]>
@madolson
Copy link
Member

@valkey-io/core-team This API is a bit late to be added. The feature adds a new functionality to using keyspace notifications, allowing them to block clients. The goal is to provide read and after write consistency for the VSS module.

There are two different ways to provide this guarantee, either block the write until it's visible in the index or block the read until all pending writes were ingested. The search module preferred to use the blocking of the write approach, but need an API to block the writes.

@murphyjacob4 Will follow up to see if there is a away to avoid this new functionality.

@@ -112,7 +113,7 @@ void notifyKeyspaceEvent(int type, char *event, robj *key, int dbid) {
* This bypasses the notifications configuration, but the module engine
* will only call event subscribers if the event type matches the types
* they are interested in. */
moduleNotifyKeyspaceEvent(type, event, key, dbid);
moduleNotifyKeyspaceEvent(c, type, event, key, dbid);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you simply use server.current_client when you invoke this method? That way you don't need to pass in client* into notifyKeyspaceEvent().

@@ -8880,8 +8924,14 @@ void moduleNotifyKeyspaceEvent(int type, const char *event, robj *key, int dbid)
if ((sub->event_mask & type) &&
(sub->active == 0 || (sub->module->options & VALKEYMODULE_OPTIONS_ALLOW_NESTED_KEYSPACE_NOTIFICATIONS))) {
ValkeyModuleCtx ctx;
moduleCreateContext(&ctx, sub->module, VALKEYMODULE_CTX_TEMP_CLIENT);
selectDb(ctx.client, dbid);
if (c == NULL) {
Copy link
Contributor

@QuChen88 QuChen88 Mar 18, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rather than passing in client* to this module API, can you simply check if server.current_client is NULL or not?

Or... maybe check server.executing_client if you want to cover the case of a Lua script.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
major-decision-pending Major decision pending by TSC team
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants