RailsのPooling機能覚書

環境

Ruby 1.8.7p302
Rails 2.3.10
DB SQL Server
接続タイムアウトは指定できる?

何のことはない database.yml に wait_timeout を指定するだけで良かった。
因みに秒指定。

development:
  adapter: sqlserver
  mode: odbc
  dsn: mssql_development
  database: testdb_dev
  username: testuser
  password: ********
  pool: 8
  wait_timeout: 8

だけど、これはRubyのバージョンが1.9未満の場合だけらしい。


activerecord-2.3.10/lib/active_record/connection_adapters/abstract/connection_pool.rb

        # default 5 second timeout unless on ruby 1.9
        @timeout =
          if RUBY_VERSION < '1.9'
            spec.config[:wait_timeout] || 5
          end

Ruby1.9を使う場合は、Railsのバージョンも3に上げる必要があるっつうことですな。

Failoverに対応してる?

ネットを彷徨っていると、対応していない、というページがヒットした・・・


参考:
Rails(ActiveRecord)でデータベースへのコネクションプーリングをさせなくする - はまさき
(LVS + keepalivedだとダメ、ということみたい。)


それは困る!
ということで、とりあえず2.3.10のソースコードを調べてみた。
checkoutの際、新規接続も既存接続も verify! が呼ばれるようになっている。


activerecord-2.3.10/lib/active_record/connection_adapters/abstract/connection_pool.rb

      def checkout_and_verify(c)
        c.verify!
        c.run_callbacks :checkout
        @checked_out << c
        c
      end

もう少し掘り下げて、SQL Serverのアダプタで、verify! が有効か調べてみた。


activerecord-2.3.10/lib/active_record/connection_adapters/abstract_adapter.rb

      # Checks whether the connection to the database is still active (i.e. not stale).
      # This is done under the hood by calling <tt>active?</tt>. If the connection
      # is no longer active, then this method will reconnect to the database.
      def verify!(*ignored)
        reconnect! unless active?
      end

activerecord-sqlserver-adapter-2.3.13/lib/active_record/connection_adapters/sqlserver_adapter.rb

      # CONNECTION MANAGEMENT ====================================#
      
      def active?
        connected = case @connection_options[:mode]
                    when :dblib
                      !@connection.closed?
                    when :odbc
                      true
                    else :adonet
                      true
                    end
        return false if !connected
        raw_connection_do("SELECT 1")
        true
      rescue *lost_connection_exceptions
        false
      end

      def reconnect!
        disconnect!
        connect
        active?
      end

有効っぽいな・・・とりあえず安心。
(時間が出来たら実際に試してみよう。)


もっと詳しく調べている人がいた。


参考:
ActiveRecordのDBコネクションの接続切れと再接続について。reconnectオプションは危険だなーとかも - odeの開発メモ日記