Question

Je place application en cours d'exécution et rails travailleurs Resque en cours d'exécution en mode de production, sur Ubuntu 9.10, Rails 2.3.4, rubis-ee 2010.01, PostgreSQL 8.4.2

Les travailleurs constamment soulevé des erreurs: PGError: serveur a fermé la connexion de façon inattendue

.

Ma meilleure estimation est que le processus de resque maître établit une connexion à db (par exemple authlogic fait que lorsque l'utilisation User.acts_as_authentic), tandis que les classes rails de chargement d'applications, et que la connexion est endommagé dans le processus ed fork () (à la sortie?), donc les enfants à venir se fourchus genre de cassés mondiale ActiveRecord :: Base.connection

Je pourrais reproduire très comportement similaire à cette imitant la fourche / traitement Worker resque. (AFAIK, les utilisateurs de libpq recommandé de recréer des connexions dans le processus fourchue de toute façon, sinon ce n'est pas sûr)

Mais, la chose étrange est que lorsque j'utilise pgbouncer ou pgpool-II au lieu de la connexion pgsql directe, de telles erreurs ne semblent pas.

Alors, la question est où et comment dois-je creuser pour savoir pourquoi il est cassé pour une connexion simple et fonctionne avec les pools de connexion? Ou solution raisonnable?

Était-ce utile?

La solution

Quand je crée Nestor , j'ai eu le même genre de problème. La solution était de rétablir la connexion dans le processus fourchue. Voir le code correspondant à http : //github.com/francois/nestor/blob/master/lib/nestor/mappers/rails/test/unit.rb#L162

De mon très regard limité à un code Resque, je crois un appel à #establish_connection devrait se faire à peu près ici: https://github.com/resque/resque/blob/master/lib/resque/worker.rb#L123

Autres conseils

Après avoir fait un peu de recherche / essais et erreurs. Pour toute personne qui vient sur la même question. Pour clarifier ce gc mentionné.

Resque.after_fork = Proc.new { ActiveRecord::Base.establish_connection }

code ci-dessus doit être placé dans: /lib/tasks/resque.rake

Par exemple:

require 'resque/tasks'

task "resque:setup" => :environment do
  ENV['QUEUE'] = '*'

  Resque.after_fork do |job|
    ActiveRecord::Base.establish_connection
  end

end

desc "Alias for resque:work (To run workers on Heroku)"
task "jobs:work" => "resque:work"

Espérons que cela aide quelqu'un, autant qu'il a fait pour moi.

Vous ne pouvez pas passer une référence libpq dans une fourchette () (ou à un nouveau thread), à moins que votre application prend en charge très proche de ne pas l'utiliser de manière contradictoires. (Comme un mutex autour de chaque tentative simple à utiliser, et vous ne devez jamais fermer). Ceci est la même pour les deux liaisons directes et en utilisant pgbouncer. Si cela a fonctionné dans pgbouncer, qui était la chance pure en manque une condition de course pour une raison quelconque, et finira par se briser.

Si votre programme utilise bifurquer, vous doit créer la connexion après la fourche.

Modification de la configuration Apache et ajoutez

PassengerSpawnMethod conservative

J'ai eu ce problème avec toutes mes classes de Mailer et je devais appeler ActiveRecord::Base.verify_active_connections! dans les méthodes de mailer afin d'assurer une connexion a été faite.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top