[webhooks] use scheduling instead of polling - #397
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (3)
🚧 Files skipped from review as they are similar to previous changes (3)
WalkthroughAdds DAO queries for due webhook counts and next attempt time, updates the repository to use due-webhook checks, and changes the worker to accept initial delays, reschedule from the next attempt time, and process each webhook inside a NonCancellable block. ChangesWebhook Due-Time Scheduling
Sequence Diagram(s)sequenceDiagram
participant WorkManager
participant WebhookQueueProcessorWorker
participant WebhookQueueRepository
participant WebhookQueueDao
WorkManager->>WebhookQueueProcessorWorker: start(initialDelayMs)
WebhookQueueProcessorWorker->>WebhookQueueRepository: hasDueWebhooks()
WebhookQueueRepository->>WebhookQueueDao: dueWebhooksCount(currentTime)
WebhookQueueProcessorWorker->>WebhookQueueRepository: getNextAttemptTime()
WebhookQueueRepository->>WebhookQueueDao: getNextAttemptTime()
WebhookQueueProcessorWorker->>WorkManager: enqueue next run with setInitialDelay(...)
Possibly related PRs
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In
`@app/src/main/java/me/capcom/smsgateway/modules/webhooks/workers/WebhookQueueProcessorWorker.kt`:
- Around line 106-108: The WebhookQueueProcessorWorker start path is replacing
the currently running unique work, which can cancel an active processor. Update
the enqueueUniqueWork call in WebhookQueueProcessorWorker.start() so it does not
use REPLACE for the live worker; instead use a non-replacing policy or split
rescheduling of delayed retries into a separate path while preserving the
existing WORK_NAME identity.
- Around line 161-186: The scheduling branch in
WebhookQueueProcessorWorker.after the cleanup/getNextAttemptTime flow drops
short-delay retries when nextAttempt is within MAX_FOREGROUND_DELAY_MS, leaving
pending webhooks unscheduled. Update the logic in WebhookQueueProcessorWorker
(around the cleanupOldEntries/getNextAttemptTime/start path) so short future
retries are either delayed in the worker or rescheduled immediately instead of
falling through to Result.success(); keep the existing start(...) call for long
delays and add the missing branch for near-term attempts.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 0acd7d05-9677-400a-a263-43508f558922
📒 Files selected for processing (3)
app/src/main/java/me/capcom/smsgateway/modules/webhooks/db/WebhookQueueDao.ktapp/src/main/java/me/capcom/smsgateway/modules/webhooks/db/WebhookQueueRepository.ktapp/src/main/java/me/capcom/smsgateway/modules/webhooks/workers/WebhookQueueProcessorWorker.kt
b7759f1 to
cacbc7a
Compare
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In
`@app/src/main/java/me/capcom/smsgateway/modules/webhooks/workers/WebhookQueueProcessorWorker.kt`:
- Around line 262-291: The webhook processing block in
WebhookQueueProcessorWorker.processBatch keeps the entire send path inside
withContext(NonCancellable), which prevents cancellation during
sendWebhook(webhook). Move NonCancellable so it wraps only the cleanup/update
steps after sendWebhook returns, specifically
webhookRepository.completeWebhook(webhook.id) and handleWebhookFailure(...),
while leaving sendWebhook(webhook) cancellable inside the main try flow.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: ab0c52d4-ec46-48c8-9a0e-9d7cbec65780
📒 Files selected for processing (3)
app/src/main/java/me/capcom/smsgateway/modules/webhooks/db/WebhookQueueDao.ktapp/src/main/java/me/capcom/smsgateway/modules/webhooks/db/WebhookQueueRepository.ktapp/src/main/java/me/capcom/smsgateway/modules/webhooks/workers/WebhookQueueProcessorWorker.kt
🚧 Files skipped from review as they are similar to previous changes (2)
- app/src/main/java/me/capcom/smsgateway/modules/webhooks/db/WebhookQueueDao.kt
- app/src/main/java/me/capcom/smsgateway/modules/webhooks/db/WebhookQueueRepository.kt
cacbc7a to
46d89ba
Compare
🤖 Pull request artifacts
|
46d89ba to
7f8418e
Compare
7f8418e to
8b9ad1b
Compare
|
This PR is stale because it has been open for 7 days with no activity. |
8b9ad1b to
a6a0ab8
Compare
e66e9bb to
00f850c
Compare
00f850c to
a9c00ed
Compare
a9c00ed to
6450156
Compare
|
@greptile review |
8cd8e0d to
7a909e8
Compare
7a909e8 to
038f096
Compare
038f096 to
855361d
Compare
Summary by CodeRabbit
Greptile Summary
This PR replaces continuous polling with a scheduling approach for webhook retries: after draining all currently-due webhooks, the worker reads the minimum
next_attempttime from the DB and re-enqueues itself with that exact delay usingAPPEND_OR_REPLACE, so the processor only wakes when work is genuinely ready. It also fixes two previously-flagged issues — theHttpClientleak (clientis nowlazyand closed infinally) andCancellationExceptionbeing swallowed by the genericcatch (e: Exception)block.doWork): loop exits whenhasDueWebhooks()is false, thengetNextAttemptTime()drives a targeted self-reschedule;APPEND_OR_REPLACEis used so an urgent immediateREPLACEfromSendWebhookWorkercorrectly wins.WebhookQueueDao):scheduledWebhooksCountreplaced by time-boundeddueWebhooksCount(currentTime)and newgetNextAttemptTime()(MIN of pending/failednext_attempt).processBatch): each webhook is now wrapped in its ownwithContext(NonCancellable)+try/catch, so a per-item failure cannot abort the rest of the batch.Confidence Score: 4/5
hasDueWebhooks()andgetNextAttemptTime()use consistent time-bounded queries,APPEND_OR_REPLACEcorrectly yields to urgentREPLACEenqueues fromSendWebhookWorker, and theCancellationExceptionrethrow andHttpClientlazy/close fixes address the two previously-reported defects. The remaining comments are purely style suggestions (clamping a negative delay before logging and guarding the lazy client close infinally).WebhookQueueProcessorWorker.kt— thefinally { client.close() }block and the rawdelayMscomputation are the two spots worth a quick look before merging.Important Files Changed
scheduledWebhooksCountwith time-boundeddueWebhooksCount(currentTime)and addsgetNextAttemptTime(); both queries are correct and the KDoc accurately describes the new semantics.hasScheduledWebhookswithhasDueWebhooks(passes current time) and addsgetNextAttemptTimethin wrapper; logic is straightforward and correct.CancellationExceptionswallowing and the HttpClient lazy/close issues; adds per-webhookNonCancellableisolation. One P2 style issue:client.close()infinallyalways forces lazy initialisation even on early failures.Sequence Diagram
sequenceDiagram participant SW as SendWebhookWorker participant WM as WorkManager participant P as WebhookQueueProcessorWorker participant R as WebhookQueueRepository SW->>R: enqueueWebhook(url, payload) SW->>WM: "start(policy=REPLACE, delay=0)" WM->>P: doWork() loop Until no due webhooks P->>R: hasDueWebhooks() R-->>P: true P->>R: getPendingWebhooks() loop Per webhook (NonCancellable) P->>R: startProcessing(id) P->>P: sendWebhook() alt Success P->>R: completeWebhook(id) else Failure P->>R: scheduleRetry(id, backoff) end end end P->>R: cleanupOldEntries() P->>R: getNextAttemptTime() R-->>P: nextAttempt (future time) P->>WM: "start(policy=APPEND_OR_REPLACE, delay=nextAttempt-now)" P-->>WM: Result.success() Note over WM,P: Delayed worker wakes at next retry time WM->>P: doWork() (after delay)Reviews (14): Last reviewed commit: "[webhooks] use scheduling instead of pol..." | Re-trigger Greptile