1

ActiveResource のリクエストでホスト名が解決されても、相手側に情報を返すサーバーがない場合、ActiveResource のタイムアウト値が機能しません。リクエストがハングするだけです。

ActiveResource コードを確認した後、これは、基になる Net:Http オブジェクトに設定されているタイムアウト値が 1 つしかないためであることがわかりました: read_timeout です。Net:Http ライブラリでは、これを「(1 回の read(2) 呼び出しで) 1 ブロックを読み取るまで待機する秒数」と定義しています。Net:Http lib は、別のタイムアウト値 open_timeout も定義します。これは、「接続が開かれるまで待機する秒数」として定義されます。

ActiveResource クラスに設定されたタイムアウト値で open_timeout がデフォルトで設定されない理由はわかりませんが、ActiveResource::Connection クラスを変更して http オブジェクトに open_timeout を含めるようにした後、私の問題は解決しました!

私はレールに慣れていないので、プロジェクトで実際にこの変更を行う最善の方法がわかりません。gem ディレクトリのコードだけを変更したくありません。Rails プロジェクトでこれらの変更を行う適切な方法はありますか? Rails クラスを /vendor フォルダーからロードできることを見てきましたが、それが機能するにはすべてのクラスがそこにある必要がありますか? ActiveResource::Base および ActiveResource::Connection クラスのサブクラスを作成し始めましたが、Net:Http インスタンスを作成する関数はプライベートであるため、これを行うためのより簡単な方法があるように思えました...何か考えはありますか?

4

1 に答える 1

3

まず、これは Rails のバグトラッカー ( https://rails.lighthouseapp.com/projects/8994-ruby-on-rails/ ) に報告する必要がある問題です。

このような小さな問題を修正する必要がある場合、通常は RAILS_ROOT/config/initializers に初期化ファイルを作成し、修正する予定のクラスを再度開きます。

class ActiveResource::Base
  # your fix goes here
end

これはモンキーパッチと呼ばれ、やや物議をかもしています。しかし、個人的には、コードにとって意味的な意味を持たない新しいレベルを継承階層に導入することは非常に残忍だと考えています。

于 2009-07-24T09:22:20.570 に答える