Skip to content

Conversation

@aparna0522
Copy link
Contributor

@aparna0522 aparna0522 commented Dec 22, 2025

Add support for counter tables/queries in Mutation Tracking

patch by Aparna Naik; for CASSANDRA-20959

@aparna0522 aparna0522 force-pushed the anaik-counters-support branch 3 times, most recently from 0ff447a to 0164723 Compare December 23, 2025 07:58
@aparna0522 aparna0522 marked this pull request as ready for review December 23, 2025 08:00
@iamaleksey iamaleksey assigned iamaleksey and unassigned iamaleksey Jan 6, 2026
@iamaleksey iamaleksey self-requested a review January 6, 2026 11:59
@aparna0522 aparna0522 force-pushed the anaik-counters-support branch from 0164723 to fada5f9 Compare January 6, 2026 21:31
Copy link
Member

@iamaleksey iamaleksey left a comment

Choose a reason for hiding this comment

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

Not fully done with the review

* @param handler the response handler
* @param coordinatorAckInfo optional coordinator info for forwarded writes (null for local coordinator)
*/
public static void sendToReplicasOnly(Mutation mutation, ReplicaPlan.ForWrite plan, TrackedWriteResponseHandler handler, ForwardedWrite.CoordinatorAckInfo coordinatorAckInfo)
Copy link
Member

Choose a reason for hiding this comment

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

You should be able to refactor applyLocallyAndSendToReplicas() to use sendToReplicasOnly(), with a few modifications - instead of duplicating the very much same logic in both these methods.

@aparna0522 aparna0522 force-pushed the anaik-counters-support branch from ee07f5e to 66bba91 Compare January 7, 2026 19:13
writeMetrics.localRequests.mark();

MutationId id = MutationTrackingService.instance.nextMutationId(keyspaceName, token);
mutation = mutation.withMutationId(id);
Copy link
Member

Choose a reason for hiding this comment

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

Now that I'm thinking about this again, I think it would be fine to restore this line, so the logic is shared between regular- and counter mutations, and undo the change to CounterMutation (so it will use the id() that we've just set here).


MutationId id = MutationTrackingService.instance.nextMutationId(keyspaceName, token);

if (logger.isTraceEnabled())
Copy link
Member

Choose a reason for hiding this comment

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

You don't need logger.isTraceEnabled() check here. We use isXEnabled() log checks in two scenarios:

  1. The arguments to the method are expensive computations (or allocate), or
  2. There are more than two parameters (excluding the format string) to pass. This is because there exist overloads for format string + 0, 1, 2 arguments, but anything beyond goes through a vararg method (e.g. void trace(String var1, Object... var2) which has to allocate an array / potentially box some primitives).
    This should be somewhere in the style guide, but I can't actually find it myself :\

Preconditions.checkState(foundSelf, "Coordinator must be a replica");

// Notify handler that local write succeeded (mutation was already applied before calling this method)
if (notifyHandlerForLocal)
Copy link
Member

@iamaleksey iamaleksey Jan 8, 2026

Choose a reason for hiding this comment

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

I believe it would be better to mimic, for counters, in LocalCounterMutationRunnable#run() what we do for regular mutations, and invoke handler.onResponse(null) there, instead of having it be done two different ways for regular- and counter mutations. I'd also rename the method to simply sendToReplicas() - 'only' is ambiguous here.

TrackedWriteRequest.sendToReplicasOnly(result, plan, handler, coordinatorAckInfo);

// Send this leader's response back to coordinator
MessagingService.instance().send(message.emptyResponse(), respondToAddress);
Copy link
Member

Choose a reason for hiding this comment

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

I think this code is missing setting up a callback on the leader. If you look at MutationVerbHandler#respond() you'll notice that the replicas respond to the coordinator (so the client can be notified) and to the leader (so that the leader can mark the id as witnessed on that replica pro-actively). For regular mutations we seem to be using LeaderCallback class for this.

* @param coordinatorAckInfo optional coordinator info for forwarded writes (null for local coordinator)
* @param notifyHandlerForLocal if true, notify handler for local replica (used when mutation already applied)
*/
private static void sendToReplicasInternal(Mutation mutation, ReplicaPlan.ForWrite plan,
Copy link
Member

Choose a reason for hiding this comment

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

I believe it should be possible to reuse this method for ForwardedWrite#applyLocallyAndForwardToReplicas() now as well?

writeMetrics.remoteRequests.mark();
return ForwardedWrite.forwardMutation(mutation, plan, rs, requestTime);

if (mutation instanceof CounterMutation)
Copy link
Member

Choose a reason for hiding this comment

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

I personally would move this branching to ForwardedWrite, to a forward method that accepts an IMutation.

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.

3 participants