Repository navigation
Update cached company metrics on track regardless of connection state - #202
Open
ryanechternacht wants to merge 1 commit into
Open
ryanechternacht wants to merge 1 commit into
ryanechternacht wants to merge 1 commit into
Conversation
This was referenced Sep 29, 2026
Track's optimistic metric update was gated on _datastreamConnected. That field is only maintained by websocket connection monitoring. In replicator mode it is set to false at construction and never updated, so the update never ran in replicator mode, whether or not the replicator reported ready. In websocket mode it stopped while the connection was down, even though flag checks keep evaluating from the cache in that state. Remove the gate so the update runs whenever a datastream client exists and the event names a company. Server updates carry absolute metric values and replace the cached company, so the local bump is superseded rather than double counted, and an uncached company is left alone. The event is still sent to the API as before. UpdateCompanyMetrics returns false for routine cases (company not cached, no matching metric) and logs its own real failures, so the caller now logs false at debug instead of error. Otherwise enabling the update in replicator mode would log an error for every track event without a matching metric. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
ryanechternacht
force-pushed
the
ryan/replicator-track-offline
branch
from
September 30, 2026 17:47
13ee966 to
509a91e
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Trackoptimistically bumps the cached company's metrics so usage limits reflect an event before the server pushes an updated company. In replicator mode, when a customer's Schematic account is closed or Schematic is unreachable, the replicator stays up with its Redis cache but reportsready: false, and flag checks keep evaluating from that cache. Usage should keep counting locally in that state.Findings
The update in
Schematic.Trackis gated on_datastreamConnected. That field is only maintained byStartConnectionMonitoring, which runs only in websocket mode. In replicator mode the constructor sets it tofalseand nothing ever changes it. So in replicator mode the optimistic update has never run, whether the replicator reports ready or not. The track event itself is still enqueued and sent to the API.History: the gate came in with the optimistic update itself in #81 (
company != null && _datastreamClient != null && _datastreamConnected) and was carried into #91 (replicator mode), which added the_datastreamConnected = falsereplicator branch. Neither PR has a description or a review comment about the gate. The #81 review discussion was about deep copying the company and locking so concurrent updates are not lost, not about connection state. In the Go SDK the equivalent gate (c.datastreamClient.IsConnected(), which maps to replicator readiness in replicator mode) came from a refactor (schematic-go #82) of an earlierdatastreamConnectedcheck, also without a stated reason.Correctness checks for removing it:
Merge.UpsertMetrics) carry absolute metric values and replace the cached company. The local bump is superseded by the next server value, which already includes the event if the server counted it. Nothing adds a server delta on top of the local bump.UpdateCompanyMetricsreturns without writing when the company is not cached, so no partial or empty entries are created.No correctness reason to keep the gate was found.
Change
UpdateCompanyMetricsreturnsfalsefor routine cases (company not cached, event with no matching metric) and logs its own real failures (lock timeout, cache write failure). The caller now logsfalseat debug instead of error. Without this, enabling the update in replicator mode would log an error for every track event that has no matching metric.UseDatastream()helper.Note: in replicator mode
Tracknow does Redis reads and a write per call that names a company, the same work websocket mode with Redis already does.Test
New
TrackOfflineMetricsTests:Trackcalls bump the cached metric from 10 to 15 (failed before this change).Trackbumps the cached metric (failed before this change).dotnet build(Release, all target frameworks) anddotnet test: 442 passed, 0 failed.🤖 Generated with Claude Code