-
Notifications
You must be signed in to change notification settings - Fork 64
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Unsupported use case: mapConcurrently-alike with concurrency limit, and ordered job start #83
Comments
I believe async-pool package does something like that. |
And note that |
@dcoutts Is |
@mitchellwrosen if you can add things into the QSem in order then it's fine, but if you start a bunch of asyncs up and each one queues itself onto the QSem then you've lost all ordering. There would have to be synchronisation, to only spawn the next one once the previous one has been enqueued (which is of course a bit tricky to arrange). |
@dcoutts Ah, that's what I meant by "small race conditions aside". Since |
You could do this by having a separate controller thread, like this:
And in the controller thread you can release tickets in the order you want, waiting for threads to complete by listening on But a much nicer way would be to build precisely the abstraction you need, which is:
Implementation left as an exercise for the reader :) |
I stumbled upon http://hackage.haskell.org/package/unliftio-0.2.13/docs/UnliftIO-Async.html and it suits me well. |
Async is a nice abstraction, however as far as I can see the following use case is not supported in any straightforward obvious way:
If it was just this, we could simply use async + a semaphore. There's one more requirement:
This last one is what means we cannot fit it into the async abstraction. But this is not an uncommon requirement. Consider a tool like cabal downloading package tarballs. We want to download e.g. 2-3 concurrently, but we want to start downloading the ones we'll need first, before the ones we'll need later, since we will also start building packages concurrently with the downloading.
The abstraction that
cabal-install
currently uses is this thing called JobControl. The above use case is handled by putting all the jobs into the job control queue in order, and the N worker threads simply grab the next one available.Of course I'm not proposing to merge the rather-different
JobControl
abstraction intoasync
, rather the challenge is if anyone can think of some way the existing async abstraction that would support this use case, and if any extensions would be needed, or if any helper utils would make this easier.The basic problem is that an
async
starts a thread immediately, so having created a bunch of them there is no way to control the relative ordering. All of them can contend on a quantity semaphore, but there is no ordering guarantee. One plausible route might be to sequentialise the startup and add a startup synchronisation between the parent and the child async, so e.g. one could have the child thread enqueue onto a quantity semaphore before returning the async in the parent. This approach would not require any extensions, but could benefit from some helper utilities.The text was updated successfully, but these errors were encountered: