mirror of
https://github.com/Wei-Shaw/sub2api.git
synced 2026-09-24 16:05:44 +08:00
perf: run balance/quota notification checks async
Move notifyBalanceLow and notifyAccountQuota to goroutines so the threshold checking logic (DB settings reads, threshold calculation, crossing detection) no longer blocks the request thread. Both are fire-and-forget with panic recovery and log-only error handling.
This commit is contained in:
@@ -1 +1 @@
|
||||
0.1.110.28
|
||||
0.1.110.29
|
||||
|
||||
@@ -7529,14 +7529,21 @@ func finalizePostUsageBilling(p *postUsageBillingParams, deps *billingDeps, resu
|
||||
|
||||
deps.deferredService.ScheduleLastUsedUpdate(p.Account.ID)
|
||||
|
||||
notifyBalanceLow(p, deps, result)
|
||||
notifyAccountQuota(p, deps, result)
|
||||
// Notification checks run async — all parameters are already captured,
|
||||
// no dependency on the request context or upstream connection.
|
||||
go notifyBalanceLow(p, deps, result)
|
||||
go notifyAccountQuota(p, deps, result)
|
||||
}
|
||||
|
||||
// notifyBalanceLow sends balance low notification after deduction.
|
||||
// When result.NewBalance is available (from DB transaction RETURNING), it is used directly
|
||||
// to reconstruct oldBalance, avoiding stale Redis reads and concurrent-deduction races.
|
||||
func notifyBalanceLow(p *postUsageBillingParams, deps *billingDeps, result *UsageBillingApplyResult) {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
slog.Error("panic in notifyBalanceLow", "recover", r)
|
||||
}
|
||||
}()
|
||||
if p.IsSubscriptionBill || p.Cost.ActualCost <= 0 || p.User == nil || deps.balanceNotifyService == nil {
|
||||
slog.Debug("notifyBalanceLow: skipped",
|
||||
"is_subscription", p.IsSubscriptionBill,
|
||||
@@ -7573,6 +7580,11 @@ func resolveOldBalance(p *postUsageBillingParams, result *UsageBillingApplyResul
|
||||
// When result.QuotaState is available (from DB transaction RETURNING), it is passed directly
|
||||
// to avoid a separate DB read that may see stale or concurrently-modified data.
|
||||
func notifyAccountQuota(p *postUsageBillingParams, deps *billingDeps, result *UsageBillingApplyResult) {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
slog.Error("panic in notifyAccountQuota", "recover", r)
|
||||
}
|
||||
}()
|
||||
if p.Cost.TotalCost <= 0 || p.Account == nil || !p.Account.IsAPIKeyOrBedrock() || deps.balanceNotifyService == nil {
|
||||
slog.Debug("notifyAccountQuota: skipped",
|
||||
"total_cost", p.Cost.TotalCost,
|
||||
|
||||
Reference in New Issue
Block a user