Ethan
Ethan

Reputation: 18864

ActiveRecord: how to reconnect to PostgreSQL automatically when connection drops?

I am using ActiveRecord with Sinatra and PostgreSQL. When the database connection drops (due to temporary network failure or postgres server restarting), my app doesn't re-acquire connection automatically. I'll have to restart the app in order to connect to postgres again. I remember I didn't have this problem when I was using Rails in another project.

Do I need to put some configuration or code to tell ActiveRecord to reconnect to PostgreSQL automatically?

Upvotes: 8

Views: 5160

Answers (3)

Jesper Rønn-Jensen
Jesper Rønn-Jensen

Reputation: 111616

UPDATED 2019-01-11 As of Rails 4.2 I have to use

ActiveRecord::Base.clear_active_connections!

and ActiveRecord will reconnect on next query. Works also from Rails console, which is rather convenient

Upvotes: 2

ruseel
ruseel

Reputation: 1734

ActiveRecord::Base.verify_active_connections! has removed back in 2012 in rails commit 9d1f1b1ea9e5d637984fda4f276db77ffd1dbdcb. so we can't use that method.

sentences below is my result of short investigation. I am no experts in rails activerecord. so listen with caution. (but hope this helpful)

comment in connection_pool.rb said

  # 1. Simply use ActiveRecord::Base.connection as with Active Record 2.1 and
  #    earlier (pre-connection-pooling). Eventually, when you're done with
  #    the connection(s) and wish it to be returned to the pool, you call
  #    ActiveRecord::Base.clear_active_connections!. This will be the
  #    default behavior for Active Record when used in conjunction with
  #    Action Pack's request handling cycle.

so maybe you (and I. I have a same situation just like you) have to return connection to pool.

and to return connection to pool in sinatra as Action Pack's request handling cycle, use ActiveRecord::ConnectionAdapters::ConnectionManagement

use ActiveRecord::ConnectionAdapters::ConnectionManagement

and then as stated in rails commit 9d1f1b1ea9e5d637984fda4f276db77ffd1dbdcb we are using a different way as in this line, always checkout_and_verify when using Basae.connection by obeying action pack lifecycle.

  def connection
    # this is correctly done double-checked locking
    # (ThreadSafe::Cache's lookups have volatile semantics)
    @reserved_connections[current_connection_id] || synchronize do
      @reserved_connections[current_connection_id] ||= checkout
    end
  end

Upvotes: 2

ian
ian

Reputation: 12251

From https://www.new-bamboo.co.uk/blog/2010/04/11/automatic-reconnection-of-mysql-connections-in-active-record/

If you use Active Record outside Rails or at least outside controller actions you have to verify connections on your own before executing a database statement. This can be done with the following code:

ActiveRecord::Base.verify_active_connections!

Since Active Record uses one connection per thread, in multi-threaded applications this verification has to be executed for each thread separately.

The blog post is about reconnecting to MySQL but I'm guessing it would be the same regardless of the engine used, as it's abstracted away. The blog also mentions a reconnect option in the configuration, but you'll have to find out if that works for Postgres.

Upvotes: 0

Related Questions