Multithreaded parallel downloads with auto-scroll and queue UI controls - #1885
Multithreaded parallel downloads with auto-scroll and queue UI controls#1885SirBiggin wants to merge 5 commits into
Conversation
# Conflicts: # Source/LibationUiBase/ProcessQueue/ProcessQueueViewModel.cs
…l downloads Snapshot GetVisible() on the UI thread before handing off to Task.Run, preventing InvalidOperationException when parallel downloads modify the collection concurrently. Also fix installer script to use 64-bit dotnet. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
rmcrackan
left a comment
There was a problem hiding this comment.
Sorry it has taken me so long to get back to this.
Thanks for this - the concurrent queue loop and multi-active TrackedQueue are a solid foundation. A few gaps before this is safe to merge:
- Avalonia parity - Parallelism is on by default in shared UI code, but Avalonia has no toggle and Cancel All still only cancels
Current(seeProcessQueueControl.axaml.cs). - Abort / disk-full - Please also cancel in-flight active downloads, not just clear the pending queue.
- Safer defaults - Defaulting to
ProcessorCountis aggressive given Audible license throttling; prefer opt-in or a small default, plus a way to set the limit. - Installer script - Please drop the hardcoded
dotnet.exepath; it looks unrelated to this feature.
Also worth rebasing on current master when you get a chance.
| SpeedLimit = Configuration.Instance.DownloadSpeedLimit / 1024m / 1024; | ||
| MaxConcurrentDownloads = Configuration.Instance.MaxConcurrentDownloads; | ||
| AutoScrollQueue = Configuration.Instance.AutoScrollQueue; | ||
| MultiThreadEnabled = true; |
There was a problem hiding this comment.
Since this lives in shared UI code, Avalonia gets parallel downloads with no control to turn them off. Could we default to off (or persist the setting) and add matching Avalonia UI?
|
|
||
| if (result == ProcessBookResult.FailedAbort) | ||
| { | ||
| abortCts.Cancel(); |
There was a problem hiding this comment.
ClearQueue() stops new work, but other active downloads keep running. Could we cancel all Active items here (same as Cancel All)? Same for the disk-full path just below.
| { | ||
| var value = GetNonString(defaultValue: 0); | ||
| // Treat 0 or 1 as "use default" — 1 may have been written by an earlier bug. | ||
| return value <= 1 ? Environment.ProcessorCount : value; |
There was a problem hiding this comment.
Defaulting to ProcessorCount may trigger Audible license denials on larger machines. A small default (e.g. 2-3) and a numeric control would be safer than an on/off checkbox alone.
| dotnet publish 'LoadByOS/WindowsConfigApp/WindowsConfigApp.csproj' @publishArgs | ||
| dotnet publish 'LibationCli/LibationCli.csproj' @publishArgs | ||
| dotnet publish "Hangover$Ui/Hangover$Ui.csproj" @publishArgs | ||
| & "C:\Program Files\dotnet\dotnet.exe" publish "Libation$Ui/Libation$Ui.csproj" @publishArgs |
There was a problem hiding this comment.
Mind leaving this out of the PR? Hardcoding C:\Program Files\dotnet\dotnet.exe is machine-specific and unrelated to parallel downloads.
|
Man I saw your reddit post you made right after I submitted this and pretty much gave up on this. I think I've already forgotten what I
Eric Greene
|
|
@SirBiggin — I'd like to pick this up and finish it, if you're alright with that. I've been working on Libation's Avalonia UI on a fork, which means the Avalonia parity item in rmcrackan's review is more or less what I've been doing anyway. The hard part here is already done. The concurrent queue loop and the multi-active Two ways to land it, and I'm fine with either:
I'd prefer the first — it's your work and it should read that way. But if you've moved on, say so and I'll take the second route. Either way there's no obligation to review anything. |
|
That's actually very kind of you, I'm happy to go route 1. just Gatta find some time this week to sink my teeth into it. This is my first PR so I'm still a little new at this |
|
Same here. At least as a collaborative on github. But been writing code for
about 25 years now.
Let me work a little bit and we can hopefully complete out the work and get
the PR done.
…-D
On Wed, Aug 12, 2026 at 6:58 PM SirBiggin ***@***.***> wrote:
*SirBiggin* left a comment (rmcrackan/Libation#1885)
<#1885 (comment)>
That's actually very kind of you, I'm happy to go route 1. just Gatta find
some time this week to sink my teeth into it. This is my first PR so I'm
still a little new at this
—
Reply to this email directly, view it on GitHub
<#1885?email_source=notifications&email_token=AIW3WWBCOKQ45BSYQWE6H7L5JUOF5A5CNFSNUABFM5UWIORPF5TWS5BNNB2WEL2JONZXKZKDN5WW2ZLOOQXTKMRXGUYDENZRHEZ2M4TFMFZW63VHMNXW23LFNZ2KKZLWMVXHJLDGN5XXIZLSL5RWY2LDNM#issuecomment-5275027193>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AIW3WWGRCIXEDNNUYAKSMLD5JUOF5AVCNFSNUABFKJSXA33TNF2G64TZHMZDCMRYHEZTMMZSHNEXG43VMU5TINZRGA3TIMRUGY42C5QC>
.
Triage notifications, keep track of coding agent tasks and review pull
requests on the go with GitHub Mobile for iOS
<https://github.com/notifications/mobile/ios/AIW3WWC2KC4IT6ALEPW6PJ35JUOF5A5CNFSNUABFM5UWIORPF5TWS5BNNB2WEL2JONZXKZKDN5WW2ZLOOQXTKMRXGUYDENZRHEZ2M4TFMFZW63VHMNXW23LFNZ2KKZLWMVXHJKTGN5XXIZLSL5UW64Y>
and Android
<https://github.com/notifications/mobile/android/AIW3WWBN64FBXKHNRHRLFMD5JUOF5A5CNFSNUABFM5UWIORPF5TWS5BNNB2WEL2JONZXKZKDN5WW2ZLOOQXTKMRXGUYDENZRHEZ2M4TFMFZW63VHMNXW23LFNZ2KKZLWMVXHJLTGN5XXIZLSL5QW4ZDSN5UWI>.
Download it today!
You are receiving this because you commented.Message ID:
***@***.***>
--
Stet domus haec donec fluctus formica marinos ebibat, et totum testudo
permabulet orbem
'May this house stand until an ant drains the flowing sea, and a tortoise
walks around the whole world'
|
|
Path 1 it is! Awesome. I rebased your two commits onto current master, then tested what happens if you merge that into your branch the normal way. It merges cleanly with no conflicts — but it quietly brings back the hardcoded The way around it is for your branch to become the rebased version rather than merge with it. If you add me as a collaborator on I'd rather hand you something finished than something half-done, so I'll work through rmcrackan's other three points first: the safer concurrency default with a numeric control, cancelling in-flight downloads on abort and disk-full, and the Avalonia UI. I'll comment here when it's ready so you can look it over before anything touches your fork. No rush on your end. Let me know. Cheers, -D |
|
@SirBiggin @rmcrackan — I've finished the changes from the review, and I'd like to know how you'd both prefer this lands. The concurrency work here is the substance of it and it holds up. I've kept both of @SirBiggin's commits unsquashed and still authored by him, rebased onto current master. All four review points are addressed:
Also rebased on current master as asked, plus three fixes found while testing: the thread-safety crash in On how to land it. My preference is still that this stays @SirBiggin's PR, since it's his work — if you add me as a collaborator on If you'd rather not, or you've moved on, that's completely fine — say so, or say nothing, and I'll open a separate PR that links back here with you credited as the original author. Either way there's no obligation to review anything. @rmcrackan — happy to go whichever way is less work for you. |
|
Reviewing now. Sorry for the additional merge conflicts I caused today. |
|
hey guys, finally got some time to work on this, im pulling everything now, give me a couple of hours to catch up. Panning on working on resolving the conflicts and pull in @dmatlock171's PR |
|
Plz don't start yet. I'm wrapping up my write up which could substantially affect your work. |
|
@SirBiggin @dmatlock171 - thanks to you both. Let me answer the "whichever is less work for you" question first, because I think the plan you have both agreed to is the riskier one, and for a reason that isn't obvious. Please open a new PR against What Path 1 costs is real. A force-push here replaces every commit on the branch, so #1885 would become a substantially different change wearing the old number, my July review would be attached to code that no longer exists, and there'd be no diff anywhere showing what changed. I'd also be seeing the new content for the first time only after it had already replaced the old. That's a bad review surface for a change to the download loop. So: new PR, both authors' commits preserved, rebased on current Now the part that matters more than the process question. The rebase is already stale, and the conflict is a design one.
This isn't a merge conflict, it's "how does the limit gate behave when N books are in flight", and I think it's the biggest piece of work left. Two defects I can reproduce. I compiled
Three more from reading the diff, all still open at
On the follow-up commits themselves - they're good, and I don't want that lost in the list above. One thing to reconsider in And a small note on point 3 from my original review - thank you for actually reproducing the @SirBiggin - your loop and the multi-active @dmatlock171 - I'd rather have this in a reviewable PR than in the right place on the org chart, so take the new-PR route and I'll review it properly. |
|
i kinda agree with this, im just a novice fucking around with some code i find cool trying to make it helpful for others. if this is legitimately going to be used i would want @rmcrackan to have another PR as long as he's willing to credit me for the work ive done so far. i do think that he needs to be the one reviewing @dmatlock171 changes going into the repo eventually. with that being said, do i need to rebase my PR and make sure it has the most recent master? |
|
acknowledged. BTW, not really worried about credit but of course it is
appreciated. I just want to contribute and playing around with a lot of
things in my Tipple fork.
But let me digest what you wrote up in more detail. There is a lot of
unpack there.
…-D
On Sun, Aug 16, 2026 at 1:08 PM rmcrackan ***@***.***> wrote:
*rmcrackan* left a comment (rmcrackan/Libation#1885)
<#1885 (comment)>
@SirBiggin <https://github.com/SirBiggin> @dmatlock171
<https://github.com/dmatlock171> - thanks to you both.
Let me answer the "whichever is less work for you" question first, because
I think the plan you have both agreed to is the riskier one, and for a
reason that isn't obvious.
*Please open a new PR against master rather than force-pushing into
SirBiggin's fork.* I'm happy to give you both credit. In fact, please do
add both github users into Source/LibationUiBase/LibationContributor.cs
What Path 1 costs is real. A force-push here replaces every commit on the
branch, so #1885 <#1885> would
become a substantially different change wearing the old number, my July
review would be attached to code that no longer exists, and there'd be no
diff anywhere showing what changed. I'd also be seeing the new content for
the first time only after it had already replaced the old. That's a bad
review surface for a change to the download loop.
So: new PR, both authors' commits preserved, rebased on current master.
Your parallel-downloads branch already looks like exactly the right scope
- if you push that and open it as-is, there is nothing to strip out. Two
things I would check first: whether the Avalonia queue panel still lays out
correctly without 6a135e0, since that reflow stays behind on tipple, and
whether you would rather c69fe2e went in here or as its own small fix.
SirBiggin, if you're happy with that, nothing is needed from you at all -
no collaborator access, nothing to resolve.
------------------------------
Now the part that matters more than the process question.
*The rebase is already stale, and the conflict is a design one.*
parallel-downloads is rooted on 7914256, which was master on Aug 9. *We're
over 100 commits past that now.* In particular 818510d (Aug 14) added
the opt-in daily download limit, and it lives inside the exact while
(Queue.MoveNext()) loop this PR replaces. It's sequential by construction
and it collides in concrete ways:
- RequeueLast(book) defers a book with Queue.ClearCurrent() +
re-enqueue. Under the new TrackedQueue, ClearCurrent() drops
_active.FirstOrDefault() - so deferring the second of three active
books silently evicts the first one instead.
- AnyOtherQueuedBookAllowed does Queue.Any(...), which is an unlocked
enumeration (more on that below).
- CancelAllAsync still only cancels Queue.Current, and it sets the
cancelAllRequested flag the daily-limit wait watches - so ba3bf91's
rewrite of it will need to keep that.
This isn't a merge conflict, it's "how does the limit gate behave when N
books are in flight", and I think it's the biggest piece of work left.
*Two defects I can reproduce.* I compiled TrackedQueue[T].cs into a
standalone harness - it has no dependencies beyond System, which is also
why it's easy to test. Note that the file is byte-identical between this
PR's head and 6d74d28, so both of these are still live on the follow-up
branch. Happy to share the harness.
1.
*Out-of-order completion renumbers rows and never says so.*
MarkCompleted moves a book from _active to _completed and the display
index comes off Completed.Count, so when the second of two active
books finishes first, the two swap rows. Only CompletedCountChanged
fires, never CollectionChanged, so a bound list keeps painting the old
order. Four queued, two active, B finishes first: [0]=A, [1]=B becomes [0]=B,
[1]=A with zero notifications. Out-of-order completion is the normal
case here, so expect rows showing the wrong book's progress.
2.
*Enumerating the queue during concurrent mutation throws.* GetAllItems
builds a lazy Concat inside the lock and returns it, so the
enumeration happens unlocked - any foreach or LINQ over the queue
while a book task mutates it throws InvalidOperationException:
Collection was modified. This one is mine, it predates the PR, and on
master it's unreachable because everything mutates on the UI thread.
This change makes it reachable. It's also the same crash the PR fixes in
setLiberatedVisibleMenuItem, treated at the symptom rather than the
source.
*Three more from reading the diff, all still open at 6d74d28:*
- *Faulted book tasks vanish.* activeTasks.RemoveWhere(t =>
t.IsCompleted) drops faulted tasks unobserved, before the closing
WhenAll could rethrow. ProcessOneAsync can throw out of its finally
via GetFailureActionAsync; today that lands in the QueueLoop catch and
gets logged. It should still get logged.
- *The bad-book dialog doesn't survive concurrency.* The license and
Widevine dialogs are guarded to fire once per run, but
ShowRetryDialogAsync is per-book and its "apply to all remaining
books" answer lands in a shared BadBookSessionContext. Three books
failing at once means three stacked modals racing to set the same override.
- *Tests.* Source/_Tests/LibationUiBase.Tests already exists and
TrackedQueue<T> is a pure data structure. Multi-active ordering and
notifications should be pinned down there.
*On the follow-up commits themselves - they're good, and I don't want that
lost in the list above.* 6d74d28 is the one I'd single out: books queued
just after the loop starts used to sit idle until an in-flight download
happened to finish, and the fix captures the signal before inspecting the
queue and swaps in a fresh TaskCompletionSource via Interlocked.Exchange,
so a wakeup landing between the dequeue and the wait isn't lost. That's the
right pattern and it's easy to get wrong. ba3bf91 also fixes an Avalonia
bug that predates this PR entirely, and c69fe2e catches the panel
overlap the new checkbox introduced. All four of my original points are
genuinely addressed, and the commit messages explain intent instead of
restating the diff - much appreciated.
One thing to reconsider in 47a3137: MaxAllowedConcurrentDownloads
becomes Math.Clamp(Environment.ProcessorCount, 1, 10) and both the getter
and the setter clamp to it. A user who picks 8, then opens the same config
on a smaller machine or in a container, reads back 2 - and has 2 written
over their stored 8. Machine capability belongs in the spinner's bounds,
not in the persisted value. Also worth confirming at runtime that the
Avalonia Minimum="{Binding MinConcurrentDownloads}" bindings resolve,
since those are static properties on the view model.
And a small note on point 3 from my original review - thank you for
actually reproducing the Content License denied errors above concurrency
3 rather than taking my word for it. A conservative default plus a hard cap
is exactly right.
@SirBiggin <https://github.com/SirBiggin> - your loop and the
multi-active TrackedQueue are still the substance of this, and that
hasn't changed.
@dmatlock171 <https://github.com/dmatlock171> - I'd rather have this in a
reviewable PR than in the right place on the org chart, so take the new-PR
route and I'll review it properly.
—
Reply to this email directly, view it on GitHub
<#1885?email_source=notifications&email_token=AIW3WWA77DYVZDQVBGMBRDD5KIIFPA5CNFSNUABFM5UWIORPF5TWS5BNNB2WEL2JONZXKZKDN5WW2ZLOOQXTKMZQHE2DGMZUHA42M4TFMFZW63VHNVSW45DJN5XKKZLWMVXHJLDGN5XXIZLSL5RWY2LDNM#issuecomment-5309433489>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AIW3WWGK34AEZ4XKP4JPZSL5KIIFPAVCNFSNUABFKJSXA33TNF2G64TZHMZDCMRYHEZTMMZSHNEXG43VMU5TINZRGA3TIMRUGY42C5QC>
.
Triage notifications, keep track of coding agent tasks and review pull
requests on the go with GitHub Mobile for iOS
<https://github.com/notifications/mobile/ios/AIW3WWGPT7JZ2FIBXLWXQ7D5KIIFPA5CNFSNUABFM5UWIORPF5TWS5BNNB2WEL2JONZXKZKDN5WW2ZLOOQXTKMZQHE2DGMZUHA42M4TFMFZW63VHNVSW45DJN5XKKZLWMVXHJKTGN5XXIZLSL5UW64Y>
and Android
<https://github.com/notifications/mobile/android/AIW3WWHACOF4ZJIUARDGB3L5KIIFPA5CNFSNUABFM5UWIORPF5TWS5BNNB2WEL2JONZXKZKDN5WW2ZLOOQXTKMZQHE2DGMZUHA42M4TFMFZW63VHNVSW45DJN5XKKZLWMVXHJLTGN5XXIZLSL5QW4ZDSN5UWI>.
Download it today!
You are receiving this because you were mentioned.Message ID:
***@***.***>
--
Stet domus haec donec fluctus formica marinos ebibat, et totum testudo
permabulet orbem
'May this house stand until an ant drains the flowing sea, and a tortoise
walks around the whole world'
|
|
The avelona panel yes is laying out correctly and was tricky as this is my
first forray into that.
Actually keeping both standard and Chardonay in sync has been a bit of a
challenge.
I am breaking from the parallel download for a spell and working on more
general issues right now to download from other sources like Chrip Books
and Downpour (assuming of course we don't break DRM).
Also, been having fun with creating a ribbon and some more hot keys .
…-D
On Sun, Aug 16, 2026 at 1:40 PM Devin Matlock ***@***.***> wrote:
acknowledged. BTW, not really worried about credit but of course it is
appreciated. I just want to contribute and playing around with a lot of
things in my Tipple fork.
But let me digest what you wrote up in more detail. There is a lot of
unpack there.
-D
On Sun, Aug 16, 2026 at 1:08 PM rmcrackan ***@***.***>
wrote:
> *rmcrackan* left a comment (rmcrackan/Libation#1885)
> <#1885 (comment)>
>
> @SirBiggin <https://github.com/SirBiggin> @dmatlock171
> <https://github.com/dmatlock171> - thanks to you both.
>
> Let me answer the "whichever is less work for you" question first,
> because I think the plan you have both agreed to is the riskier one, and
> for a reason that isn't obvious.
>
> *Please open a new PR against master rather than force-pushing into
> SirBiggin's fork.* I'm happy to give you both credit. In fact, please do
> add both github users into Source/LibationUiBase/LibationContributor.cs
>
> What Path 1 costs is real. A force-push here replaces every commit on the
> branch, so #1885 <#1885> would
> become a substantially different change wearing the old number, my July
> review would be attached to code that no longer exists, and there'd be no
> diff anywhere showing what changed. I'd also be seeing the new content for
> the first time only after it had already replaced the old. That's a bad
> review surface for a change to the download loop.
>
> So: new PR, both authors' commits preserved, rebased on current master.
> Your parallel-downloads branch already looks like exactly the right
> scope - if you push that and open it as-is, there is nothing to strip out.
> Two things I would check first: whether the Avalonia queue panel still lays
> out correctly without 6a135e0, since that reflow stays behind on tipple,
> and whether you would rather c69fe2e went in here or as its own small
> fix. SirBiggin, if you're happy with that, nothing is needed from you at
> all - no collaborator access, nothing to resolve.
> ------------------------------
>
> Now the part that matters more than the process question.
>
> *The rebase is already stale, and the conflict is a design one.*
> parallel-downloads is rooted on 7914256, which was master on Aug 9. *We're
> over 100 commits past that now.* In particular 818510d (Aug 14) added
> the opt-in daily download limit, and it lives inside the exact while
> (Queue.MoveNext()) loop this PR replaces. It's sequential by
> construction and it collides in concrete ways:
>
> - RequeueLast(book) defers a book with Queue.ClearCurrent() +
> re-enqueue. Under the new TrackedQueue, ClearCurrent() drops
> _active.FirstOrDefault() - so deferring the second of three active
> books silently evicts the first one instead.
> - AnyOtherQueuedBookAllowed does Queue.Any(...), which is an unlocked
> enumeration (more on that below).
> - CancelAllAsync still only cancels Queue.Current, and it sets the
> cancelAllRequested flag the daily-limit wait watches - so ba3bf91's
> rewrite of it will need to keep that.
>
> This isn't a merge conflict, it's "how does the limit gate behave when N
> books are in flight", and I think it's the biggest piece of work left.
>
> *Two defects I can reproduce.* I compiled TrackedQueue[T].cs into a
> standalone harness - it has no dependencies beyond System, which is also
> why it's easy to test. Note that the file is byte-identical between this
> PR's head and 6d74d28, so both of these are still live on the follow-up
> branch. Happy to share the harness.
>
> 1.
>
> *Out-of-order completion renumbers rows and never says so.*
> MarkCompleted moves a book from _active to _completed and the display
> index comes off Completed.Count, so when the second of two active
> books finishes first, the two swap rows. Only CompletedCountChanged
> fires, never CollectionChanged, so a bound list keeps painting the
> old order. Four queued, two active, B finishes first: [0]=A, [1]=B
> becomes [0]=B, [1]=A with zero notifications. Out-of-order completion
> is the normal case here, so expect rows showing the wrong book's progress.
> 2.
>
> *Enumerating the queue during concurrent mutation throws.* GetAllItems
> builds a lazy Concat inside the lock and returns it, so the
> enumeration happens unlocked - any foreach or LINQ over the queue
> while a book task mutates it throws InvalidOperationException:
> Collection was modified. This one is mine, it predates the PR, and on
> master it's unreachable because everything mutates on the UI thread.
> This change makes it reachable. It's also the same crash the PR fixes in
> setLiberatedVisibleMenuItem, treated at the symptom rather than the
> source.
>
> *Three more from reading the diff, all still open at 6d74d28:*
>
> - *Faulted book tasks vanish.* activeTasks.RemoveWhere(t =>
> t.IsCompleted) drops faulted tasks unobserved, before the closing
> WhenAll could rethrow. ProcessOneAsync can throw out of its finally
> via GetFailureActionAsync; today that lands in the QueueLoop catch
> and gets logged. It should still get logged.
> - *The bad-book dialog doesn't survive concurrency.* The license and
> Widevine dialogs are guarded to fire once per run, but
> ShowRetryDialogAsync is per-book and its "apply to all remaining
> books" answer lands in a shared BadBookSessionContext. Three books
> failing at once means three stacked modals racing to set the same override.
> - *Tests.* Source/_Tests/LibationUiBase.Tests already exists and
> TrackedQueue<T> is a pure data structure. Multi-active ordering and
> notifications should be pinned down there.
>
> *On the follow-up commits themselves - they're good, and I don't want
> that lost in the list above.* 6d74d28 is the one I'd single out: books
> queued just after the loop starts used to sit idle until an in-flight
> download happened to finish, and the fix captures the signal before
> inspecting the queue and swaps in a fresh TaskCompletionSource via
> Interlocked.Exchange, so a wakeup landing between the dequeue and the
> wait isn't lost. That's the right pattern and it's easy to get wrong.
> ba3bf91 also fixes an Avalonia bug that predates this PR entirely, and
> c69fe2e catches the panel overlap the new checkbox introduced. All four
> of my original points are genuinely addressed, and the commit messages
> explain intent instead of restating the diff - much appreciated.
>
> One thing to reconsider in 47a3137: MaxAllowedConcurrentDownloads
> becomes Math.Clamp(Environment.ProcessorCount, 1, 10) and both the
> getter and the setter clamp to it. A user who picks 8, then opens the same
> config on a smaller machine or in a container, reads back 2 - and has 2
> written over their stored 8. Machine capability belongs in the spinner's
> bounds, not in the persisted value. Also worth confirming at runtime that
> the Avalonia Minimum="{Binding MinConcurrentDownloads}" bindings
> resolve, since those are static properties on the view model.
>
> And a small note on point 3 from my original review - thank you for
> actually reproducing the Content License denied errors above concurrency
> 3 rather than taking my word for it. A conservative default plus a hard cap
> is exactly right.
>
> @SirBiggin <https://github.com/SirBiggin> - your loop and the
> multi-active TrackedQueue are still the substance of this, and that
> hasn't changed.
>
> @dmatlock171 <https://github.com/dmatlock171> - I'd rather have this in
> a reviewable PR than in the right place on the org chart, so take the
> new-PR route and I'll review it properly.
>
> —
> Reply to this email directly, view it on GitHub
> <#1885?email_source=notifications&email_token=AIW3WWA77DYVZDQVBGMBRDD5KIIFPA5CNFSNUABFM5UWIORPF5TWS5BNNB2WEL2JONZXKZKDN5WW2ZLOOQXTKMZQHE2DGMZUHA42M4TFMFZW63VHNVSW45DJN5XKKZLWMVXHJLDGN5XXIZLSL5RWY2LDNM#issuecomment-5309433489>,
> or unsubscribe
> <https://github.com/notifications/unsubscribe-auth/AIW3WWGK34AEZ4XKP4JPZSL5KIIFPAVCNFSNUABFKJSXA33TNF2G64TZHMZDCMRYHEZTMMZSHNEXG43VMU5TINZRGA3TIMRUGY42C5QC>
> .
> Triage notifications, keep track of coding agent tasks and review pull
> requests on the go with GitHub Mobile for iOS
> <https://github.com/notifications/mobile/ios/AIW3WWGPT7JZ2FIBXLWXQ7D5KIIFPA5CNFSNUABFM5UWIORPF5TWS5BNNB2WEL2JONZXKZKDN5WW2ZLOOQXTKMZQHE2DGMZUHA42M4TFMFZW63VHNVSW45DJN5XKKZLWMVXHJKTGN5XXIZLSL5UW64Y>
> and Android
> <https://github.com/notifications/mobile/android/AIW3WWHACOF4ZJIUARDGB3L5KIIFPA5CNFSNUABFM5UWIORPF5TWS5BNNB2WEL2JONZXKZKDN5WW2ZLOOQXTKMZQHE2DGMZUHA42M4TFMFZW63VHNVSW45DJN5XKKZLWMVXHJLTGN5XXIZLSL5QW4ZDSN5UWI>.
> Download it today!
> You are receiving this because you were mentioned.Message ID:
> ***@***.***>
>
--
Stet domus haec donec fluctus formica marinos ebibat, et totum testudo
permabulet orbem
'May this house stand until an ant drains the flowing sea, and a tortoise
walks around the whole world'
--
Stet domus haec donec fluctus formica marinos ebibat, et totum testudo
permabulet orbem
'May this house stand until an ant drains the flowing sea, and a tortoise
walks around the whole world'
|
|
Oh my yes. SirBiggin you should have the main mast head credit. While I had
this idea seperately you had it first and did a lot of ground work that I
leveraged. So you deserve that credit.
I just want to help and I really like making thread safe acrhicttures.
…-D
On Sun, Aug 16, 2026 at 1:26 PM SirBiggin ***@***.***> wrote:
*SirBiggin* left a comment (rmcrackan/Libation#1885)
<#1885 (comment)>
i kinda agree with this, im just a novice fucking around with some code i
find cool trying to make it helpful for others.
if this is legitimately going to be used i would want @rmcrackan
<https://github.com/rmcrackan> to have another PR as long as he's willing
to credit me for the work ive done so far. i do think that he needs to be
the one reviewing @dmatlock171 <https://github.com/dmatlock171> changes
going into the repo eventually.
with that being said, do i need to rebase my PR and make sure it has the
most recent master?
—
Reply to this email directly, view it on GitHub
<#1885?email_source=notifications&email_token=AIW3WWAWKMKQ3HC77RDTP3D5KIKGZA5CNFSNUABFM5UWIORPF5TWS5BNNB2WEL2JONZXKZKDN5WW2ZLOOQXTKMZQHE2TANBZGMZ2M4TFMFZW63VHNVSW45DJN5XKKZLWMVXHJLDGN5XXIZLSL5RWY2LDNM#issuecomment-5309504933>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AIW3WWBVLE5ZNDZNW3P7CGT5KIKGZAVCNFSNUABFKJSXA33TNF2G64TZHMZDCMRYHEZTMMZSHNEXG43VMU5TINZRGA3TIMRUGY42C5QC>
.
Triage notifications, keep track of coding agent tasks and review pull
requests on the go with GitHub Mobile for iOS
<https://github.com/notifications/mobile/ios/AIW3WWDH3LIIQPGPZZL5DH35KIKGZA5CNFSNUABFM5UWIORPF5TWS5BNNB2WEL2JONZXKZKDN5WW2ZLOOQXTKMZQHE2TANBZGMZ2M4TFMFZW63VHNVSW45DJN5XKKZLWMVXHJKTGN5XXIZLSL5UW64Y>
and Android
<https://github.com/notifications/mobile/android/AIW3WWBX3MRBPGJ3Y6IHRW35KIKGZA5CNFSNUABFM5UWIORPF5TWS5BNNB2WEL2JONZXKZKDN5WW2ZLOOQXTKMZQHE2TANBZGMZ2M4TFMFZW63VHNVSW45DJN5XKKZLWMVXHJLTGN5XXIZLSL5QW4ZDSN5UWI>.
Download it today!
You are receiving this because you were mentioned.Message ID:
***@***.***>
--
Stet domus haec donec fluctus formica marinos ebibat, et totum testudo
permabulet orbem
'May this house stand until an ant drains the flowing sea, and a tortoise
walks around the whole world'
|
|
hey, i was content not getting credit for my work when @rmcrackan made that reddit post about stepping back from dev work from the project literally days after i made the PR. i thought for sure my PR was going to get shot down. i'll take credit if its being given out, but i just wanted to add a cool feature |
|
Well,
same here. I like libation and have been having a lot of find stretchging
my gui muscles. I suck at GUIs. Not my field.
But doing community work is always fun. I always develop things at work in
ways others can leverage them and not reinvent a wheel, etc
So I am just listening to music and playing around this sunday and having
fun.
I will workin the PR a bit later as I am working on Tipple right now.
…-D
On Sun, Aug 16, 2026 at 1:50 PM SirBiggin ***@***.***> wrote:
*SirBiggin* left a comment (rmcrackan/Libation#1885)
<#1885 (comment)>
hey, i was content not getting credit for my work when @rmcrackan
<https://github.com/rmcrackan> made that reddit post about stepping back
from dev work from the project literally days after i made the PR. i
thought for sure my PR was going to get shot down. i'll take credit if its
being given out, but i just wanted to add a cool feature
—
Reply to this email directly, view it on GitHub
<#1885?email_source=notifications&email_token=AIW3WWCY5FVXNL3SDCBTYSL5KINAZA5CNFSNUABFM5UWIORPF5TWS5BNNB2WEL2JONZXKZKDN5WW2ZLOOQXTKMZQHE3DAMZWGAZ2M4TFMFZW63VHNVSW45DJN5XKKZLWMVXHJLDGN5XXIZLSL5RWY2LDNM#issuecomment-5309603603>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AIW3WWCOGUUJAPNYSPO3T5L5KINAZAVCNFSNUABFKJSXA33TNF2G64TZHMZDCMRYHEZTMMZSHNEXG43VMU5TINZRGA3TIMRUGY42C5QC>
.
Triage notifications, keep track of coding agent tasks and review pull
requests on the go with GitHub Mobile for iOS
<https://github.com/notifications/mobile/ios/AIW3WWFQMYSADAGCKENQXRL5KINAZA5CNFSNUABFM5UWIORPF5TWS5BNNB2WEL2JONZXKZKDN5WW2ZLOOQXTKMZQHE3DAMZWGAZ2M4TFMFZW63VHNVSW45DJN5XKKZLWMVXHJKTGN5XXIZLSL5UW64Y>
and Android
<https://github.com/notifications/mobile/android/AIW3WWBT5NBKGZCE46TNJGD5KINAZA5CNFSNUABFM5UWIORPF5TWS5BNNB2WEL2JONZXKZKDN5WW2ZLOOQXTKMZQHE3DAMZWGAZ2M4TFMFZW63VHNVSW45DJN5XKKZLWMVXHJLTGN5XXIZLSL5QW4ZDSN5UWI>.
Download it today!
You are receiving this because you were mentioned.Message ID:
***@***.***>
--
Stet domus haec donec fluctus formica marinos ebibat, et totum testudo
permabulet orbem
'May this house stand until an ant drains the flowing sea, and a tortoise
walks around the whole world'
|
|
@SirBiggin @rmcrackan — opened as #1958, rebased onto current master with both of SirBiggin's commits preserved and still authored by him. All four points from the July review are addressed, plus what came out of the writeup: the daily download limit collision (818510d assumed the sequential loop, so RequeueLast was evicting the wrong active book), both TrackedQueue defects, and the three from reading the diff. TrackedQueue tests are in Source/_Tests/LibationUiBase.Tests. We're both added to LibationContributor.cs. Tested end to end against a real library: parallel downloads, out-of-order completion, Cancel All mid-run, the limit pause and resume, and the Plus-only deferral. @SirBiggin — nothing needed from you, no collaborator access. The loop and the multi-active queue are still the substance of this. Some other minor notes I put in the PR about the queue window, etc. |
|
Thanks y'all. I'll be reviewing the other one when I can get a break at work. I was up all night addressing other Libation issues and questions so I'm a bit burned-out right now. I'm going to close this PR (#1885) and we'll focus on the new one (#1958). You're welcome to continue discussions in either. |
Summary
HashSet<Task>loop allowing dynamic concurrency changes mid-run.ScrollToTopmethod onVirtualFlowControl.Auto-scrollandParallel downloads— alongside the existing Cancel All and DL Limit controls.InvalidOperationExceptioncrash insetLiberatedVisibleMenuItemcaused by enumeratingGetVisible()on a background thread while parallel downloads modified the collection. Collection is now snapshotted on the UI thread before being passed toTask.Run.Currentitem with an_activelist to track multiple simultaneous downloads, while keeping the backward-compatibleCurrentproperty.AutoScrollQueue(bool) andMaxConcurrentDownloads(int) persistent settings.Test plan
Parallel downloadscheckbox off mid-run and confirm it serializesAuto-scrolland confirm queue scrolls/stops scrolling to active itemsInvalidOperationExceptioncrash during parallel downloadsCancel Allcancels all active downloads