У меня возникла странная проблема с функцией в моем приложении Rails 4 + Devise 3.2, которая позволяет пользователям изменять свой пароль через AJAX POST на следующее действие, полученное из вики Devise Разрешить пользователям изменять свой пароль. Похоже, что после того, как пользователь изменит свой пароль и после одного или нескольких запросов позже, он будет принудительно выйти из системы и продолжит принудительный выход из системы после повторного входа.
# 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. Похоже, что происходит то, что пользователь останется в системе до тех пор, пока один из их запросов не попадет в другой поток, а затем они выйдут из системы как 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
}
Я загружаю puma через 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
Итак ... что здесь может быть не так? Как я могу обновить сеанс для всех потоков / рабочих при изменении пароля без перезапуска сервера?
sign_in
? - person phoet   schedule 10.02.2014sign_in
не решает проблемы. - person Mike Atlas   schedule 11.02.2014