feat(daemon): send Anthropic usage data to server#241
Conversation
After fetching rate limit data from Anthropic, fire-and-forget POST to /api/v1/anthropic-usage so the server can schedule push notifications when rate limits reset. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
Summary of ChangesHello @AnnatarHe, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request introduces a new feature to send Anthropic usage data to the ShellTime server. This allows the server to schedule push notifications related to rate limit resets. The implementation uses existing patterns for sending HTTP requests and includes error handling to prevent blocking the daemon. Highlights
Changelog
Activity
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
| s.rateLimitCache.mu.Unlock() | ||
|
|
||
| // Send usage data to server for push notification scheduling (fire-and-forget) | ||
| go s.sendAnthropicUsageToServer(ctx, usage) |
There was a problem hiding this comment.
🔴 Fire-and-forget goroutine uses a context that is cancelled immediately after spawning
The sendAnthropicUsageToServer goroutine is spawned at line 436 with the same ctx that was passed to fetchRateLimit. However, the callers of fetchRateLimit (at lines 171-173 and 194-196) create a timeout context with defer cancel() in the enclosing anonymous function. When fetchRateLimit returns synchronously, cancel() fires, cancelling the context. The newly spawned goroutine then tries to make an HTTP request with this already-cancelled context, which will fail immediately.
Root Cause and Impact
The call chain is:
timerLoopspawns an anonymous goroutine (line 166-174)- Inside it:
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)thendefer cancel() s.fetchRateLimit(ctx)is called synchronously- Inside
fetchRateLimit, at line 436:go s.sendAnthropicUsageToServer(ctx, usage)— this spawns a goroutine with the samectx fetchRateLimitreturns →defer cancel()fires →ctxis cancelledsendAnthropicUsageToServercallsmodel.SendHTTPRequestJSONwhich useshttp.NewRequestWithContext(ctx, ...)atmodel/api.base.go:50— this request will fail immediately withcontext canceled
Impact: The usage data will never be successfully sent to the server. The fire-and-forget feature is completely non-functional. Every attempt will log "Failed to send anthropic usage to server" with a context cancellation error.
| go s.sendAnthropicUsageToServer(ctx, usage) | |
| go s.sendAnthropicUsageToServer(context.Background(), usage) |
Was this helpful? React with 👍 or 👎 to provide feedback.
There was a problem hiding this comment.
Code Review
This pull request introduces a new feature to send Anthropic usage data to the server for push notification scheduling. It adds a new function sendAnthropicUsageToServer to handle the data sending logic and calls it after fetching rate limit data. The changes include creating data structures for the payload and using the existing SendHTTPRequestJSON function. The test plan includes verifying the POST request and ensuring it's fire-and-forget.
| // sendAnthropicUsageToServer sends the Anthropic usage data to the ShellTime server | ||
| // for scheduling push notifications when rate limits reset. | ||
| func (s *CCInfoTimerService) sendAnthropicUsageToServer(ctx context.Context, usage *AnthropicRateLimitData) { | ||
| if s.config.Token == "" { | ||
| return | ||
| } | ||
|
|
||
| type usageBucket struct { | ||
| Utilization float64 `json:"utilization"` | ||
| ResetsAt string `json:"resets_at"` | ||
| } | ||
| type usagePayload struct { | ||
| FiveHour usageBucket `json:"five_hour"` | ||
| SevenDay usageBucket `json:"seven_day"` | ||
| } | ||
|
|
||
| payload := usagePayload{ | ||
| FiveHour: usageBucket{ | ||
| Utilization: usage.FiveHourUtilization, | ||
| ResetsAt: usage.FiveHourResetsAt, | ||
| }, | ||
| SevenDay: usageBucket{ | ||
| Utilization: usage.SevenDayUtilization, | ||
| ResetsAt: usage.SevenDayResetsAt, | ||
| }, | ||
| } | ||
|
|
||
| err := model.SendHTTPRequestJSON(model.HTTPRequestOptions[usagePayload, any]{ | ||
| Context: ctx, | ||
| Endpoint: model.Endpoint{ | ||
| Token: s.config.Token, | ||
| APIEndpoint: s.config.APIEndpoint, | ||
| }, | ||
| Method: "POST", | ||
| Path: "/api/v1/anthropic-usage", | ||
| Payload: payload, | ||
| Timeout: 5 * time.Second, | ||
| }) | ||
| if err != nil { | ||
| slog.Warn("Failed to send anthropic usage to server", slog.Any("err", err)) | ||
| } | ||
| } |
There was a problem hiding this comment.
Consider adding more robust error handling. While the current implementation logs a warning if sending usage data fails, it might be beneficial to implement a retry mechanism with exponential backoff to handle transient network issues. This would improve the reliability of sending usage data to the server.
|
|
||
| // sendAnthropicUsageToServer sends the Anthropic usage data to the ShellTime server | ||
| // for scheduling push notifications when rate limits reset. | ||
| func (s *CCInfoTimerService) sendAnthropicUsageToServer(ctx context.Context, usage *AnthropicRateLimitData) { |
There was a problem hiding this comment.
The function sendAnthropicUsageToServer could benefit from input validation. Before sending the data, validate the usage parameter to ensure that the FiveHourUtilization, SevenDayUtilization, FiveHourResetsAt, and SevenDayResetsAt fields contain valid data. This can prevent unexpected errors or incorrect data being sent to the server.
Codecov Report❌ Patch coverage is
Flags with carried forward coverage won't be shown. Click here to find out more.
... and 2 files with indirect coverage changes 🚀 New features to boost your workflow:
|
Summary
/api/v1/anthropic-usageon the ShellTime serverSendHTTPRequestJSONpattern with CLI token authRelated PRs
Test plan
/api/v1/anthropic-usageon rate limit fetch🤖 Generated with Claude Code