1

データベース接続パラメーター (ホスト、データベース名、ユーザー名、パスワード) を保存し、フォームに入力するモデルがあります。作成または更新する前に、入力したパラメーターで接続が良好かどうかを確認する必要があります。validate :check_connectionバリデータを作成します:

# don`t change primary connection
class Remote < ActiveRecord::Base; end

def check_connection
  return if errors.any? || (!new_record? && password.empty?)
  begin
    Remote.establish_connection(
      adapter: 'mysql2',
      host: host,
      username: username,
      password: password,
      database: database,
      connect_timeout: 5,
      reconnect: false
    )
    # maybe need to make some sql request? did try it
  rescue Exception => e
    errors.add :connection, 'Could not connect to database'
  end
end

アクセス可能なホスト ( localhost) を入力しようとすると、上記のようなコードがうまく機能します。しかし、192.168.1.1フォームを送信した後にホストが(アクセスできない)ページがフリーズした場合。1 秒ごとに接続が試行され、ブラウザーで ESC (ページの読み込みを停止) を実行しても停止しませんでした (ネットワーク インターフェイスで tcpdump の試行が見られます)。そして試みは止まらなかった..

では、どうすればデータベースへの接続を検証できますか? また、接続を確立できない場合、ページは長時間ロードされません。

4

2 に答える 2

0

変数connect_timeoutはグローバル変数です。したがって、mysql2おそらく無視してください。

mysql5.6:

mysql[(none)]> set connect_timeout = 123;
ERROR 1229 (HY000): Variable 'connect_timeout' is a GLOBAL variable and should be set with SET GLOBAL

timeoutmysql2の初期化時に変数を設定したのですが反映されません。mysql2 の README には *timeout オプションを設定できると書かれていますが、README は古いか壊れていると思います。

mysql2 0.3.14(宝石):

client =  Mysql2::Client.new(
  host: 'localhost',
  database: 'test',
  username: 'root',
  password: '',
  connect_timeout: 3,
  read_timeout: 3,
  write_timeout: 3,
  wait_timeout: 3);

client.query('show variables like "%timeout%"').map{|r| [r["Variable_name"], r["Value"]] }

=> [["connect_timeout", "10"],
 ["delayed_insert_timeout", "300"],
 ["innodb_lock_wait_timeout", "50"],
 ["innodb_rollback_on_timeout", "OFF"],
 ["interactive_timeout", "28800"],
 ["lock_wait_timeout", "31536000"],
 ["net_read_timeout", "30"],  # Maybe older mysql has read_timeout?
 ["net_write_timeout", "60"], # Maybe older mysql has write_timeout?
 ["slave_net_timeout", "3600"],
 ["wait_timeout", "28800"]]

を使用すると、変数ActiveRecordのみを で設定できます。wait_timeoutdatabase.yml

database.yml で:

development:
  adapter: mysql2
  encoding: utf8
  charset: utf8
  database: test
  pool: 5
  username: root
  password: 
  host: localhost
  connect_timeout: 3
  read_timeout: 3
  write_timeout: 3
  wait_timeout: 3

ActiveRecord 4.0.1 の結果:

> ActiveRecord::Base.connection.execute('show variables like "%timeout%"').to_a
=> [["connect_timeout", "10"],
 ["delayed_insert_timeout", "300"],
 ["innodb_flush_log_at_timeout", "1"],
 ["innodb_lock_wait_timeout", "50"],
 ["innodb_rollback_on_timeout", "OFF"],
 ["interactive_timeout", "28800"],
 ["lock_wait_timeout", "31536000"],
 ["net_read_timeout", "30"],
 ["net_write_timeout", "60"],
 ["rpl_stop_slave_timeout", "31536000"],
 ["slave_net_timeout", "3600"],
 ["wait_timeout", "3"]]

ActiveRecordwait_timeoutで変数を設定しますabstract_mysql_adapter.rb

見る:

abstract_mysql_adapter.rb https://github.com/rails/rails/blob/master/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb

mysql2_adapter.rb https://github.com/rails/rails/blob/master/activerecord/lib/active_record/connection_adapters/mysql2_adapter.rb

于 2014-09-13T11:52:38.523 に答える
0

私はgem 'mysql2'0.3.11バージョンを使用してバンドルインストールしました。このバージョンは無視connect_timeoutされ、新しいバージョンでバグが修正されました。0.3.12b4 ( gem 'mysql2', '~> 0.3.12b4') を試した後、すべて正常に動作します。

于 2012-08-30T11:04:58.983 に答える