如何在ActiveRecord中重复使用连接?

5

当我使用Sinatra和ActiveRecord时,我发现这个简单的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!

API会在我第一次GET订阅者时返回一个订阅者或404。前五次获取订阅者时,每次都会打开一个新的读写文件描述符newsletter.db。第六次请求则超时。我希望始终只有一个读写文件描述符打开。
如何告诉ActiveRecord重用连接?

1
请查看这个答案 https://dev59.com/YGkw5IYBdhLWcg3wBl-A?rq=1 - Angie Rabelero
通过查看那个答案,我最终发现调用 ActiveRecord::Base.clear_active_connections! 对我有用。 我确实尝试了 ActiveRecord::Base.connection.close,发现这种方式关闭了连接而不是将连接返回到连接池中。 我没有尝试过 config.ru 的方法。 - mrrusof
1个回答

1

清理连接的一种方法是在每次使用Subscriber.find_by_emailSubscriber.create之后调用ActiveRecord::Base.clear_active_connections!

after do
    ActiveRecord::Base.clear_active_connections!
end

其他地方,一些人建议使用中间件ActiveRecord::ConnectionAdapters::ConnectionManagement。但在Thin中不起作用,因为Thin在一个线程中开始处理每个请求,并在另一个线程中完成请求的处理。 ConnectionManagement仅将当前线程活动的连接返回到池中,而Thin在第二个线程中应用ConnectionManagement而不是第一个。

编辑:

我解释了为什么在Thin的线程模式下使用中间件ActiveRecord :: Connectionadapters :: ConnectionManagement不起作用,您可以在此处找到。

2016.05.18编辑:

我与Thin作者跟进了这个问题,在问题307之后,该问题未得到解决。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接