(ctx context.Context)
| 178 | } |
| 179 | |
| 180 | func (w *Worker) tick(ctx context.Context) { |
| 181 | // Use a dedicated tick timeout that is longer than the |
| 182 | // polling interval. This gives concurrent HTTP calls enough |
| 183 | // headroom without stalling the next tick excessively. |
| 184 | ctx, cancel := context.WithTimeout(ctx, w.tickTimeout) |
| 185 | defer cancel() |
| 186 | |
| 187 | acquiredRows, err := w.store.AcquireStaleChatDiffStatuses(ctx, w.batchSize) |
| 188 | if err != nil { |
| 189 | w.logger.Warn(ctx, "acquire stale chat diff statuses", |
| 190 | slog.Error(err)) |
| 191 | return |
| 192 | } |
| 193 | if len(acquiredRows) == 0 { |
| 194 | return |
| 195 | } |
| 196 | |
| 197 | // Build refresh requests directly from acquired rows. |
| 198 | requests := make([]RefreshRequest, 0, len(acquiredRows)) |
| 199 | for _, row := range acquiredRows { |
| 200 | requests = append(requests, RefreshRequest{ |
| 201 | Row: chatDiffStatusFromRow(row), |
| 202 | OwnerID: row.OwnerID, |
| 203 | }) |
| 204 | } |
| 205 | |
| 206 | results, err := w.refresher.Refresh(ctx, requests) |
| 207 | if err != nil { |
| 208 | w.logger.Warn(ctx, "batch refresh chat diff statuses", |
| 209 | slog.Error(err)) |
| 210 | return |
| 211 | } |
| 212 | |
| 213 | for _, res := range results { |
| 214 | if res.Error != nil { |
| 215 | w.logger.Debug(ctx, "refresh chat diff status", |
| 216 | slog.F("chat_id", res.Request.Row.ChatID), |
| 217 | slog.Error(res.Error)) |
| 218 | // Apply a longer backoff for rows whose owner has |
| 219 | // no linked token — retrying every 2 minutes is |
| 220 | // pointless until the user links their account. |
| 221 | backoff := DiffStatusTTL |
| 222 | if errors.Is(res.Error, ErrNoTokenAvailable) { |
| 223 | backoff = NoTokenBackoff |
| 224 | } |
| 225 | // Back off so the row isn't retried immediately. |
| 226 | if err := w.store.BackoffChatDiffStatus(ctx, |
| 227 | database.BackoffChatDiffStatusParams{ |
| 228 | ChatID: res.Request.Row.ChatID, |
| 229 | StaleAt: w.clock.Now().UTC().Add(backoff), |
| 230 | }, |
| 231 | ); err != nil { |
| 232 | w.logger.Warn(ctx, "backoff failed chat diff status", |
| 233 | slog.F("chat_id", res.Request.Row.ChatID), |
| 234 | slog.Error(err)) |
| 235 | } |
| 236 | continue |
| 237 | } |
no test coverage detected