Rails 4 + Devise 3.2 アプリケーションの機能で、ユーザーが AJAX POST を介して次のアクションにパスワードを変更できるようにする機能で奇妙な問題が発生しています。ユーザーがパスワードを変更した後、後で 1 つ以上の要求を行った後、強制的にログアウトされ、再度サインインした後も強制的にログアウトされ続けるようです。
# POST /update_my_password
def update_my_password
@user = User.find(current_user.id)
authorize! :update, @user ## CanCan check here as well
if @user.valid_password?(params[:old_password])
@user.password = params[:new_password]
@user.password_confirmation = params[:new_password_conf]
if @user.save
sign_in @user, :bypass => true
head :no_content
return
end
else
render :json => { "error_code" => "Incorrect password" }, :status => 401
return
end
render :json => { :errors => @user.errors }, :status => 422
end
このアクションは実際には開発では問題なく機能しますが、マルチスレッド、マルチワーカーの Puma インスタンスを実行している場合、本番環境では失敗します。発生しているように見えるのは、リクエストの 1 つが別のスレッドに到達するまでユーザーがログインしたままになり、その後Unauthorized
401 応答ステータスでログアウトされることです。単一のスレッドと単一のワーカーで Puma を実行すると、問題は発生しません。ユーザーが複数のスレッドで再度ログインしたままにできるようにする唯一の方法は、サーバーを再起動することです (これは解決策ではありません)。私が持っているセッションストレージ構成がそれを正しく処理すると思っていたので、これはかなり奇妙です。私のconfig/initializers/session_store.rb
ファイルには以下が含まれています:
MyApp::Application.config.session_store(ActionDispatch::Session::CacheStore,
:expire_after => 3.days)
私のproduction.rb
設定には以下が含まれます:
config.cache_store = :dalli_store, ENV["MEMCACHE_SERVERS"],
{
:pool_size => (ENV['MEMCACHE_POOL_SIZE'] || 1),
:compress => true,
:socket_timeout => 0.75,
:socket_max_failures => 3,
:socket_failure_delay => 0.1,
:down_retry_delay => 2.seconds,
:keepalive => true,
:failover => true
}
経由でプーマを起動していbundle exec puma -p $PORT -C ./config/puma.rb
ます。私のpuma.rb
内容:
threads ENV['PUMA_MIN_THREADS'] || 8, ENV['PUMA_MAX_THREADS'] || 16
workers ENV['PUMA_WORKERS'] || 2
preload_app!
on_worker_boot do
ActiveSupport.on_load(:active_record) do
config = Rails.application.config.database_configuration[Rails.env]
config['reaping_frequency'] = ENV['DB_REAP_FREQ'] || 10 # seconds
config['pool'] = ENV['DB_POOL'] || 16
ActiveRecord::Base.establish_connection(config)
end
end
それで...ここで何がうまくいかないのでしょうか?パスワードが変更されたときに、サーバーを再起動せずにすべてのスレッド/ワーカーでセッションを更新するにはどうすればよいですか?