Skip to content

[service] allow follower ReportEvent queries - #263

Draft
charpty wants to merge 1 commit into
mainfrom
agent/reportevent-follower-read
Draft

[service] allow follower ReportEvent queries#263
charpty wants to merge 1 commit into
mainfrom
agent/reportevent-follower-read

Conversation

@charpty

@charpty charpty commented Jul 31, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • Allow GetHostCacheState to serve follower requests as a best-effort read of the node's local ReportEvent view.
  • Keep ReportEvent mutations leader-only.
  • Add a regression test covering follower read access and follower write rejection.

Motivation

When the leader is unavailable, followers should still be able to return their local cache state. The returned state may be stale and is not intended to provide strong consistency.

Validation

  • External source: //kv_cache_manager/service/test:all with debug + ASAN — 7/7 passed.
  • Internal source: //kv_cache_manager/service/test:all with debug + ASAN — 7/7 passed.
  • git diff --check
  • buildifier -mode=check kv_cache_manager/service/test/BUILD

@qoderai qoderai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Review Summary

Minimal, correct change. Flipping GetHostCacheState's API_CALL_GUARD to is_leader_only=false is the right mechanism and has precedent in GetClusterInfo (line 825). ReportEvent correctly stays leader-only, so mutations aren't opened up to followers.

The regression test is well-constructed: using an empty instance_id to prove the follower gate was passed (reaching normal INVALID_ARGUMENT validation) rather than SERVER_NOT_LEADER is a neat way to assert gate behavior without standing up a full instance/data set, and the write-rejection assertion confirms the asymmetry. The -fno-access-control copt and deps match the file's existing conventions, and ServiceCallGuard is null-safe for the nullptr metrics_reporter (guarded at service_call_guard.cc:142).

One inline note about a behavioral consequence worth confirming: followers now surface INSTANCE_NOT_EXIST (rather than SERVER_NOT_LEADER) for instances not in their local view, and it's worth confirming (a) the client treats non-leader responses as non-authoritative, and (b) that followers actually hold a populated local view given ReportEvent is leader-only.

No blocking issues.


🤖 Generated by Qoder

Comment on lines +906 to +908
// This is a best-effort read of the node's local ReportEvent view. Followers may
// serve a stale view, while ReportEvent mutations remain leader-only.
API_CALL_GUARD("GetHostCacheState", false);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Allowing followers to serve this read is a reasonable best-effort behavior, and is_leader_only=false mirrors GetClusterInfo (line 825). Two consequences worth confirming:

  1. Error-code shift for missing instances. Previously a follower always returned SERVER_NOT_LEADER here regardless of the instance. Now a follower whose local view doesn't contain the instance returns INSTANCE_NOT_EXIST (via CacheManager::GetHostCacheStatemeta_searcher_manager_->GetMetaSearcher, cache_manager.cc:3703, mapped through ToMetaPbError). Callers that read INSTANCE_NOT_EXIST as "instance doesn't exist anywhere" rather than "this follower doesn't have it locally" could behave incorrectly — worth confirming the client SDK retries the leader (or otherwise treats non-leader responses as non-authoritative) on this code.

  2. Is the follower's local view actually populated? ReportEvent (the write path that populates this state) is leader-only, so a node that has never been leader won't have received those mutations. Is the meta/registry state replicated to followers through another path, or is the expected local view limited to a stale snapshot from when this node was last leader? The latter is fine for best-effort reads — just want it to be explicit since OnNoLongerLeader pauses the reclaimer but doesn't otherwise sync new events.


🤖 Generated by Qoder

@github-actions github-actions Bot added the ai reviewed AI has reviewed this PR label Jul 31, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ai reviewed AI has reviewed this PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant