Frage

Ich habe Site-Laufen-Rails-Anwendungs- und Resque-Mitarbeiter im Produktionsmodus unter Ubuntu 9.10, Rails 2.3.4, Ruby-ee 2010.01, PostgreSQL 8.4.2

Die Arbeiter haben ständig Fehler angehoben: PGERROR: Server schloss die Verbindung unerwartet ab.

Meine beste Vermutung ist, dass Master Resque -Prozess eine Verbindung zu DB herstellt (z. B. Authlogic tut dies, wenn sie user.acts_as_authentic) beim Laden von Rails -App -Klassen, und diese Verbindung wird in fork () ed (am Exit?), Also als nächstes Forked, beschädigt. Kinder erhalten eine Art gebrochenes globales activerecord :: base.connection

Ich könnte ein sehr ähnliches Verhalten damit reproduzieren Beispielcode Nachahmung von Gabel/Verarbeitung in Resque Worker. (AFAIK, Benutzer von LIBPQ haben empfohlen, Verbindungen im Forked -Prozess ohnehin nachzubilden, sonst ist es nicht sicher.)

Das Seltsame ist jedoch, dass solche Fehler nicht angezeigt werden, wenn ich PGBouncer oder pgpool-II anstelle von direkter PGSQL-Verbindung verwende.

Die Frage ist also, wo und wie ich graben soll, um herauszufinden, warum es für einfache Verbindung gebrochen ist und mit Verbindungspools arbeitet. Oder angemessene Problemumgehung?

War es hilfreich?

Lösung

Als ich erstellt habe Nestor, Ich hatte das gleiche Problem. Die Lösung bestand darin, die Verbindung im Forked-Prozess wiederherzustellen. Siehe den entsprechenden Code bei http://github.com/francois/nestor/blob/master/lib/nestor/mappers/rails/test/unit.rb#l162

Von meinem sehr Ein begrenzter Blick auf Resque -Code, ich glaube, ein Anruf bei #Establish_Connection sollte hier richtig gemacht werden: https://github.com/resque/resque/blob/master/lib/resque/worker.rb#l123

Andere Tipps

Nach ein wenig Forschung / Versuch und Irrtum. Für alle, die auf das gleiche Problem stoßen. Um zu verdeutlichen, was GC erwähnt hat.

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

Der obere Code sollte in: /lib/tasks/resque.rake platziert werden

Zum Beispiel:

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"

Ich hoffe, das hilft jemandem, genauso wie es für mich getan hat.

Sie können keine LIBPQ -Referenz über einen Fork () (oder an einen neuen Thread) übergeben, es sei denn, Ihre Bewerbung sorgt dafür, dass Sie sie nicht auf widersprüchliche Weise verwenden. (Wie ein Mutex um jeden einzelnen Versuch, es zu verwenden, und Sie dürfen ihn niemals schließen). Dies gilt sowohl für direkte Verbindungen als auch für die Verwendung von PGBouncer. Wenn es in PGBouncer funktionierte, war dies ein pures Glück, wenn es aus irgendeinem Grund eine Rennbedingung verpasste, und wird schließlich brechen.

Wenn Ihr Programm die Gabele verwendet, sind Sie muss Erstellen Sie die Verbindung nach die Gabel.

Ändern Sie die Apache -Konfiguration und fügen Sie hinzu

PassengerSpawnMethod conservative

Ich hatte dieses Problem mit allen meinen Mailerkursen und musste anrufen ActiveRecord::Base.verify_active_connections! Innerhalb der Mailer -Methoden, um sicherzustellen, dass eine Verbindung hergestellt wurde.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top