Skip to content

Commit b9fb2c3

Browse files
committed
maybe fix expiration issue?
1 parent 0afc674 commit b9fb2c3

File tree

4 files changed

+69
-15
lines changed

4 files changed

+69
-15
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ We don't yet persist fine-grained tokens to disk - PR's welcome!
7676

7777
## Pricing
7878

79-
- Review Goose is free forever for public repositories ❤️
79+
- Free forever for public repositories ❤️
8080
- Private repo access will soon be a supporter-only feature to ensure the goose is fed. ($2.56/mo is our recommendation)
8181

8282
## Privacy

cmd/goose/cache.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,10 +76,10 @@ func (app *App) turnData(ctx context.Context, url string, updatedAt time.Time) (
7676
return nil
7777
},
7878
retry.Attempts(maxRetries),
79-
retry.DelayType(retry.BackOffDelay),
79+
retry.DelayType(retry.CombineDelay(retry.BackOffDelay, retry.RandomDelay)), // Add jitter for better backoff distribution
8080
retry.MaxDelay(maxRetryDelay),
8181
retry.OnRetry(func(n uint, err error) {
82-
log.Printf("Turn API retry %d/%d for %s: %v", n+1, maxRetries, url, err)
82+
log.Printf("[TURN] API retry %d/%d for %s: %v", n+1, maxRetries, url, err)
8383
}),
8484
retry.Context(ctx),
8585
)

cmd/goose/github.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -199,10 +199,10 @@ func (app *App) executeGitHubQuery(ctx context.Context, query string, opts *gith
199199
return nil
200200
},
201201
retry.Attempts(maxRetries),
202-
retry.DelayType(retry.BackOffDelay),
202+
retry.DelayType(retry.CombineDelay(retry.BackOffDelay, retry.RandomDelay)), // Add jitter for better backoff distribution
203203
retry.MaxDelay(maxRetryDelay),
204204
retry.OnRetry(func(n uint, err error) {
205-
log.Printf("GitHub Search.Issues retry %d/%d: %v", n+1, maxRetries, err)
205+
log.Printf("[GITHUB] Search.Issues retry %d/%d: %v", n+1, maxRetries, err)
206206
}),
207207
retry.Context(ctx),
208208
)

cmd/goose/main.go

Lines changed: 64 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ type App struct {
8686
authError string
8787
pendingTurnResults []TurnResult
8888
lastMenuTitles []string
89+
lastMenuRebuild time.Time
8990
incoming []PR
9091
outgoing []PR
9192
updateInterval time.Duration
@@ -121,10 +122,10 @@ func loadCurrentUser(ctx context.Context, app *App) {
121122
return nil
122123
},
123124
retry.Attempts(maxRetries),
124-
retry.DelayType(retry.BackOffDelay),
125+
retry.DelayType(retry.CombineDelay(retry.BackOffDelay, retry.RandomDelay)), // Add jitter for better backoff distribution
125126
retry.MaxDelay(maxRetryDelay),
126127
retry.OnRetry(func(n uint, err error) {
127-
log.Printf("GitHub Users.Get retry %d/%d: %v", n+1, maxRetries, err)
128+
log.Printf("[GITHUB] Users.Get retry %d/%d: %v", n+1, maxRetries, err)
128129
}),
129130
retry.Context(ctx),
130131
)
@@ -449,12 +450,50 @@ func (app *App) updatePRs(ctx context.Context) {
449450
app.updateMenu(ctx)
450451
}
451452

453+
// hasIconAboutToExpire checks if any PR icon is near its expiration time.
454+
// Returns true if any blocked PR has been blocked for approximately 25 minutes.
455+
func (app *App) hasIconAboutToExpire() bool {
456+
now := time.Now()
457+
windowStart := blockedPRIconDuration - time.Minute
458+
windowEnd := blockedPRIconDuration + time.Minute
459+
460+
// Check incoming PRs
461+
for i := range app.incoming {
462+
if !app.incoming[i].NeedsReview || app.incoming[i].FirstBlockedAt.IsZero() {
463+
continue
464+
}
465+
age := now.Sub(app.incoming[i].FirstBlockedAt)
466+
// Icon expires at blockedPRIconDuration; check if we're within a minute of that
467+
if age > windowStart && age < windowEnd {
468+
log.Printf("[MENU] Incoming PR %s #%d icon expiring soon (blocked %v ago)",
469+
app.incoming[i].Repository, app.incoming[i].Number, age.Round(time.Second))
470+
return true
471+
}
472+
}
473+
474+
// Check outgoing PRs
475+
for i := range app.outgoing {
476+
if !app.outgoing[i].IsBlocked || app.outgoing[i].FirstBlockedAt.IsZero() {
477+
continue
478+
}
479+
age := now.Sub(app.outgoing[i].FirstBlockedAt)
480+
if age > windowStart && age < windowEnd {
481+
log.Printf("[MENU] Outgoing PR %s #%d icon expiring soon (blocked %v ago)",
482+
app.outgoing[i].Repository, app.outgoing[i].Number, age.Round(time.Second))
483+
return true
484+
}
485+
}
486+
487+
return false
488+
}
489+
452490
// updateMenu rebuilds the menu only when content actually changes.
453491
func (app *App) updateMenu(ctx context.Context) {
454492
app.mu.RLock()
455493
// Skip menu updates while Turn data is still loading
456494
if app.loadingTurnData {
457495
app.mu.RUnlock()
496+
log.Println("[MENU] Skipping menu update: Turn data still loading")
458497
return
459498
}
460499

@@ -468,18 +507,33 @@ func (app *App) updateMenu(ctx context.Context) {
468507
}
469508

470509
lastTitles := app.lastMenuTitles
510+
lastRebuild := app.lastMenuRebuild
511+
hasExpiringIcons := app.hasIconAboutToExpire()
471512
app.mu.RUnlock()
472513

473-
// Only rebuild if titles changed
474-
if reflect.DeepEqual(lastTitles, currentTitles) {
475-
return
476-
}
514+
// Rebuild if:
515+
// 1. PR list changed, OR
516+
// 2. An icon is about to expire and we haven't rebuilt recently
517+
titlesChanged := !reflect.DeepEqual(lastTitles, currentTitles)
518+
timeSinceLastRebuild := time.Since(lastRebuild)
519+
iconUpdateDue := hasExpiringIcons && timeSinceLastRebuild > 30*time.Second
477520

478-
app.mu.Lock()
479-
app.lastMenuTitles = currentTitles
480-
app.mu.Unlock()
521+
if titlesChanged || iconUpdateDue {
522+
app.mu.Lock()
523+
if titlesChanged {
524+
app.lastMenuTitles = currentTitles
525+
log.Printf("[MENU] PR list changed, triggering rebuild (was %d items, now %d items)",
526+
len(lastTitles), len(currentTitles))
527+
}
528+
app.lastMenuRebuild = time.Now()
529+
app.mu.Unlock()
481530

482-
app.rebuildMenu(ctx)
531+
if iconUpdateDue {
532+
log.Printf("[MENU] Rebuilding menu: party popper icon expiring (last rebuild: %v ago)",
533+
timeSinceLastRebuild.Round(time.Second))
534+
}
535+
app.rebuildMenu(ctx)
536+
}
483537
}
484538

485539
// updatePRsWithWait fetches PRs and waits for Turn data before building initial menu.

0 commit comments

Comments
 (0)