Repository navigation
feat: charges advancer - #4065
Conversation
|
Caution Review failedPull request was closed or merged during review 📝 Walkthrough🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ 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 |
2dd2d2f to
3c0df79
Compare
There was a problem hiding this comment.
Actionable comments posted: 3
🧹 Nitpick comments (1)
cmd/jobs/quickstart/cronjobs.go (1)
85-101: Consider guarding against overlapping charge-advance runs.Small reliability/perf hardening: if one run takes longer than a minute, the next scheduled run can start before the previous one finishes.
Proposed change
import ( "log/slog" "os" + "sync/atomic" "time" @@ namespaces := []string{"default"} batchSize := 10 + var chargesAdvanceRunning atomic.Bool @@ if internal.App.ChargesAutoAdvancer != nil { _, err = s.NewJob( gocron.DurationJob(time.Minute), gocron.NewTask(func() { + if !chargesAdvanceRunning.CompareAndSwap(false, true) { + slog.Warn("Skipping charge advancement; previous run still in progress") + return + } + defer chargesAdvanceRunning.Store(false) + slog.Info("Advancing charges") err := internal.App.ChargesAutoAdvancer.All(cmd.Context(), namespaces) if err != nil { slog.Error("Error advancing charges", "error", err) } }), )🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@cmd/jobs/quickstart/cronjobs.go` around lines 85 - 101, The scheduled charge-advance job created with s.NewJob (using gocron.DurationJob(time.Minute) and calling internal.App.ChargesAutoAdvancer.All) can overlap if a run exceeds one minute; add a guard so only one run executes at a time (e.g., a package-level sync.Mutex or an atomic boolean) around the body that calls ChargesAutoAdvancer.All to skip or defer concurrent executions; update the s.NewJob task to acquire the guard before calling internal.App.ChargesAutoAdvancer.All and release it afterwards, and ensure errors are still logged when skipped or when All returns an error.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@openmeter/billing/charges/service.go`:
- Around line 203-208: ListCustomersToAdvanceInput.Validate currently only
checks AdvanceAfterLTE but allows a partially filled pagination.Page that causes
negative offsets in adapter/search.go when calling page.Offset()/page.Limit();
update ListCustomersToAdvanceInput.Validate to also validate the Page when it's
partially populated (e.g., if Page.PageSize>0 or Page.PageNumber>0) by invoking
the pagination.Page.Validate() (or equivalent) so only fully valid pages are
accepted while preserving zero-value page support for internal non-paginated
calls.
In `@openmeter/billing/worker/worker.go`:
- Around line 195-200: The AdvanceChargesEvent path currently forwards events
straight to w.asyncAdvanceChargesHandler.Handle, skipping the namespace-lock
short-circuit used elsewhere; update the grouphandler.NewGroupEventHandler
callback for AdvanceChargesEvent to first check the namespace lock (use the same
check used by other handlers, e.g., the existing namespace lock predicate or
method on w that other handlers use) and return nil when the namespace is locked
so locked namespaces are skipped instead of retried; ensure you keep the
reference to w.asyncAdvanceChargesHandler.Handle for normal processing when the
namespace is not locked.
---
Nitpick comments:
In `@cmd/jobs/quickstart/cronjobs.go`:
- Around line 85-101: The scheduled charge-advance job created with s.NewJob
(using gocron.DurationJob(time.Minute) and calling
internal.App.ChargesAutoAdvancer.All) can overlap if a run exceeds one minute;
add a guard so only one run executes at a time (e.g., a package-level sync.Mutex
or an atomic boolean) around the body that calls ChargesAutoAdvancer.All to skip
or defer concurrent executions; update the s.NewJob task to acquire the guard
before calling internal.App.ChargesAutoAdvancer.All and release it afterwards,
and ensure errors are still logged when skipped or when All returns an error.
🪄 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: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 53ab813a-19ac-4cdd-aeea-52c72bd92f4b
📒 Files selected for processing (15)
app/common/billing.goapp/common/openmeter_billingworker.gocmd/jobs/billing/advancecharges/advancecharges.gocmd/jobs/billing/billing.gocmd/jobs/internal/wire.gocmd/jobs/internal/wire_gen.gocmd/jobs/quickstart/cronjobs.goopenmeter/billing/charges/adapter.goopenmeter/billing/charges/adapter/search.goopenmeter/billing/charges/events.goopenmeter/billing/charges/service.goopenmeter/billing/charges/service/list.goopenmeter/billing/charges/worker/advance/advance.goopenmeter/billing/charges/worker/asyncadvance/asyncadvance.goopenmeter/billing/worker/worker.go
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Overview
advance_after deadline and advances them sequentially, collecting and logging errors along the way.
the event triggers async charge advancement for a specific customer.
pairs from the ChargesSearchV1 view filtered by advance_after <= now and non-terminal statuses.
and provides CLI commands (advance-charges list, advance-charges customer, advance-charges all) for manual operation.
keeping the existing invoice advancement path completely unchanged.
Notes for reviewer
Summary by CodeRabbit
New Features
Tests