Railsの起動時に、アプリの存続期間中実行されるスレッドを作成しようとしています。奇妙なことに、実行中の別のスレッドで既にこれが機能していました。その (作業中の) コードをコピーし、それを新しいスレッドの新しいコードのボイラープレートとして使用しました。しかし、スレッドは起動しません。
- コードは config/initializers にあります (これは正しい場所ですか?)。
- ファイルは最後に実行されるように「z_...」で始まる名前が付けられます。
- レール 3.2.6
コードの一般的な構造は次のとおりです。
class Blah
def self.the_thread
The_Model.transaction do
# do some database stuff
# ...
end
TheThread = Thread.new do
while true do
the_thread
sleep 5.seconds
end
end
end
Rails コンソールを開いて Blah::TheThread を調べると、一度も実行されていないように見えるデッド スレッドが明らかになります。Railsコンソールを開いたときにメソッドを実行でき、問題なく動作するため、クラスの宣言にもメソッドにもエラーはないようです。また、レールコンソールにスレッドを生成する上記の正確なコードを手動で入力すると (TheThread = Thread new do ...)、問題なく動作します (5 秒ごとにウェイクアップし、そのことを実行し、再びスリープします)。
繰り返しますが、奇妙なことに、Rails で単純なスレッドを生成するためのこの正確なボイラープレートは、以前はまったく同じアプリケーションで機能していました。
私が奇妙な問題であると考えるものについて、誰かが何らかの洞察を持っているなら、私は完全に耳を傾けます.
ありがとう。
編集: 新しい情報 - トランザクション呼び出し (および一致する終了) をコメントアウトしたところ、正常に動作します。ただし、トランザクションが何を妨げているのかはわかりません。他のカスタム初期化スクリプトを削除しましたが、ディレクトリ内の他のスクリプトは、デフォルトのものか、devise に属するものだけです。私はそれらを熟読しましたが、取引が行われているのを見ませんでした。
さらに新しい情報。スレッド コードの最後に「TheThread.abort_on_exception = true」を追加しました。Rails を起動すると、「ArgumentError: 閉じたデータベースで準備が呼び出されました: ロールバック トランザクション (ActiveRecord::StatementInvalid)」という例外が発生します。エラーは sqlite3 gem で発生しています。私は sqlite3 gem バージョン 1.3.6 と sqlite-ruby gem バージョン 1.3.3 を持っています。エラーをグーグルで調べたところ、同じエラーについて不平を言っている投稿がいくつか見つかりましたが、解決策はありませんでした。
これはもはやスレッドの問題ではなく、データベースの問題であると考えていますが、この投稿のタイトルを変更するには遅すぎます。
これだけ: スレッド コードの先頭 (while ループに入る直前) に「sleep 15.seconds」を配置すると、問題が解決されます。しかし、問題の原因と、「ハッキングされていない」解決策が何であるかを知りたいです。何らかの理由で、このコードの実行時にデータベースの準備ができていません。私の初期化コードは単に間違った場所にありますか?