Skip to content

search-service cleanup: drop cache metrics, rename RoomIDs, dead const#133

Merged
mliu33 merged 1 commit into
mainfrom
claude/search-service-cleanup
Apr 28, 2026
Merged

search-service cleanup: drop cache metrics, rename RoomIDs, dead const#133
mliu33 merged 1 commit into
mainfrom
claude/search-service-cleanup

Conversation

@Joey0538
Copy link
Copy Markdown
Collaborator

@Joey0538 Joey0538 commented Apr 28, 2026

Summary

Four small unrelated cleanups in search-service and one stray dead constant in search-sync-worker:

  1. Remove restricted-rooms cache hit/miss Prometheus counters. search_service_cache_hits_total{kind} and search_service_cache_misses_total{kind} tracked Valkey lookups for the per-user restricted-rooms blob. The hit/miss view wasn't actionable in practice and the operationally useful tail-latency view stays via search_service_es_duration_seconds{op="user_room_get"}. The kind parameter on loadRestricted (only plumbed to those counters) is dropped. The metricKindMessages / metricKindRooms constants stay — still used by request-path metrics.

  2. Rename SearchMessagesRequest.RoomIdsRoomIDs. Go-style initialism. JSON tag stays roomIds so the wire format is unchanged.

  3. Drop the sort.Strings on user-input slices in scopedAccessClauses. The sort was only there for deterministic test output; tests use assert.ElementsMatch so ordering didn't matter. Slices come from caller-supplied RoomIDs (already deterministic). The sortedRIDs helper stays — it sorts map iteration in globalAccessClauses, which is a different concern (and load-bearing per its existing comment).

  4. Delete the unused esErrIndexNotFound constant in search-sync-worker/handler.go. Only esErrDocumentMissing is referenced; collapse the const block and tighten the doc comment to call out that other 404 error types stay treated as failures.

Test plan

  • make test — green across the monorepo
  • make lint — 0 issues
  • grep RoomIds repo-wide returns no Go field hits (only the JSON tag string "roomIds" and lowercase roomIds in prose comments referring to the wire-format key)
  • grep esErrIndexNotFound repo-wide returns 0 matches
  • JSON wire compat verified — model_test.go round-trip asserts roomIds is the marshalled key
  • Optional: confirm /metrics output no longer exposes search_service_cache_* after deploy

https://claude.ai/code/session_015Cu3UPeWDU4DaJwP7JZtvc


Generated by Claude Code

Summary by CodeRabbit

Release Notes

  • Bug Fixes

    • Improved Elasticsearch error handling to better distinguish transient failures from genuine errors, enhancing reliability.
  • Refactor

    • Updated naming conventions in search request models.
    • Removed internal cache performance metrics.
    • Simplified restricted-rooms cache initialization process.
    • Adjusted filtering logic ordering for scoped searches.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 28, 2026

Warning

Rate limit exceeded

@Joey0538 has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 38 minutes and 59 seconds before requesting another review.

To keep reviews running without waiting, you can enable usage-based add-on for your organization. This allows additional reviews beyond the hourly cap. Account admins can enable it under billing.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: eb324b4f-780a-4844-867c-82529cd9c298

📥 Commits

Reviewing files that changed from the base of the PR and between ddead4c and 9f9a6f4.

📒 Files selected for processing (8)
  • pkg/model/model_test.go
  • pkg/model/search.go
  • search-service/handler.go
  • search-service/handler_test.go
  • search-service/metrics.go
  • search-service/query_messages.go
  • search-service/query_messages_test.go
  • search-sync-worker/handler.go
📝 Walkthrough

Walkthrough

This PR standardizes the SearchMessagesRequest struct field from RoomIds to RoomIDs across models and tests, removes Elasticsearch cache hit/miss metrics from the search service, simplifies restricted-room cache loading by removing the endpoint "kind" parameter, removes deterministic sorting in scoped access clauses, and refines Elasticsearch 404 error classification in the search-sync-worker.

Changes

Cohort / File(s) Summary
Model Field Standardization
pkg/model/search.go, pkg/model/model_test.go
Renamed SearchMessagesRequest struct field from RoomIds to RoomIDs (JSON tag unchanged as roomIds,omitempty), updating both model definition and related test fixture.
Search Service Query Updates
search-service/query_messages.go, search-service/query_messages_test.go, search-service/handler_test.go
Updated references to use RoomIDs field name and removed deterministic sorting of unrestricted/restricted subsets in scoped access clauses.
Cache Metrics Removal
search-service/metrics.go, search-service/handler.go
Deleted cache-hit and cache-miss Prometheus counter vectors and their accessor functions; removed kind parameter from loadRestricted calls to eliminate endpoint-labeled metrics tracking.
Error Handling Refinement
search-sync-worker/handler.go
Removed index_not_found_exception classification; only document_missing_exception on update-on-missing-doc is treated as benign, with all other 404 errors treated as real failures.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

Possibly related PRs

Suggested reviewers

  • mliu33

Poem

🐰 Room IDs now stand tall with proper case,
Cache metrics fade from their tracking space,
Sorting constraints released, errors refined,
Elasticsearch errors better defined! 📊✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 22.22% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the four main cleanup objectives: removing cache metrics, renaming RoomIds to RoomIDs, and removing a dead constant.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/search-service-cleanup

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
pkg/model/model_test.go (1)

1297-1319: ⚠️ Potential issue | 🟡 Minor

Keep a wire-key assertion for SearchMessagesRequest.

This round-trip still passes if the JSON tag regresses, because it never inspects the marshaled key. Add an assertion on the populated payload so this rename stays wire-compatible.

🧪 Suggested assertion
         data, err := json.Marshal(&req)
         require.NoError(t, err)
+        var raw map[string]any
+        require.NoError(t, json.Unmarshal(data, &raw))
+        _, hasRoomIDs := raw["roomIds"]
+        assert.True(t, hasRoomIDs, "roomIds must remain the wire key when populated")
         var dst model.SearchMessagesRequest
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@pkg/model/model_test.go` around lines 1297 - 1319, The test
TestSearchMessagesRequestJSON currently only round-trips the struct and checks
omission of roomIds but doesn't assert the actual JSON wire keys; add an
assertion that verifies the marshaled JSON uses the expected field names (e.g.,
"searchText" and "roomIds") so future tag renames will fail the test. Modify the
subtests in TestSearchMessagesRequestJSON to unmarshal the marshaled bytes into
a map[string]any (as already done in the "global" case) and add explicit
assertions that raw contains "searchText" with the expected value in the "full"
case and that "roomIds" is present with the expected slice, and keep the
"global" case assertion that "roomIds" is absent.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@pkg/model/model_test.go`:
- Around line 1297-1319: The test TestSearchMessagesRequestJSON currently only
round-trips the struct and checks omission of roomIds but doesn't assert the
actual JSON wire keys; add an assertion that verifies the marshaled JSON uses
the expected field names (e.g., "searchText" and "roomIds") so future tag
renames will fail the test. Modify the subtests in TestSearchMessagesRequestJSON
to unmarshal the marshaled bytes into a map[string]any (as already done in the
"global" case) and add explicit assertions that raw contains "searchText" with
the expected value in the "full" case and that "roomIds" is present with the
expected slice, and keep the "global" case assertion that "roomIds" is absent.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: edb35731-ad37-438a-b73c-73c19729b64e

📥 Commits

Reviewing files that changed from the base of the PR and between 7773eda and ddead4c.

📒 Files selected for processing (8)
  • pkg/model/model_test.go
  • pkg/model/search.go
  • search-service/handler.go
  • search-service/handler_test.go
  • search-service/metrics.go
  • search-service/query_messages.go
  • search-service/query_messages_test.go
  • search-sync-worker/handler.go

Comment thread search-service/handler.go Outdated
…const)

- search-service/metrics.go + handler.go: remove restricted-rooms Valkey
  cache hit/miss counters (search_service_cache_hits_total,
  search_service_cache_misses_total). They tracked cache events for the
  per-user restricted-rooms blob lookup and weren't actionable signals;
  the operationally useful tail-latency view stays via
  search_service_es_duration_seconds{op="user_room_get"}. Drop the now-
  unused `kind` parameter from loadRestricted; metricKind* constants
  stay (still used by request-path metrics).

- pkg/model/search.go: rename SearchMessagesRequest.RoomIds → RoomIDs to
  follow Go's initialism convention. JSON tag stays `roomIds` so the
  wire format is unchanged. Update all callers + tests.

- search-service/query_messages.go: remove the sort.Strings calls on the
  user-provided unrestricted/restrictedSubset slices in
  scopedAccessClauses. Tests use ElementsMatch; emission order matches
  the input order. The sortedRIDs helper stays (operates on map keys
  for global search and is documented as load-bearing for ES query-plan
  cacheability).

- search-sync-worker/handler.go: drop the unused esErrIndexNotFound
  constant. Only its sibling esErrDocumentMissing is referenced;
  collapse the const block to a single line and update the doc comment
  to call out that other 404 error types are still treated as failures.

https://claude.ai/code/session_015Cu3UPeWDU4DaJwP7JZtvc
@Joey0538 Joey0538 force-pushed the claude/search-service-cleanup branch from ddead4c to 9f9a6f4 Compare April 28, 2026 02:49
Copy link
Copy Markdown
Collaborator Author

Extended the cleanup to also drop search_service_es_duration_seconds{op="user_room_get"} per follow-up review.

Why: the user_room_get slice only fired on the cache-miss path of the restricted-rooms lookup, and a single-doc GET is generally fast and uniform — its standalone latency wasn't actionable, and tail-latency triage is already covered by the op="search" slice. Removing it leaves only one value (search) on the op label, which is a Prometheus anti-pattern, so I also collapsed the label entirely: metricESDuration is now a plain Histogram instead of HistogramVec. The metricOpSearch / metricOpUserRoomGet constants and the esDurFor dispatch helper go with it.

Final metric inventory (all 4-5/5 importance):

Metric What it tells you
search_service_requests_total{kind, status} Throughput + outcome distribution per endpoint
search_service_request_duration_seconds{kind} User-perceived API latency per endpoint
search_service_es_duration_seconds ES _search latency — decomposes total request time into "us" vs "ES"

Tests + lint green on 9f9a6f4. Spec doc intentionally not touched.


Generated by Claude Code

Copy link
Copy Markdown
Collaborator

@mliu33 mliu33 left a comment

Choose a reason for hiding this comment

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

Super, thanks!

@mliu33 mliu33 merged commit 94e9ad0 into main Apr 28, 2026
6 checks passed
@Joey0538 Joey0538 deleted the claude/search-service-cleanup branch April 28, 2026 03:01
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