mirror of
https://github.com/rmcrackan/Libation.git
synced 2026-09-12 21:57:19 -04:00
The opt-in daily download limit landed after this branch was written and lives inside the sequential while (Queue.MoveNext()) loop this change replaces. It is sequential by construction, so rebasing alone leaves it subtly wrong rather than merely conflicted. The gate now runs in the dispatch loop, between taking a book off the queue and starting its task. That keeps the existing semantics - checked as a book is about to start so the queue keeps its contents and the limit can be changed mid-run - while books already in flight carry on. Putting it inside the book task instead would have every blocked book polling the history at once. Three concrete defects that fell out of the collision: RequeueLast deferred a book with Queue.ClearCurrent(), which drops Active[0]. With one book at a time that is the book being deferred; with three in flight it is somebody else's download, so deferring the second active book silently evicted the first. It now removes the book it was given. A book cancelled at the gate was left on the active list. The sequential loop retired it on the next MoveNext(); there is no next MoveNext(), so it is marked completed explicitly. CancelAllAsync existed twice after the rebase - the sequential version that sets cancelAllRequested and cancels Queue.Current, and this branch's version that cancels every active book. Unified into one that does both. The flag matters: a queue paused on the limit is sitting in WaitForDailyLimitAsync and that flag is how it learns to stop. AnyOtherQueuedBookAllowed enumerates the queue with Queue.Any(...) while book tasks mutate it; that is safe now that GetAllItems snapshots under the lock, and it also now takes a copy of the active list to cancel.