fix(providers/cost_tracker): protect _daily_costs read-modify-write in record_usage with a threading.Lock #3164

Closed
freemo wants to merge 1 commits from fix/concurrency-cost-tracker-record-usage-race-condition into master

1 Commits

Author SHA1 Message Date
freemo 79135cf143 fix(providers/cost_tracker): protect _daily_costs read-modify-write in record_usage with a threading.Lock
CI / lint (pull_request) Successful in 29s
CI / typecheck (pull_request) Successful in 53s
CI / security (pull_request) Successful in 1m5s
CI / quality (pull_request) Successful in 33s
CI / build (pull_request) Successful in 26s
CI / helm (pull_request) Successful in 23s
CI / unit_tests (pull_request) Successful in 6m41s
CI / docker (pull_request) Successful in 1m24s
CI / e2e_tests (pull_request) Successful in 18m32s
CI / coverage (pull_request) Successful in 11m3s
CI / integration_tests (pull_request) Successful in 22m56s
CI / status-check (pull_request) Successful in 1s
CI / benchmark-publish (pull_request) Has been skipped
CI / benchmark-regression (pull_request) Successful in 57m7s
Introduce _daily_costs_lock: threading.Lock in CostTracker.__init__ and
wrap the read-modify-write sequence in record_usage inside
'with self._daily_costs_lock:'. Extend the same lock to guard reads in
check_daily_budget and get_daily_spend to ensure full visibility of
writes across threads and avoid relying on CPython GIL implementation
details.

Add a @concurrency Behave scenario that spawns 20 threads concurrently
calling record_usage and asserts the final daily spend exactly equals
the arithmetic sum of all individual costs, directly proving the race
condition is eliminated.

ISSUES CLOSED: #2895
2026-04-05 07:05:19 +00:00