Skip to content

Conversation

@jkowalski
Copy link
Contributor

@jkowalski jkowalski commented Jul 22, 2025

This was a very stupid bug introduced in
kopia#4682

Fixes kopia#4729
@jkowalski jkowalski requested a review from julio-lopez July 22, 2025 00:37
@jkowalski jkowalski marked this pull request as ready for review July 22, 2025 00:38
Copilot AI review requested due to automatic review settings July 22, 2025 00:38
Copy link

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 fixes a scheduling bug in the sleepable timer implementation that was incorrectly limiting long duration timers to a maximum sleep time instead of allowing them to wait for their full duration. The fix ensures timers continue looping until they reach the actual target time rather than being capped prematurely.

  • Changed timer logic to continue looping until the actual target time is reached instead of capping at maxSleepTime
  • Updated test cases to verify timers wait for their full specified duration
  • Adjusted test timing tolerances and expectations to match the corrected behavior

Reviewed Changes

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

File Description
internal/sleepable/sleepable_timer.go Fixed timer logic to continue looping instead of closing channel immediately when intermediate timer triggers
internal/sleepable/sleepable_timer_test.go Updated test expectations to verify full duration waits and adjusted timing tolerances

Comment on lines +178 to +185
target := start.Add(100 * time.Millisecond) // Use a shorter duration for testing
timer := NewTimer(clock.Now, target)
select {
case <-timer.C:
elapsed := clock.Now().Sub(start)
if elapsed < testMaxSleepTime-5*time.Millisecond || elapsed > testMaxSleepTime+50*time.Millisecond {
t.Errorf("very long timer triggered at wrong time: expected ~%v, got %v", testMaxSleepTime, elapsed)
// Allow tolerance for timing variations
if elapsed < 100*time.Millisecond-20*time.Millisecond || elapsed > 100*time.Millisecond+50*time.Millisecond {
t.Errorf("very long timer triggered at wrong time: expected ~%v, got %v", 100*time.Millisecond, elapsed)
Copy link

Copilot AI Jul 22, 2025

Choose a reason for hiding this comment

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

The hardcoded duration values (100time.Millisecond, 20time.Millisecond, 50*time.Millisecond) are duplicated from line 178 and create magic numbers. Consider extracting these into named constants or variables for better maintainability.

Copilot uses AI. Check for mistakes.
Comment on lines +178 to +185
target := start.Add(100 * time.Millisecond) // Use a shorter duration for testing
timer := NewTimer(clock.Now, target)
select {
case <-timer.C:
elapsed := clock.Now().Sub(start)
if elapsed < testMaxSleepTime-5*time.Millisecond || elapsed > testMaxSleepTime+50*time.Millisecond {
t.Errorf("very long timer triggered at wrong time: expected ~%v, got %v", testMaxSleepTime, elapsed)
// Allow tolerance for timing variations
if elapsed < 100*time.Millisecond-20*time.Millisecond || elapsed > 100*time.Millisecond+50*time.Millisecond {
t.Errorf("very long timer triggered at wrong time: expected ~%v, got %v", 100*time.Millisecond, elapsed)
Copy link

Copilot AI Jul 22, 2025

Choose a reason for hiding this comment

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

Another instance of the hardcoded 100*time.Millisecond magic number that should be extracted into a variable to match the duration used in the test setup.

Copilot uses AI. Check for mistakes.
@codecov
Copy link

codecov bot commented Jul 22, 2025

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 76.38%. Comparing base (cb455c6) to head (56efdf7).
Report is 609 commits behind head on master.

Additional details and impacted files
@@            Coverage Diff             @@
##           master    #4732      +/-   ##
==========================================
+ Coverage   75.86%   76.38%   +0.51%     
==========================================
  Files         470      530      +60     
  Lines       37301    40467    +3166     
==========================================
+ Hits        28299    30911    +2612     
- Misses       7071     7510     +439     
- Partials     1931     2046     +115     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@jkowalski jkowalski enabled auto-merge (squash) July 22, 2025 00:45
tolerance = 20 * time.Millisecond
}

if elapsed < tt.duration-tolerance || elapsed > tt.duration+tolerance {
Copy link
Collaborator

Choose a reason for hiding this comment

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

is this going to lead to flaky tests?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

we can adjust it if ends up being flaky

@jkowalski jkowalski merged commit 0733cb4 into kopia:master Jul 22, 2025
27 checks passed
t.Run("very long duration", func(t *testing.T) {
start := clock.Now()
target := start.Add(24 * time.Hour)
target := start.Add(100 * time.Millisecond) // Use a shorter duration for testing
Copy link
Collaborator

Choose a reason for hiding this comment

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

The subtest name no longer describes the case being tested with the new parameters.

if elapsed < testMaxSleepTime-5*time.Millisecond || elapsed > testMaxSleepTime+50*time.Millisecond {
t.Errorf("very long timer triggered at wrong time: expected ~%v, got %v", testMaxSleepTime, elapsed)
// Allow tolerance for timing variations
if elapsed < 100*time.Millisecond-20*time.Millisecond || elapsed > 100*time.Millisecond+50*time.Millisecond {
Copy link
Collaborator

Choose a reason for hiding this comment

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

It'd be good to check the tolerance in terms of the "target duration", that is, what is being added to start.Add above.

@julio-lopez
Copy link
Collaborator

julio-lopez commented Jul 22, 2025

Thanks @jkowalski! 🏆

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.

Since upgrade to 0.21 snapshots are taken every 20 to 30 seconds

2 participants