DirtyHairy/async-mutex

Why can't I release a semaphore?

Closed this issue · 2 comments

Would you consider un-deprecating the release method? 0ccb014

Preventing release means you always have to acquire/unlock in the same scope, which works well when you want to control how many jobs can be done concurrently.

Semaphores also have another use, where you can use it to manage a shared resource that have separate writers and readers.
Here you would not initialize the semaphore to a positive value; starting at 0 is fine.
A writer pushes an item into an array and signals (or releases as this library calls it) the semaphore.
A reader waits/acquires on the semaphore, and then is guaranteed to have an item to work on.
This is the more classical use of a semaphore, where semaphores do not need to be signalled/waited on in the same thread.

So, it would be nice for this library to support that. This would also solve #23.

Every so often I go to find a semaphore library and always have to skip this one (which seems to be the most popular), and reach for semaphore-async-await.

The reason why I added the now-deprecated API was #15 . However, that is precisely the use case for which I provide runExclusive, and as people were misusing it and running into subsequent issues. I don't want to add it back for this reason: this is the use case Mutex and Semaphore aim at (locking shared resources), and the generalised API invites abuse and code that is broken in subtle ways.

That said, I am not against adding a semaphore the counts from zero upwards, but I want to keep this library as simple as possible and would prefer to see a convincing usecase in JS before adding something new. Imo your particular example (as I understand it) would be better addressed with an array and an event that is fired whenever an item is pushed. However, on a less abstract level I cannot imagine an actual problem where this approach is necessary --- JS is not concurrent, so there is no notion of keeping a pool of "worker threads", and if you want to limit the number of cooperatively "concurrent" async tasks Semaphore will do the job.

About writer/reader threads, maybe you're right and this isn't relevant to JS.

I had a search through all my uses of semaphore, and I did find one use which isn't possible without a release method.

I had a semaphore with 10 max concurrency, and every so often I wanted to take all 10 of those, and then afterwards release all 10. In this case I wanted to have 10 concurrenct requests using an OAuth token, but separately refresh the token and make sure no requests were in-flight.