I was playing around with Sinatra and ActiveRecord when I found that a connections are not reused automatically by this simple API.
#!/usr/bin/env ruby
require 'sinatra'
require 'active_record'
ActiveRecord::Base.establish_connection(
adapter: 'sqlite3',
database: 'newsletter.db'
)
ActiveRecord::Schema.define do
create_table :subscribers do |t|
t.string :email
t.timestamps
end
end
class Subscriber < ActiveRecord::Base
validates :email, presence: true
end
class Newsletter < Sinatra::Base
set :server, :thin
get '/subscribers/:email' do
s = Subscriber.find_by_email(params[:email])
if s == nil
status 404
else
content_type 'application/json'
s.to_json
end
end
post '/subscribers/:email' do
Subscriber.create(email: params[:email])
end
end
Newsletter.run!
The API returns either a subscriber or a 404 the first 5 times I GET a subscriber. The 6th time I get a timeout. After each of the first 5 GETs, there is one more read+write file descriptor open for newsletter.db
. I would expect there to be only one all the time.
How do I tell ActiveRecord to reuse a connection?
One way of cleaning connections is to call ActiveRecord::Base.clear_active_connections!
after each use of Subscriber.find_by_email
and Subscriber.create
, like so.
after do
ActiveRecord::Base.clear_active_connections!
end
Somewhere else, some people suggest using middleware ActiveRecord::ConnectionAdapters::ConnectionManagement
. That does not work in Thin because Thin starts processing each request in a thread and finishes processing the request in another thread. ConnectionManagement
only returns to the pool those connections that are active for the current thread and Thin applies ConnectionManagement
in the second thread instead of the first.
EDIT:
I made an explanation of why using middleware ActiveRecord::Connectionadapters::ConnectionManagement
won't work with Thin in threaded mode, which you can find here.
2016.05.18 EDIT:
I followed up this issue with Thin author and this issue is not resolved after issue 307.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With