lightninglabs / lightninglabs/aperture
meterd: bound stranded reservations with a TTL
Nobody has claimed this yet.
- Dominant language
- Go
- Stars
- 268
- Forks
- 78
- Avg merge
- 22h 25m
- Merged PRs (30d)
- 1
Description
Follow-up from the review of #247, which fixed the reservation leaks that were reachable through normal request flow (the rate limiter running after the reservation, a backend that never answered skipping ModifyResponse, and protocol upgrades returning early). What remains is the ops-event tail, and it wants a backstop rather than another targeted fix.
What is still open
AuthorizeRequest reserves an estimate and only a usage report gives it back. After #247 the report is sent on every path the proxy controls, but not when the process loses the ability to send one at all:
- the pricer is down through all four
reportUsageWithRetryattempts - aperture crashes or is restarted between authorize and report
- a handler panics somewhere between the two
Bundle.Reserved is deliberately not persisted (store.go, the json:"-" tag), so a meterd restart clears it. That is the only thing clearing it today. Until then available = RemainingTokens - Reserved stays depressed, and enough stranded reservations make a bundle with real balance read as exhausted, at which point the buyer is told to purchase another one.
What to do
Give a reservation a TTL and sweep expired ones, on the order of ten times reportTimeout so a slow-but-succeeding report is never swept out from under itself. The existing ExpireStale janitor is the natural place to hang it.
Two details worth getting right:
- A swept reservation must not double-release if the late report eventually lands. Recording reservations individually rather than as a single counter per bundle would make that natural, at the cost of more state.
- The sweep needs the same eviction age floor that #247 added for un-paid bundles, so a young reservation on an in-flight long request is never reaped.
Acceptance
- A reservation whose report never arrives is released within a bounded window.
- A late report after a sweep does not release twice.
- An in-flight request longer than the report timeout is not swept.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with Bundle.Reserved and the json:"-" handling in store.go, then trace AuthorizeRequest, reportUsageWithRetry, and the existing ExpireStale janitor. Determine how reservations can be tracked individually and how the #247 eviction age floor applies. Done means abandoned reservations are released within a bounded window, late reports do not release twice, and long in-flight requests are not swept.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- go
- Domain
- backend
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100