Rails マルチスレッド実行環境でデッドロックが発生

2020年7月29日水曜日

Rails

t f B! P L

概要

RailsでThreadを利用して並行処理を実装したが、デッドロックが発生。処理が止まってしまった。エラーも発生しない

class MainController
  def thread_exe
    sub_a = Sub_A.find(1)
    th = Thread.new { Sub_A.call_b }
    th.join
  end
end
class Sub_A < ApplicationRecord
  def call_b
    Sub_B.call_b # ここでデッドロック
  end
end
class Sub_B < ApplicationRecord
  def call_b
    # 何らかの処理
  end
end

解決策

permit_concurrent_loadsメソッドで外部クラスの自動読み込みを許可する

class MainController
  def thread_exe
    sub_a = Sub_A.find(1)
    th = Thread.new { Sub_A.call_b }
    # ここを追加
    ActiveSupport::Dependencies.interlock.permit_concurrent_loads do
      th.join
    end
  end
end

予備知識

Threadとは

一連の処理の流れのこと。複数の処理の流れはマルチスレッド

リエントラント

処理を実行中に再び同じ処理が呼び出され並行に実行されたとしても、データ破壊や矛盾などが発生せず、安全に処理終了できること

Railsの自動読み込み

Railsではrequireを書かなくてもappはいかのcontrollersやmodelsなどにあるファイルを自動読み込みする

自己紹介

Webエンジニアをやっています。日々思ったことや、読書レビュー、IT系の記事などを書き連ねています

Rails6で追加 レコードを一括登録できるinsert_allについて

  insert_allの概要 rails6で追加された。複数レコードを一括登録できる。 insert_allドキュメント insert_allの使い方 形としてはこんな感じ。 モデル.insert_all([{カラム: value...},{カラム: value...}......

QooQ