TimedSemaphore implementation in Ruby

Ruby is a programming language with a focus on simplicity and productivity. However, it lacks in performance comparing to other programming languages, especially in applications which make a lot of non-blocking operations like database and network calls. Concurrency can help with this, even though Ruby doesn’t support true multithreading (talking about MRI). The problem is that Ruby doesn’t provide many synchronization primitives, like some other languages designed with concurrency in mind (e.g Go).

Ruby’s standard library provides following synchronization mechanisms: Mutex, Monitor, and ConditionVariable. They can lead to complex code if used a lot. Yet, they are enough to build higher level mechanisms on top of them, like semaphores, countdown latches, cyclic barriers, etc. I suggest taking a look at the concurrent-ruby gem. This library implements modern concurrency tools, inspired by other languages like Erlang, Java, and others.

A TimedSemaphore is a specialized implementation of a Semaphore that gives a number of permits in a given time frame. The idea is taken from the Apache Commons Lang package. A use case for it is to limit the load on a resource. Consider an application that issues network calls to an external API to collect some data. Typical API’s have limitations based on calls per second. A counting semaphore couldn’t be used, since for example, 10 calls per second aren’t the same as 10 calls at a time. Here a TimedSemaphore could be used to guarantee that only a given number of API calls are issued per second.

Here is the code for the TimedSemaphore:


A thread can request a permit using the acquire method. However, there is an additional timing dimension: a thread cannot release his permit, but all permits are automatically released at the end of the given time. If a thread calls acquire and the available permits are already used for this time frame, the thread waits. After the time frame ends all permits requested so far are released and waiting threads are waked up again, so that they can try to acquire a new permit. This basically means that in the specified number of seconds only the specified number of operations is possible.

Here is a basic example of using a TimedSemaphore:

This example will produce something like this:


Follow me

Sadzid Suljic

Software Developer at Cron
Full-stack developer with experience in developing on various application stacks. I strive to learn something new and apply the best practices on a daily basis.
Follow me
Sadzid SuljicTimedSemaphore implementation in Ruby