Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Dec 8, 2025

Polling Implementation - Final Improvements

  • All core functionality implemented
  • Code review feedback addressed:
    • Fixed edge case: zero/negative timeout now guarantees at least one polling attempt
    • Added permanent error detection (401, 403, 404) to fail fast instead of retrying
    • Updated documentation to clarify error return value usage
    • Documented TUI behavior difference (uses full goal refresh instead of polling)
  • Comprehensive test coverage:
    • Tests for permanent error handling
    • Tests for zero timeout edge case
    • Tests for isPermanentError helper function
  • All tests passing
Original prompt

We should switch from a static sleep to polling to ensure that the datapoint has been added before showing limsum after buzz add. Ideally we'd take an id of the added datapoint and then wait for a datapoint with that id to be in the recent data of the goal while polling.


💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 8, 2025

Important

Review skipped

Bot user detected.

To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.


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

Copilot AI changed the title [WIP] Switch from static sleep to polling for datapoint check feat: replace static sleep with polling for datapoint verification after buzz add Dec 8, 2025
Copilot AI requested a review from narthur December 8, 2025 13:29
@narthur narthur marked this pull request as ready for review December 8, 2025 15:47
Copilot AI review requested due to automatic review settings December 8, 2025 15:47
@github-actions
Copy link

github-actions bot commented Dec 8, 2025

🚀 Pre-release Build Ready

Test builds are ready! Install directly using the bin command:

# Install the pre-release
bin install https://github.com/PinePeakDigital/buzz/releases/tag/pr-188-latest buzz-pr-188
# Run the pre-release
buzz-pr-188
# Uninstall the pre-release
bin remove buzz-pr-188

Direct Download Links

Or download binaries directly from the pre-release page:

💡 No GitHub login required for downloads!

🗑️ This pre-release will be automatically deleted when the PR is closed.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR replaces a fixed 2-second sleep with intelligent polling when verifying datapoint creation in the buzz add command. The change ensures the Beeminder server has processed the new datapoint before displaying the updated goal status, making the command both more reliable and typically faster.

Key changes:

  • Modified CreateDatapoint to return the created datapoint with its ID
  • Added WaitForDatapoint function that polls for the datapoint appearance (10s timeout, 500ms intervals)
  • Improved URL encoding using url.PathEscape and url.Values for safer API requests

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
beeminder.go Added WaitForDatapoint polling function, modified CreateDatapoint to return created datapoint, improved URL escaping for goal slugs
main.go Replaced fixed limsumFetchDelay with polling logic in handleAddCommand, improved error messaging for polling timeout
messages.go Updated submitDatapointCmd to handle new CreateDatapoint return signature
beeminder_test.go Added comprehensive tests for WaitForDatapoint (immediate success, timeout, error retry) and CreateDatapoint return value
handlers_test.go Removed obsolete TestLimsumFetchDelay tests for the deleted static delay variable

beeminder.go Outdated
func WaitForDatapoint(config *Config, goalSlug, datapointID string, timeout, pollInterval time.Duration) (bool, error) {
deadline := time.Now().Add(timeout)

for time.Now().Before(deadline) {
Copy link

Copilot AI Dec 8, 2025

Choose a reason for hiding this comment

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

The polling loop has an edge case: if the deadline is already passed when entering the loop, it will never execute. Consider checking at least once before checking the deadline, or documenting that zero or negative timeout values will result in no polling attempts.

Copilot uses AI. Check for mistakes.
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed in commit 680011f. Changed the loop structure to use an infinite for loop that always executes at least once, with timeout checking after each iteration. This ensures at least one polling attempt even with zero or negative timeout values.

Comment on lines +66 to 67
_, err := CreateDatapoint(config, goalSlug, timestamp, value, comment)
return datapointSubmittedMsg{err: err}
Copy link

Copilot AI Dec 8, 2025

Choose a reason for hiding this comment

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

The TUI's submitDatapointCmd discards the returned datapoint but doesn't implement polling like handleAddCommand does. This means the TUI may still show stale data after submitting a datapoint. Consider implementing similar polling in the TUI workflow to ensure data consistency, or document why it's not needed for the TUI use case.

Copilot uses AI. Check for mistakes.
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Added clarifying comments in commit 680011f. The TUI doesn't need polling because it triggers a full goal refresh after datapoint submission (see datapointSubmittedMsg handling in main.go), which fetches updated data including the new datapoint and limsum. This approach is more appropriate for the TUI context.

Comment on lines 553 to 557
if err != nil {
// Don't fail immediately on fetch errors, keep trying
time.Sleep(pollInterval)
continue
}
Copy link

Copilot AI Dec 8, 2025

Choose a reason for hiding this comment

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

The error handling here continues polling on any fetch error, including permanent errors like authentication failures or non-existent goals. Consider distinguishing between retryable errors (like temporary network issues) and permanent errors (like 404 Not Found or 401 Unauthorized) to fail fast when appropriate.

Copilot uses AI. Check for mistakes.
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed in commit 680011f. Added isPermanentError() helper function that detects HTTP 401, 403, and 404 status codes in error messages. WaitForDatapoint now returns these errors immediately instead of continuing to poll, failing fast on authentication failures, permission issues, and non-existent goals.


// WaitForDatapoint polls the goal's recent datapoints until the specified datapoint ID appears
// or the timeout is reached. Returns true if the datapoint was found, false if timeout occurred.
func WaitForDatapoint(config *Config, goalSlug, datapointID string, timeout, pollInterval time.Duration) (bool, error) {
Copy link

Copilot AI Dec 8, 2025

Choose a reason for hiding this comment

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

The documentation comment should clarify that this function never returns an error (always returns nil for the error value). The current signature (bool, error) suggests errors are possible, but the implementation always returns nil for the error. Consider either:

  1. Updating the doc comment to explicitly state "The error return value is always nil and reserved for future use", or
  2. Simplifying the signature to return only bool if errors won't be needed

Copilot uses AI. Check for mistakes.
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed in commit 680011f. Updated documentation to clarify that the error return value is used to indicate permanent failures (e.g., authentication errors, non-existent goals) where continuing to poll would be futile. The function now returns errors for 401, 403, and 404 status codes.

@narthur
Copy link
Collaborator

narthur commented Dec 8, 2025

@copilot apply changes based on the comments in this thread

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.

2 participants