4

For the past few weeks I've been learning Ruby and I must say that it hasn't been easy to get a grasp of some things.

That leads me to asking this question, I'm trying to setup a project which uses Rubinius as ruby engine, puma as webserver (since Puma states that it's best made to work with Rubinius because of their concurrency implementation), PostgreSQL as database and sequel as toolkit for the database.

What I'm struggling with is making the database connection. As it is, I'm doing it in the config.ru:

require 'rubygems'
require 'bundler/setup'
require 'uri'
require 'yaml'
require 'erb'


Bundler.require :default, ENV['RACK_ENV']

DATABASE.disconnect if defined?(DATABASE)

if ENV['DATABASE_URL']
  db_config = URI.parse ENV['DATABASE_URL']
else
  #noinspection RubyResolve
  db_config = YAML.load(ERB.new(File.read('config/database.yml')).result)[ENV['RACK_ENV']]
end

DATABASE = Sequel.connect db_config

require File.expand_path('../application/api', __FILE__)

run APP::API

But I've been told that it's not the best place to do it if I want concurrency and not a shared connection. If I were using Unicorn I would do it in the before_fork, but Puma does not have such a function.

Though it does provide a on_worker_boot it is not useful with Sequel, because if I preload the app, Sequel requires a database connection before it can create my models (class SomeClass < Sequel::Model).

I am a bit confused now and I'm not sure where to go from this point. I was trying to find some guides or some good practices on this matter, but the only things I found were using ActiveRecord.

Does someone know how to actually do this properly, connecting to the database?

3
  • 1
    It would be totally wrong to establish a PostgreSQL database connection before forking anyway. You can't share one socket and connection across multiple workers. You'd need to connect after forking workers. Commented Feb 28, 2014 at 22:57
  • @craigringer ~ so what you're saying is that it's fine the way I'm already doing it. Commented Mar 1, 2014 at 14:53
  • I don't know the tools involved well enough to say for sure. All I'm saying is that you can't safely share one PostgreSQL connection between multiple forked processes, and you should establish a connection after you fork workers from a main process, not before. Commented Mar 2, 2014 at 0:19

1 Answer 1

2

If you haven't set up puma to fork and preload the app (-w and --preload flags), you shouldn't need to do anything. If you have set up puma to fork and preload, then after loading your model classes, call DATABASE.disconnect. You may also want to lobby the puma developers to add a hook similar to before_fork in unicorn.

Sign up to request clarification or add additional context in comments.

2 Comments

thanks for suggesting to close the connection after I load all model classes, yes I do preload the app
puma has a before_fork hook now github.com/puma/puma#clustered-mode

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.