Skip to content

eventservice: event service use server level tz to avoid unncessary call and verbose log#4836

Merged
ti-chi-bot[bot] merged 4 commits into
pingcap:masterfrom
3AceShowHand:tz-log
Apr 17, 2026
Merged

eventservice: event service use server level tz to avoid unncessary call and verbose log#4836
ti-chi-bot[bot] merged 4 commits into
pingcap:masterfrom
3AceShowHand:tz-log

Conversation

@3AceShowHand
Copy link
Copy Markdown
Collaborator

@3AceShowHand 3AceShowHand commented Apr 16, 2026

What problem does this PR solve?

Issue Number: close #4843

This PR is helpful to remove the call to the GetTimezone method, which print a log each time on the dispatcher request, such as add dispatcher

What is changed and how it works?

  • event broker set the tz from the server config
  • remove the timezone from the dispatcher request
  • set the filter to the changefeed level on the event broker side.

Check List

Tests

  • Unit test
  • Integration test
  • Manual test (add detailed scripts or steps below)
  • No code

Questions

Will it cause performance regression or break compatibility?
Do you need to update user documentation, design documentation or monitoring documentation?

Release note

`None`

Summary by CodeRabbit

  • Refactor

    • Restructured how changefeed filters and timezone are managed and shared across the event service to improve consistency and reuse.
  • Tests

    • Updated tests to exercise the new shared filter and changefeed status initialization behavior.

@ti-chi-bot ti-chi-bot Bot added do-not-merge/needs-linked-issue release-note Denotes a PR that will be considered when it comes time to generate release notes. size/M Denotes a PR that changes 30-99 lines, ignoring generated files. labels Apr 16, 2026
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 16, 2026

📝 Walkthrough

Walkthrough

Changefeed filter handling and timezone responsibilities were refactored: DispatcherInfo now exposes filter config, eventService centralizes timezone, and eventBroker/getOrSetChangefeedStatus create or reuse a shared filter via shared filter storage and attach it to changefeedStatus. Tests updated to use the new APIs.

Changes

Cohort / File(s) Summary
Interface & Messaging
pkg/eventservice/event_service.go, pkg/messaging/message.go
DispatcherInfo now exposes GetFilterConfig() *eventpb.FilterConfig (removed GetFilter() and GetTimezone()); messaging types return filter config instead of constructed filters/timezone.
Broker & Changefeed status
pkg/eventservice/event_broker.go, pkg/eventservice/dispatcher_stat.go
eventBroker gains timezone string; getOrSetChangefeedStatus now accepts DispatcherInfo, initializes/loads a shared filter via filter.GetSharedFilterStorage().GetOrSetFilter(...), stores the filter on changefeedStatus, and returns stored status.
Service-level timezone
pkg/eventservice/event_service.go
eventService reads global TZ once (tz *time.Location) and passes it to brokers; removed per-dispatcher timezone handling.
Tests updated
pkg/eventservice/..._test.go (multiple files), pkg/eventservice/event_service_test.go, pkg/eventservice/dispatcher_stat_test.go, pkg/eventservice/event_broker_test.go, pkg/eventservice/event_scanner_test.go, pkg/eventservice/metrics_collector_test.go
Tests updated to use GetFilterConfig() and new getOrSetChangefeedStatus(info) call; added helpers to initialize and assert shared filter presence and reuse in changefeedStatus.
Removed direct filter construction
pkg/messaging/message.go
Removed methods that constructed/parsing timezone and created filter.Filter; code now supplies raw filter configs to shared storage creation.

Sequence Diagram(s)

sequenceDiagram
  participant Dispatcher as DispatcherInfo
  participant Broker as eventBroker
  participant Storage as SharedFilterStorage
  participant Status as changefeedStatus

  Dispatcher->>Broker: addDispatcher(info)
  Broker->>Broker: getOrSetChangefeedStatus(info)
  alt status exists
    Broker-->>Dispatcher: return existing changefeedStatus
  else new status
    Broker->>Storage: GetOrSetFilter(changefeedID, info.GetFilterConfig(), Broker.timezone)
    Storage-->>Broker: filter (or error -> panic)
    Broker->>Status: create changefeedStatus{filter: filter, ...}
    Broker->>Broker: LoadOrStore(status)
    Broker-->>Dispatcher: return new changefeedStatus
  end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested labels

lgtm, approved, size/XL

Suggested reviewers

  • flowbehappy
  • asddongmen
  • wk989898

Poem

🐰 I hopped from broker to shared-filter store,
Took timezone once, no more per-dispatcher chore,
Filters shared and pointers true,
Dispatchers lighter, tests pass through,
A little hop of code—now watch it soar! ✨

🚥 Pre-merge checks | ❌ 3

❌ Failed checks (2 warnings, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 6.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Description check ⚠️ Warning The PR description is incomplete and does not properly follow the repository's contribution template. While it includes the required structure, critical sections lack substantive detail and contain placeholder values. Replace the placeholder 'close #xxx' with the actual issue number; provide detailed explanations of changes in each section; update the release note section with appropriate content instead of 'None'.
Title check ❓ Inconclusive The title references using server-level timezone, which is a core change in the PR. However, it mentions avoiding 'unnecessary call and verbose log' which are not clearly demonstrated by the changeset. Clarify whether the changes actually eliminate calls/logs or if the title should focus solely on the timezone consolidation aspect.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request refactors the event service to centralize timezone management and move filter creation into the dispatcher initialization process. The DispatcherInfo interface was updated to provide filter configurations instead of pre-instantiated filters, and the eventService now utilizes a global timezone setting. Feedback was provided regarding a potential nil pointer dereference when accessing the filter configuration in newDispatcherStat, which could lead to a panic if the configuration is not explicitly checked before use.

Comment thread pkg/eventservice/dispatcher_stat.go Outdated
Copy link
Copy Markdown
Contributor

@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.

🧹 Nitpick comments (1)
pkg/eventservice/event_broker.go (1)

1577-1588: Potential race condition in getOrSetChangefeedStatus - mitigated by current usage

The Load-then-Store pattern here is not atomic. If two goroutines call this concurrently for the same changefeedID, both could create new changefeedStatus instances, and one would overwrite the other, potentially losing registered dispatchers.

Currently this appears safe because callers (addDispatcher, resetDispatcher) are invoked sequentially from eventService.Run's select loop. However, consider using sync.Map.LoadOrStore for defensive thread-safety:

💡 Suggested defensive improvement
 func (c *eventBroker) getOrSetChangefeedStatus(changefeedID common.ChangeFeedID, syncPointInterval time.Duration) *changefeedStatus {
-	stat, ok := c.changefeedMap.Load(changefeedID)
-	if !ok {
-		stat = newChangefeedStatus(changefeedID, syncPointInterval)
-		stat.(*changefeedStatus).timezone = c.timezone
-		log.Info("new changefeed status", zap.Stringer("changefeedID", changefeedID))
-		c.changefeedMap.Store(changefeedID, stat)
+	newStat := newChangefeedStatus(changefeedID, syncPointInterval)
+	newStat.timezone = c.timezone
+	stat, loaded := c.changefeedMap.LoadOrStore(changefeedID, newStat)
+	if !loaded {
+		log.Info("new changefeed status", zap.Stringer("changefeedID", changefeedID))
 		metrics.EventServiceScanWindowBaseTsGaugeVec.WithLabelValues(changefeedID.String()).Set(0)
 		metrics.EventServiceScanWindowIntervalGaugeVec.WithLabelValues(changefeedID.String()).Set(defaultScanInterval.Seconds())
 	}
 	return stat.(*changefeedStatus)
 }

Note: This creates a changefeedStatus on every call even if one exists, but it ensures atomicity. Alternatively, use double-checked locking if allocation cost is a concern.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@pkg/eventservice/event_broker.go` around lines 1577 - 1588, The
Load-then-Store pattern in getOrSetChangefeedStatus can race; change the
implementation to use changefeedMap.LoadOrStore to atomically obtain or insert a
*changefeedStatus (call newChangefeedStatus only for the candidate), then if the
returned loaded flag is false (i.e., we stored the new one) set the timezone on
that instance, log and call
metrics.EventServiceScanWindowBaseTsGaugeVec/...Set(...) and return the stored
value; if loaded is true discard the candidate and return the existing value.
This preserves current behavior but makes getOrSetChangefeedStatus atomic and
avoids overwriting existing changefeedStatus (symbols: getOrSetChangefeedStatus,
changefeedMap, newChangefeedStatus, changefeedStatus,
metrics.EventServiceScanWindowBaseTsGaugeVec).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@pkg/eventservice/event_broker.go`:
- Around line 1577-1588: The Load-then-Store pattern in getOrSetChangefeedStatus
can race; change the implementation to use changefeedMap.LoadOrStore to
atomically obtain or insert a *changefeedStatus (call newChangefeedStatus only
for the candidate), then if the returned loaded flag is false (i.e., we stored
the new one) set the timezone on that instance, log and call
metrics.EventServiceScanWindowBaseTsGaugeVec/...Set(...) and return the stored
value; if loaded is true discard the candidate and return the existing value.
This preserves current behavior but makes getOrSetChangefeedStatus atomic and
avoids overwriting existing changefeedStatus (symbols: getOrSetChangefeedStatus,
changefeedMap, newChangefeedStatus, changefeedStatus,
metrics.EventServiceScanWindowBaseTsGaugeVec).

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: fc7b7e96-124b-455b-a856-ff8d31dce4aa

📥 Commits

Reviewing files that changed from the base of the PR and between b7ca768 and ec899db.

📒 Files selected for processing (5)
  • pkg/eventservice/dispatcher_stat.go
  • pkg/eventservice/event_broker.go
  • pkg/eventservice/event_service.go
  • pkg/eventservice/event_service_test.go
  • pkg/messaging/message.go

@3AceShowHand
Copy link
Copy Markdown
Collaborator Author

/retest

@3AceShowHand
Copy link
Copy Markdown
Collaborator Author

/test all

@ti-chi-bot ti-chi-bot Bot added size/L Denotes a PR that changes 100-499 lines, ignoring generated files. and removed size/M Denotes a PR that changes 30-99 lines, ignoring generated files. labels Apr 16, 2026
@3AceShowHand
Copy link
Copy Markdown
Collaborator Author

/test all

Copy link
Copy Markdown
Contributor

@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.

Actionable comments posted: 2

🧹 Nitpick comments (1)
pkg/eventservice/event_service_test.go (1)

502-537: Unify these changefeed-status test helpers.

newChangefeedStatusForTest hardcodes UTC, while addChangefeedStatusToBrokerForTest creates a partially initialized changefeedStatus and relies on mustInitChangefeedStatusFilter later. That makes it easy for future tests to miss the broker invariant that status.filter is preinitialized from the broker timezone. A single helper that always takes the intended timezone and fully initializes status would keep tests closer to production behavior.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@pkg/eventservice/event_service_test.go` around lines 502 - 537, Tests use
multiple helpers that differ in timezone handling and initialization
(newChangefeedStatusForTest, addChangefeedStatusToBrokerForTest,
mustInitChangefeedStatusFilter), which risks leaving changefeedStatus.filter
uninitialized; replace them with a single helper (e.g.,
newInitializedChangefeedStatusForTest) that accepts DispatcherInfo, timezone
string, and an eventBroker pointer, creates a fully initialized changefeedStatus
via newChangefeedStatus(changefeedID, syncPointInterval), stores it into
broker.changefeedMap, and sets status.filter using
newChangefeedFilterForTest/GetOrSetFilter so the stored status always has filter
populated; update tests to call this new helper and remove the partial helpers
to enforce the broker invariant.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@pkg/eventservice/event_broker.go`:
- Around line 1588-1595: The code currently panics on filter init failure;
replace the log.Panic call in the block that calls
filter.GetSharedFilterStorage().GetOrSetFilter(changefeedID,
info.GetFilterConfig(), c.timezone) with returning the error up the call chain
(wrap with context mentioning changefeedID and filter config), and update
callers of this site (the functions addDispatcher and resetDispatcher) to
propagate and return that error instead of letting the process crash; ensure
changefeedFilter is only used when err == nil and that the returned error is
handled by the caller paths that previously assumed success.
- Around line 1578-1606: SharedFilterStorage currently lacks a removal method,
causing filters keyed by changefeedID to leak after changefeed teardown; add a
DeleteFilter(changefeedID) method to the SharedFilterStorage implementation
(complementing GetOrSetFilter) that safely removes the filter from the internal
map, and then call SharedFilterStorage.DeleteFilter(changefeedID) from the same
teardown locations where changefeedMap.Delete(changefeedID) is invoked (the code
paths that remove the changefeedStatus and metrics) so the filter entry is
removed atomically/under the same synchronization to prevent memory leaks.

---

Nitpick comments:
In `@pkg/eventservice/event_service_test.go`:
- Around line 502-537: Tests use multiple helpers that differ in timezone
handling and initialization (newChangefeedStatusForTest,
addChangefeedStatusToBrokerForTest, mustInitChangefeedStatusFilter), which risks
leaving changefeedStatus.filter uninitialized; replace them with a single helper
(e.g., newInitializedChangefeedStatusForTest) that accepts DispatcherInfo,
timezone string, and an eventBroker pointer, creates a fully initialized
changefeedStatus via newChangefeedStatus(changefeedID, syncPointInterval),
stores it into broker.changefeedMap, and sets status.filter using
newChangefeedFilterForTest/GetOrSetFilter so the stored status always has filter
populated; update tests to call this new helper and remove the partial helpers
to enforce the broker invariant.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 386da5e3-94a9-4ce6-9883-4180e8a1dd73

📥 Commits

Reviewing files that changed from the base of the PR and between ec899db and 4f8ec88.

📒 Files selected for processing (7)
  • pkg/eventservice/dispatcher_stat.go
  • pkg/eventservice/dispatcher_stat_test.go
  • pkg/eventservice/event_broker.go
  • pkg/eventservice/event_broker_test.go
  • pkg/eventservice/event_scanner_test.go
  • pkg/eventservice/event_service_test.go
  • pkg/eventservice/metrics_collector_test.go
🚧 Files skipped from review as they are similar to previous changes (1)
  • pkg/eventservice/dispatcher_stat.go

Comment thread pkg/eventservice/event_broker.go
Comment thread pkg/eventservice/event_broker.go
@ti-chi-bot ti-chi-bot Bot added size/XL Denotes a PR that changes 500-999 lines, ignoring generated files. and removed size/L Denotes a PR that changes 100-499 lines, ignoring generated files. labels Apr 17, 2026
@3AceShowHand
Copy link
Copy Markdown
Collaborator Author

/test all

@ti-chi-bot ti-chi-bot Bot added release-note-none Denotes a PR that doesn't merit a release note. and removed do-not-merge/needs-linked-issue release-note Denotes a PR that will be considered when it comes time to generate release notes. labels Apr 17, 2026
@wk989898
Copy link
Copy Markdown
Collaborator

Please add an integration test to cover this situation

@3AceShowHand 3AceShowHand changed the title eventservice: event service use server level tz eventservice: event service use server level tz to avoid unncessary call and verbose log Apr 17, 2026
@ti-chi-bot ti-chi-bot Bot added needs-1-more-lgtm Indicates a PR needs 1 more LGTM. approved labels Apr 17, 2026
@ti-chi-bot ti-chi-bot Bot added the lgtm label Apr 17, 2026
@ti-chi-bot
Copy link
Copy Markdown

ti-chi-bot Bot commented Apr 17, 2026

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: asddongmen, wk989898

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Details Needs approval from an approver in each of these files:
  • OWNERS [asddongmen,wk989898]

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@ti-chi-bot ti-chi-bot Bot removed the needs-1-more-lgtm Indicates a PR needs 1 more LGTM. label Apr 17, 2026
@ti-chi-bot
Copy link
Copy Markdown

ti-chi-bot Bot commented Apr 17, 2026

[LGTM Timeline notifier]

Timeline:

  • 2026-04-17 06:54:23.484507043 +0000 UTC m=+1716868.689867090: ☑️ agreed by wk989898.
  • 2026-04-17 09:17:13.215555963 +0000 UTC m=+1725438.420916020: ☑️ agreed by asddongmen.

@3AceShowHand
Copy link
Copy Markdown
Collaborator Author

/retest

@ti-chi-bot ti-chi-bot Bot merged commit 32e1ab5 into pingcap:master Apr 17, 2026
26 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

approved lgtm release-note-none Denotes a PR that doesn't merit a release note. size/XL Denotes a PR that changes 500-999 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

remove the verbose timezone log

3 participants