Thread Safe Connection Pool in Ruby

Jay Shah
Jay Shah
May 26, 2020 · 4 min read

To demonstrate a thread safe implementation of a connection pool, we will use a class instance variable, a Mutex, and the connection_pool gem.

Class Instance Variables

Class instance variables work like regular class variables except for two main differences.

  1. Class instance variables are available only to class methods and not to instance methods.
  2. Class instance variables are not shared with sub-classes. They belong exclusively to the class itself.

We will use class instance variables (mainly for reason 1) to share a connection pool which all threads will be able to access. Here is a quick example of what class instance variables can do for us.

When was accessed by class methods, its value was only accessed and updated at the class level. When accessed as an instance method, it was accessed and updated in a separate memory space at the instance level.

If you want to learn more about class instance variables, take a look at this article and this post.

Now that we have a way to access the same connection pool across threads, we need to actually create the pool so threads can use it.

Connection Pool

The connection_pool gem will allow us to create a pool of connections which we can use to grab a connection and return it after we’re done using it. This allows us to specify a static number of connections and forces our threads to share those connections.

With this, we can now access the shared connection pool across threads by calling . To use one of the connections in the pool, we use which will yield a connection.

However, there is a slight problem. Multiple threads could access at the same time, see that hasn't been initialized, and then each one of those threads would create another connection pool. This would cause us to create extra pools (and extra connections) which we don’t want. We only want the first thread that accesses to initialize and not the consequent ones.

To demonstrate the race condition, we will slightly modify the class above to show how that’s possible.

Output

As you can see, ends up being accessed multiple times, even when we have to check for initialization. There is a race condition between threads that ends up updating multiple times. We only want to be updated once no matter how many times is called.

We can use a to solve this.

Mutex

In the ruby documentation, the class has the following description

Mutex implements a simple semaphore that can be used to coordinate access to shared data from multiple concurrent threads.¹

We can use a mutex to avoid creating multiple pools when threads initially access .

We’ve introduced a mutex in to only allow one thread to create the pool at a time. Additionally, if threads are waiting for the mutex to be free while the pool is initially being created, will stop those threads from creating a new pool when they get a chance to access the mutex.

At this point, we should be able to use safely across our threads.

In Action

So we can see this in action, we will again slightly modify the above class so we can run it in many threads and see what the output is.

With a Mutex

Output

Now, is only initialized once by the first thread and returned in consequent calls and threads.

There you have it! How to a create thread safe connection pool using class instance variables, a Mutex, and the connection_pool gem.

References

  1. https://ruby-doc.org/core-2.6/Mutex.html

The Startup

Get smarter at building your thing. Join The Startup’s +799K followers.

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store