У меня есть сайт, запускающий приложение направляющих и рискованных рабочих, работающих в производственном режиме, на Ubuntu 9.10, направляющие 2.3.4, рубиновые-ee 2010.01, PostgreSQL 8.4.2
Рабочие постоянно повышали ошибки: PGError: сервер неожиданно закрыл соединение.
Мое лучшее предположение - то, что основной рискованный процесс устанавливает соединение с дб (например, authlogic делает это, когда Пользователь acts_as_authentic использования), при загрузке классов приложения для направляющих, и то соединение становится поврежденным в ветвлении () процесс редактора (на выходе?), поэтому затем разветвленные дети получают вид поврежденного глобального ActiveRecord:: Base.connection
Я мог воспроизвести очень похожее поведение с этим примером кода, подражающим ветвлению/обработке в рискованном рабочем. (AFAIK, пользователи libpq рекомендовали воссоздать соединения в разветвленном процессе так или иначе, иначе это не безопасно),
Но, нечетная вещь состоит в том, что, когда я использую pgbouncer или pgpool-II вместо прямого pgsql соединения, такие ошибки не появляются.
Так, вопрос состоит в том, где и как я должен вырыть для обнаружения, почему он повреждается для простого соединения и работает с пулами соединения? Или разумное обходное решение?
Когда я создал Нестора , у меня была такая же проблема. Решением было восстановить соединение в разветвленном процессе. См. Соответствующий код на http://github.com/francois/nestor/blob/master/lib/nestor/mappers/rails/test/unit.rb#L162
Из моего очень ограниченный взгляд на код Resque, я считаю, что вызов #establish_connection следует делать прямо здесь: https://github.com/resque/resque/blob/master/lib/resque/worker.rb#L123
Вы не можете передать ссылку libpq через fork () (или в новый поток), если ваше приложение не позаботится о том, чтобы не использовать ее конфликтующими способами. (Например, мьютекс вокруг каждой попытки его использования, и вы никогда не должны его закрывать). То же самое и для прямого подключения, и для использования pgbouncer. Если это сработало в pgbouncer, это была чистая удача, потому что по какой-то причине не было состояния гонки, и в конечном итоге она сломается.
Если ваша программа использует разветвление, вы должны создать соединение после разветвления.