Skip to content

feat(keyspace): emit set and del notifications - #3541

Open
Aetherance wants to merge 19 commits into
apache:unstablefrom
Aetherance:feat/notify-keyspace-events
Open

feat(keyspace): emit set and del notifications#3541
Aetherance wants to merge 19 commits into
apache:unstablefrom
Aetherance:feat/notify-keyspace-events

Conversation

@Aetherance

@Aetherance Aetherance commented Jul 1, 2026

Copy link
Copy Markdown

Implement initial keyspace notifications for set and del events, compatible with Redis notify-keyspace-events.

This PR adds the initial notification emitters and configuration support:

  • Support K, E, g, $, and A flags, where A currently expands to the implemented event classes g$.
  • Emit set notifications only when the shared Set path actually applies a write, including conditional SET variants.
  • Emit del notifications only for keys that are actually deleted through the shared delete path.
  • Deduplicate repeated keys in a single delete operation, so the same key is deleted and notified once.
  • Queue notifications inside MULTI/EXEC and publish them after a successful commit.
  • Map notification DB names correctly:
    • default namespace uses DB 0
    • redis-databases namespaces map back to Redis DB indexes

This PR only adds the initial set and del event paths on primary nodes, keeping the initial patch small and reviewable. Commands sharing the same underlying mutation APIs may also produce these events. Replica-side notifications and additional event types, if supported, can be added in follow-up PRs.

Unsupported notification classes are rejected for now until their emitters are implemented.

Ref Proposal: #3533
Tracking Issue: #2915

Assisted by Codex/GPT-5.5.

@Aetherance

Copy link
Copy Markdown
Author

I added optional output parameters to String::Set and Database::MDel so the command layer can emit notifications based on what actually changed.

For SET, this avoids duplicating the conditional SET decision logic in the command layer. For DEL, this avoids an extra EXISTS pass before deletion, which would add unnecessary storage reads and overhead. It also lets MDel return the keys it actually deleted.

The alternative would be to keep these storage APIs unchanged and infer the notification decisions in the command layer. That would keep the APIs smaller, but the trade-off is that SET would duplicate conditional SET/GET logic outside String::Set, and DEL would need extra reads before MDel. Over time, this could also drift from the actual write behavior.

I chose the optional-output approach for this PR, but I’m open to maintainers’ preference here.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR adds initial Redis-compatible keyspace notification support to Kvrocks by introducing notify-keyspace-events flag parsing and emitting notifications for SET and DEL only when those commands actually apply changes. It also ensures notifications behave correctly with MULTI/EXEC (queued until successful commit) and handles Redis DB index mapping when redis-databases is enabled.

Changes:

  • Add notify-keyspace-events configuration parsing/validation and a server-side NotifyKeyspaceEvent publisher.
  • Emit set notifications only when SET actually writes (including conditional variants) and emit del only for keys actually deleted (including deduping duplicate keys in a single DEL).
  • Queue keyspace events during EXEC and publish them only after a successful transaction commit; add Go and C++ unit tests for flags and observable pubsub behavior.

Reviewed changes

Copilot reviewed 19 out of 19 changed files in this pull request and generated no comments.

Show a summary per file
File Description
tests/gocase/unit/keyspacenotify/keyspacenotify_test.go New Go tests validating SET/DEL keyspace+keyevent messages, conditional SET behavior, runtime CONFIG SET, MULTI/EXEC queuing, and redis-databases DB mapping.
tests/gocase/unit/keyspace/keyspace_test.go Extends existing DEL tests to assert duplicate keys are only counted/deleted once.
tests/cppunit/keyspace_events_test.cc New C++ unit tests for notify flag parsing, A expansion, unsupported flag rejection, and namespace→DB mapping.
src/common/keyspace_events.h / src/common/keyspace_events.cc New helpers for parsing notify-keyspace-events and mapping namespace to keyspace DB name (with percent-encoding for non-db namespaces).
src/config/config.h / src/config/config.cc Adds stored parsed notify flags and wires up the notify-keyspace-events config field with validation and runtime callback parsing.
src/server/server.h / src/server/server.cc Adds Server::NotifyKeyspaceEvent that filters by configured flags and publishes keyspace then keyevent messages.
src/server/redis_connection.h / src/server/redis_connection.cc Adds per-connection queueing for keyspace events during EXEC, flushing after successful commit, and clearing on reset/abort.
src/commands/cmd_txn.cc Flushes queued keyspace events only after a successful CommitTxn() in EXEC.
src/types/redis_string.h / src/types/redis_string.cc Extends String::Set with an applied out-param to distinguish “command OK” from “write actually happened”.
src/commands/cmd_string.cc Emits set notifications only when String::Set reports an applied write and notifications are enabled.
src/storage/redis_db.h / src/storage/redis_db.cc Extends MDel to optionally return the list of deleted user keys, and deduplicates repeated keys so deletes/counts match Redis behavior.
src/commands/cmd_key.cc For DEL, requests deleted key list from MDel and emits one del notification per actually-deleted key (skipping non-deletes and duplicates).
kvrocks.conf Documents the new keyspace notification configuration and supported flags.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@jihuayu jihuayu left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Looks great. I like the code you wrote.

Redis keyspace notifications treat $ as the string command class. Besides SET, commands such as SETEX/PSETEX, GETSET, MSET, APPEND, INCR*, and SETRANGE also emit string events (set, append, incrby, setrange, etc.; SETEX/PSETEX also emit expire). This PR currently only emits notifications for literal SET. Is the remaining string command coverage intentionally deferred to a follow-up PR?

@Aetherance

Copy link
Copy Markdown
Author

Looks great. I like the code you wrote.看起来很棒。我喜欢你写的代码。

Redis keyspace notifications treat $ as the string command class. Besides SET, commands such as SETEX/PSETEX, GETSET, MSET, APPEND, INCR*, and SETRANGE also emit string events (set, append, incrby, setrange, etc.; SETEX/PSETEX also emit expire). This PR currently only emits notifications for literal SET. Is the remaining string command coverage intentionally deferred to a follow-up PR?Redis 键空间通知将 $ 视为字符串命令类型。除了 SET 之外, SETEXPSETEXGETSETMSETAPPENDINCR*SETRANGE 等命令也会触发字符串相关的事件(如 setappendincrbysetrange 等; SETEX / PSETEX 也会触发 expire 相关事件)。目前的这个 PR 仅针对 SET 这种命令类型发出通知。至于其他字符串命令的处理,是否打算在后续的 PR 中再处理呢?

@jihuayu

Yes, that is intentionally deferred to follow-up PRs.

This PR focuses on the minimal SET and DEL notification support first. Adding the rest of the string command coverage in the same PR would make the change much larger and harder to review, so I intentionally kept the scope limited here.

I’m happy to cover the remaining string commands such as SETEX/PSETEX, GETSET, MSET, APPEND, INCR*, and SETRANGE in follow-up PRs once the basic notification path is accepted.

jihuayu
jihuayu previously approved these changes Jul 4, 2026

@jihuayu jihuayu left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thank you! I’ll wait for others to reply over the next two days.

@git-hulk

git-hulk commented Jul 4, 2026

Copy link
Copy Markdown
Member

@jihuayu I will take a look at this implementation since it might heavily impact the performance.

@PragmaTwice PragmaTwice left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I don’t think this keyspace notification design is scalable.

Adding more code for each new event is easy, especially with AI agents. But that is not the real problem. The real problem is whether the design is maintainable.

This PR does not solve that. It adds duplicated code for each event and requires changes in many command implementations. I don’t see a clear shared abstraction here.

I don’t think we should merge this in the current form. We should first design a better general mechanism.

Comment thread src/types/redis_string.cc Outdated
Comment thread src/storage/redis_db.cc Outdated
@git-hulk

git-hulk commented Jul 4, 2026

Copy link
Copy Markdown
Member

We should first design a better general mechanism.

Yes, I fully agree with this concern. We have an entry point to execute commands, so it should be possible to catch the changed events/data in one place instead of doing this in each command.

@Aetherance

Copy link
Copy Markdown
Author

@PragmaTwice @git-hulk Thanks for the careful review.

When I started implementing keyspace notifications, I also considered using a single common trigger point. However, while working on SET/DEL, I found that the generic command execution entry does not have enough semantic information to generate correct notifications.

For example, a conditional SET may return OK without actually writing the key, such as SET ... NX when the key already exists. DEL also needs to know the exact keys that were actually removed; cases like DEL k k k must not emit duplicate
notifications. These details are only known after the concrete command/type logic evaluates the command semantics, and cannot be derived reliably from the command name, arguments, Status, or reply at the generic execution entry.

I agree the current implementation is not scalable enough. I’ll revisit the design and try to centralize the shared parts better. I also think it may not be realistic to add more keyspace notification coverage without touching individual command/type implementations at all, because some event decisions still need to be made where the Redis semantics are fully known.

@git-hulk

git-hulk commented Jul 4, 2026

Copy link
Copy Markdown
Member

@Aetherance Thanks for your effort and reply.

For example, a conditional SET may return OK without actually writing the key, such as SET ... NX when the key already exists. DEL also needs to know the exact keys that were actually removed; cases like DEL k k k must not emit duplicate
notifications.

After iterating on the current implementation and proposal, I understood your intention. And yes, it's a bit tricky to depend on rocksdb WAL to achieve this feature.

For the implementation, we can check config flags, channel names, Pub/Sub publishing in one place like srv->NotifyKeyspaceEvent. So we can just add one line for each place where we need to emit the event.

@Aetherance
Aetherance force-pushed the feat/notify-keyspace-events branch 2 times, most recently from 36915d9 to ac611f8 Compare July 6, 2026 10:21
@Aetherance

This comment was marked as outdated.

@Aetherance
Aetherance requested a review from PragmaTwice July 10, 2026 05:30
@Aetherance
Aetherance force-pushed the feat/notify-keyspace-events branch from 2911a37 to e2f6660 Compare July 10, 2026 07:44
@sonarqubecloud

Copy link
Copy Markdown

Quality Gate Failed Quality Gate failed

Failed conditions
46.8% Coverage on New Code (required ≥ 50%)

See analysis details on SonarQube Cloud

@Aetherance

Copy link
Copy Markdown
Author

It looks like the full CI has not run on the latest commit. The previous CI run failed during startup because it was blocked by the repository’s action policy. Could a maintainer please help re-run or enable the CI when convenient?
@PragmaTwice @jihuayu @git-hulk

@Aetherance

Copy link
Copy Markdown
Author

I found that this PR has significant room for performance optimization. I’ll convert it to a draft for now and request a review once I’ve completed the optimizations. Thanks for all reviewers!

@Aetherance
Aetherance marked this pull request as draft July 24, 2026 15:09
@Aetherance
Aetherance marked this pull request as ready for review July 29, 2026 07:44

@Aetherance Aetherance left a comment

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

To make the review easier, I added inline comments in several places where the intent may not be immediately clear from the code itself. I hope this makes the implementation easier to understand.

Thanks for the review! 🙏


#include "status.h"

// Flags for notify-keyspace-events, separate from RedisType.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

To reduce the review burden and keep the scope of the changes manageable, this PR only adds support for the SET and DEL commands. Currently, only the $ and g event classes are supported. Support for other commands will be added in follow-up PRs.

#include "config/config.h"
#include "fmt/format.h"

bool ShouldNotifyKeyspaceEvent(int notify_flags, int type_flag) {

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

A notification is generated here only when both conditions are met: the event type is enabled, and at least one of K or E is enabled.

Comment thread src/server/redis_connection.cc Outdated
auto start = std::chrono::high_resolution_clock::now();
bool is_profiling = IsProfilingEnabled(cmd_name);

keyspace_event_notify_flags_ = srv_->GetConfig()->notify_keyspace_events;

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

The keyspace_event_collector is created only when keyspace notifications are enabled, and notifications are emitted only when the collector exists. Therefore, when keyspace notifications are disabled—or when a command’s event type is not enabled—the command skips all notification-related work except for a few lightweight condition checks. As a result, the performance impact in these cases should be negligible.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

By the way, support for additional commands can be added by simply calling conn->AddKeyspaceEvent. Some minor changes may also be needed to accurately capture the full semantics of the event, but no major changes to the notification mechanism should be necessary.

// Retain capacity for typical transactions, but request releasing unusually large buffers.
constexpr std::size_t kMaxRetainedKeyspaceEvents = 1024;
if (pending_keyspace_events_.capacity() > kMaxRetainedKeyspaceEvents) {
pending_keyspace_events_.shrink_to_fit();

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

clear() does not release the vector’s capacity, so a large transaction may cause a long-lived connection to retain excessive memory and potentially lead to OOM. To mitigate this, I call shrink_to_fit() when the capacity exceeds 1,024.

For small transactions, we can simply call clear() and reuse the allocated memory.

Comment thread src/server/server.cc
}

void Server::NotifyKeyspaceEvent(int flags, const std::string &event, const std::string &ns, const std::string &key) {
const std::string db = MapNamespaceToKeyspaceDB(ns, GetConfig()->redis_databases);

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Kvrocks has both ns and db. MapNamespaceToKeyspaceDB provides a unified representation of the two when naming Pub/Sub channels.

Comment thread src/types/redis_string.cc Outdated

rocksdb::Status String::Set(engine::Context &ctx, const std::string &user_key, const std::string &value,
const StringSetArgs &args, std::optional<std::string> &ret) {
const StringSetArgs &args, std::optional<std::string> &ret, bool *applied) {

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Here, Status::OK does not necessarily mean that a conditional SET was applied, so an additional applied flag is needed. So does it in DEL

Comment thread src/commands/cmd_key.cc Outdated
redis::Database redis(srv->storage, conn->GetNamespace());

auto s = redis.MDel(ctx, keys, &cnt);
const bool notify_del = GetAttributes()->name == "del" && conn->IsKeyspaceEventEnabled(kNotifyGeneric);

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

UNLINK is intentionally excluded here. Whether to support it will be decided in a follow-up PR or discussion.

@Aetherance

Copy link
Copy Markdown
Author

I ran multiple rounds of local performance benchmarks using redis-benchmark, covering several scenarios. I also included Redis as a reference to verify that this PR does not introduce a performance regression.

For example, the SET benchmark was run using the following command:

redis-benchmark -h 127.0.0.1 -p 6670 --threads 4 -c 64 -P 16 \
    -n 1000000 -r 1000000000 --seed 2002 --csv \
    SET bench:set:__rand_int__ 0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef

The benchmarks covered the Kvrocks unstable branch, the current PR branch, and Redis with notifications both disabled and enabled, allowing comparison with the keyspace notification implementation in this PR.

Kvrocks

Version / configuration Test RPS Avg latency (ms) Min (ms) P50 (ms) P95 (ms) P99 (ms) Max (ms)
unstable DEL 399,042.28 2.441 0.312 2.287 3.911 4.239 13.383
unstable SET 498,753.09 1.798 0.248 1.831 2.287 2.479 9.895
unstable PING 1,992,032.00 0.275 0.048 0.239 0.455 0.471 2.671
PR, notifications disabled DEL 398,724.09 2.348 0.480 2.351 2.727 3.015 11.791
PR, notifications disabled SET 570,450.62 1.757 0.096 1.839 2.367 2.551 11.679
PR, notifications disabled PING 1,992,032.00 0.249 0.024 0.255 0.343 0.383 2.087
PR, KE$g DEL 332,225.91 2.914 0.864 2.735 3.983 5.199 12.815
PR, KE$g SET 399,201.59 2.327 0.352 2.423 3.351 4.151 13.863

Redis reference

Configuration Test RPS Avg latency (ms) Min (ms) P50 (ms) P95 (ms) P99 (ms) Max (ms)
Notifications disabled DEL 1,329,787.25 0.636 0.120 0.639 0.911 1.063 3.271
Notifications disabled SET 996,016.00 0.801 0.120 0.823 1.111 1.615 3.423
KE$g DEL 664,451.81 1.411 0.168 1.439 1.871 2.247 7.111
KE$g SET 569,800.56 1.601 0.192 1.615 2.175 2.655 4.311

I ran multiple rounds of these benchmarks and observed no significant variation between runs.

The results show no meaningful performance difference between the current PR and the original unstable branch when notifications are disabled or when unrelated commands are executed. This indicates that the PR has no measurable performance impact in these scenarios.

With KE$g enabled and an active subscriber connected, SET and DEL performance decreased. In this benchmark, the notification overhead in Kvrocks, measured as throughput loss, was approximately 16.68% for DEL and 30.02% for SET. Under the same conditions, the corresponding overhead in Redis was approximately 50.03% for DEL and 42.79% for SET.

Because Redis and Kvrocks use different storage engines, their absolute RPS values are not directly comparable. Instead, the relevant comparison is the relative performance change before and after notifications are enabled. The official Redis documentation also notes that keyspace notifications are disabled by default partly because the feature consumes additional CPU resources. Redis Keyspace Notify

To further identify the source of the performance overhead, I profiled the PR branch using Linux perf and generated pprof-style differential call graphs from the samples. The graphs compare two scenarios with KE$g enabled: one without subscribers and one with an active subscriber. Red nodes indicate an increase in CPU usage after the subscriber was connected.

SET

set-notify pprof-style

DEL

del-notify pprof-style

The call graphs show that the performance bottleneck is in Server::PublishMessage. The underlying Pub/Sub delivery path is part of Kvrocks’ existing implementation, and this PR invokes it only when notifications are enabled and a notification event is actually generated. These results therefore indicate that the PR does not affect performance when notifications are disabled or when unrelated commands are executed. For the hot path that actually generates notifications, the observed performance cost has a clear and expected source.

@Aetherance
Aetherance requested a review from jihuayu July 30, 2026 03:25
@jihuayu

jihuayu commented Jul 30, 2026

Copy link
Copy Markdown
Member

@Aetherance Wow, you’re incredibly thorough, and the diagrams are excellent. I really like them. I’m currently away on a business trip and have been quite busy, but I’ll make time to take a look. Thank you for your patience.

@Aetherance

Copy link
Copy Markdown
Author

@Aetherance Wow, you’re incredibly thorough, and the diagrams are excellent. I really like them. I’m currently away on a business trip and have been quite busy, but I’ll make time to take a look. Thank you for your patience.

@jihuayu Thank you! I hope the comments and diagrams make this large PR easier to review—it’s my responsibility as the author. Feel free to reach out with any questions.

Comment thread src/commands/cmd_key.cc Outdated
Comment on lines +384 to +387
for (const auto &key : deleted_keys) {
conn->AddKeyspaceEvent(kNotifyGeneric, "del", std::string_view(key.data(), key.size()));
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

cc @git-hulk @PragmaTwice
Do you think this is a good design? My concern is that, with this approach, all the affected keys would need to be propagated from the storage layer up to the command layer, and every storage-layer method would need an additional field for them.

Would it be better to emit the event immediately after the deletion is performed in the storage layer, rather than propagating the information all the way up to the command layer?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Would it be better to emit the event immediately after the deletion is performed in the storage layer, rather than propagating the information all the way up to the command layer?

The initial version of this PR used a similar approach, but a reviewer pointed out that it was not very extensible:

Yes, I fully agree with this concern. We have an entry point to execute commands, so it should be possible to catch the changed events/data in one place instead of doing this in each command.

Therefore, I changed it to the current approach, where events are emitted at the unified command execution entry point.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

What I mean is, could we emit the event here instead of propagating it up to the command layer?

https://github.com/apache/kvrocks/pull/3541/changes#diff-df4860055937f1bb78946c49a63a6c4120812a1ec6229a5ded3aa3536220c253R210

Please don’t rush to make changes. I’d like to hear what others think first.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Thank you for the patient explanation.

I considered emitting the notification directly here when I first started implementing this PR, since this is indeed the cleanest place to access the complete semantics of the operation. I ultimately decided against it for the following reasons, which I hope help explain the decision:

The main reason is that this layer has no access to Server or Connection, so it cannot call PublishMessage. I also don't think the storage layer should be responsible for publishing messages.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Also, if this PR should be split into several smaller PRs, should I first refactor the current PR to use the context-based approach you suggested, and then split it? Or should I implement this approach only after the PR has been split?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Hi @jihuayu,

I’ve implemented this refactoring locally and rerun the benchmarks. The performance issue I was previously concerned about does not appear to exist; in fact, this version performs slightly better than my previous implementation.

I also found that, with this design, simply adjusting where notify is triggered can significantly reduce the overall complexity and eliminate a considerable amount of unnecessary code, such as the guards for re-entrant execution in Lua scripts or EXEC.

However, I’m still not sure whether this approach would be acceptable, so I’d like to hear your thoughts before updating this PR. For now, I’ve opened a demonstration PR in my own repository with the local implementation:

Aetherance#2

Do you think this approach would be acceptable? I’d like to get your feedback before proceeding further.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

You can take a quick look at this implementation. If the approach looks good, we can continue with a more detailed review in this PR.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Let me have a see

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

I’ve added some comments to explain the refactored implementation. I hope they’re helpful.

@jihuayu

jihuayu commented Aug 3, 2026

Copy link
Copy Markdown
Member

@Aetherance I think this PR would be a great fit for stacked PRs.

This is not a requirement. If you are interested in stacked PRs and would like to try them out, you could split this PR into a stack of smaller PRs. If that feels like too much trouble, you do not have enough time, or you are simply not interested, please feel free to ignore this message.

This is only an invitation in case the idea interests you.

@Aetherance

Copy link
Copy Markdown
Author

@Aetherance I think this PR would be a great fit for stacked PRs.

This is not a requirement. If you are interested in stacked PRs and would like to try them out, you could split this PR into a stack of smaller PRs. If that feels like too much trouble, you do not have enough time, or you are simply not interested, please feel free to ignore this message.

This is only an invitation in case the idea interests you.

Hi @jihuayu . Thanks for the suggestion! I’d be happy to try this approach.

However, since this PR is being submitted from a fork and I don’t have permission to push branches directly to apache/kvrocks, I’m still not sure how the native stacked PR workflow would work in this case. I noticed that one of the prerequisites may prevent me from using this feature:

A GitHub repository you can push to.

From:
https://docs.github.com/en/pull-requests/get-started/stacked-prs-quickstart#prerequisites

If the native stacked PR workflow is indeed not applicable here, I’d also be happy to split the current PR into several regular PRs.

@jihuayu

jihuayu commented Aug 7, 2026

Copy link
Copy Markdown
Member

@Aetherance I think your new implementation looks good. You can merge the code in, and then we can have the other reviewers take a look as well.

Regarding stacked PRs, I checked that they’re indeed not supported yet. The official response says it’s on the roadmap github/gh-stack#46, so we can leave it aside for now.

@Aetherance

Copy link
Copy Markdown
Author

@Aetherance I think your new implementation looks good. You can merge the code in, and then we can have the other reviewers take a look as well.

Regarding stacked PRs, I checked that they’re indeed not supported yet. The official response says it’s on the roadmap github/gh-stack#46, so we can leave it aside for now.

Got it! Thank you for your patience.

FCALL can apply writes before a later statement returns an error. Publish the events collected for those successful writes regardless of the final command status.
@Aetherance

Copy link
Copy Markdown
Author

Hi @jihuayu, sorry to bother you again. It looks like the CI needs maintainer approval before it can run. Could you please help run the CI when you have a chance?

@jihuayu

jihuayu commented Aug 8, 2026

Copy link
Copy Markdown
Member

Hi @git-hulk. I think the new abstraction looks good. Could you take a look?

@Aetherance

Copy link
Copy Markdown
Author

Some CI checks failed, but judging from the error logs, the failures don't appear to have been introduced by this PR.

@Aetherance

Copy link
Copy Markdown
Author

Hi @git-hulk @PragmaTwice , we’d love to hear your thoughts on this PR. Would you have time to take a look?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants