Приложение Rails зависает: завершено 401 Unauthorized in x ms

После обновления приложения Rails с RestfulAuthentication и Rails 2.3 до Devise и Rails 5.0 мы получаем странные ошибки «401 Unauthorized», и приложение rails зависает при первом же запросе:

Completed 401 Unauthorized in x ms

где х очень большое число. Ошибка возникает только при первом запуске сервера (после длительного простоя). Приложение просто зависает и отказывается запускаться, а если мы прерываем работу сервера, то появляются ошибки 401 Unauthorized. Кажется, не имеет значения, используем ли мы Webrick, Puma, Thin или Unicorn. ApplicationController выглядит так

class ApplicationController < ActionController::Base
  protect_from_forgery with: :exception
  before_action :set_http_headers
  alias login_required authenticate_user!
  ...

(псевдоним был добавлен, чтобы гарантировать плавный переход на Devise). Конфигурационный файл database.yml выглядит так

development:
  adapter: mysql2
  encoding: utf8
  database: db_name
  pool: 5
  timeout: 5000
  username: db_user
  passwort:

После запуска приложения ошибки исчезают, но если мы перезагрузим компьютер через несколько часов или на следующий день, ошибка появится снова.

Иногда также возникают ошибки тайм-аута, такие как

ActiveRecord::ConnectionTimeoutError: could not obtain a connection from the pool within 5.000 seconds (waited 5.003 seconds); all pooled connections were in use

or

No live threads left. Deadlock? (fatal)

Связанные с Devise проблемы (здесь и здесь) не помогают, и ни один из связанных вопросов не дал решения, ни ActiveRecord::Base.clear_active_connections! не помогает, как было предложено здесь и Session.delete_all (сессия хранится в ActiveRecord). Помощь! Любые идеи?


person 0x4a6f4672    schedule 06.09.2016    source источник
comment
Это будет очень сложно устранить, не имея доступа к приложению. Вы действительно обновились с 2.3 до 5.0? На одном дыхании? Тогда ожидайте много других проблем :) Или вы обновлялись постепенно? Тогда между какими версиями это действительно произошло?   -  person Thilo    schedule 06.09.2016
comment
На самом деле мы создали новое приложение Rails 5, которое подключено к старой базе данных MySQL, и немного модифицировали его в соответствии с официальными рекомендациями github.com/plataformatec/devise/wiki/   -  person 0x4a6f4672    schedule 06.09.2016
comment
Проблема, скорее всего, в вашем коде, который вы не включили в вопрос. Нам нужно это увидеть, чтобы иметь возможность диагностировать проблему. Перед строкой Completed 401 Unauthorized in x ms в вашем журнале должна быть еще одна строка, указывающая, какой контроллер и какое действие обрабатывает запрос — опубликуйте код для этого контроллера. Если это происходит при каждом запросе, опубликуйте контроллер приложения.   -  person ArtOfCode    schedule 06.09.2016
comment
Я добавил первые строки контроллера приложений. Почему-то логи ничего не говорят, потому что приложение просто зависает :-( Только если приложение прерывается по Ctrl-C в терминале появляется сообщение об ошибке, а трассировка стека указывает только на сам веб-сервер :-(   -  person 0x4a6f4672    schedule 06.09.2016
comment
Добавьте свои файлы database.yml и, возможно, файлы my.cnf - я подозреваю, что это просто где-то ошибка конфигурации.   -  person Thilo    schedule 07.09.2016
comment
К сожалению, также трудно устранить неполадки, если у вас есть доступ к приложению. Проблема все еще возникает, и это очень раздражает :-(   -  person 0x4a6f4672    schedule 28.09.2016


Ответы (2)


Я согласен, что это была особенно неприятная ошибка. Для меня то, что в конечном итоге исправило, изменилось:

config.eager_load = false

to

config.eager_load = true

в config/environments/development.rb

person apod    schedule 22.12.2016
comment
Спасибо! У меня действительно есть config.cache_classes = false и config.eager_load = false в конфиге. Позвольте мне проверить, решает ли он, наконец, эту действительно неприятную ошибку. Какая польза от eager_load = false, если это делает приложение непригодным для использования? - person 0x4a6f4672; 23.12.2016
comment
Я не слишком углублялся в репозиторий Devise, но я предполагаю, что эта ошибка связана с тем, что Devise не имеет доступа к какому-то модулю, который ему нужен, когда он впервые пытается аутентифицироваться. Таким образом, несмотря на то, что отключение await_load может быть нормальным для ванильного приложения Rails, похоже, что оно создает проблемы в сочетании с Devise. Явно где-то ошибка, но не уверен, где именно. - person apod; 23.12.2016
comment
Нет, к сожалению, это не помогло :-( Я ненавижу эту проблему :-( - person 0x4a6f4672; 17.01.2017

Я не знаю, сколько часов мне стоила эта проблема, она действительно раздражает. За последние 8 лет я не встречал бага, на выяснение которого у меня ушло так много времени. Это произошло только в среде разработки. Gemfile говорит

group :development do
  # Spring speeds up development by keeping your application running in the background.
  # Read more: https://github.com/rails/spring
  gem 'spring'
end

Gemfile.lock говорит, что упаковщик установил версию 1.7.2 Spring. Некоторые люди предлагают останавливать spring, если команда rails зависает. Я закомментировал гем spring в Gemfile, удалил гем с помощью gem uninstall spring и обновил диспетчер версий RVM ruby, который я все еще использую, и проблема с зависанием рельсов при первом запуске кажется менее частой (но она не исчезла полностью)

  # gem 'spring'

Таким образом, это частично проблема spring, возможно, связанная с эта проблема. Довольно парадоксально, гем, который должен ускорить приложение, замедляет его до тех пор, пока оно не зависнет :-(

person 0x4a6f4672    schedule 05.10.2016