Skip to content

Add Semaphore #4

@ysbaddaden

Description

@ysbaddaden

Right now we can limit the concurrency of something to N by starting N fibers with a channel. If it needs to return a value, we must pass a Sync::Future(T). For example:

# start workers:
N.times do
  ::spawn do
    while message = channel.receive?
      work, future = message
      future.set(foobar(work))
    rescue exception
      future.fail(exception)
    end
  end
end

# somewhere else (called from different places):
future = Future(Foo).new
channel.send({new_work, future})
value = future.get

This is all nice, but rather complex, it needs to pre-initialize a bunch of resources and lots of communication. This is worth it when we want to put the computation in a specific execution context, or there are lots of computations to repeatedly calculate.

Yet, simpler usages to merely limit the concurrency of bcrypt hashes, might benefit from a simple counting semaphore. It would avoid all this boilerplate (no need for dedicated worker fibers, channels or futures), just by allowing up to N concurrent accesses to a critical section (from anywhere in the program) and putting the calling fiber into a wait list. For example:

SEM = Sync::Semaphore.new(N)

work = new_work
value = SEM.synchronize { foobar(work) }

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions