Rails lavoratori Resque falliscono con PGError: server ha chiuso la connessione inaspettatamente
-
25-09-2019 - |
Domanda
Ho sito in esecuzione rotaie applicazione e lavoratori Resque in esecuzione in modalità di produzione, su Ubuntu 9.10, Rails 2.3.4, ruby-ee 2010.01, PostgreSQL 8.4.2
Lavoratori errori costantemente sollevate: PGError:. Server ha chiuso la connessione inaspettatamente
La mia ipotesi migliore è che processo maestro resque stabilisce una connessione al db (ad esempio Authlogic fa che quando uso User.acts_as_authentic), durante il caricamento rotaie classi app, e che il collegamento viene danneggiato a fork () processo ED (in uscita?), così i bambini prossima biforcuta ottenere tipo di ActiveRecord globale rotto :: Base.connection
ho potuto riprodurre comportamento molto simile con questo codice imitando forcella / campione trasformazione in lavoratore Resque. (AFAIK, gli utenti di libpq consiglia di ricreare le connessioni a processo biforcuta in ogni caso, altrimenti non è sicuro)
Ma, la cosa strana è che quando uso pgbouncer o pgpool-II invece di collegamento pgsql diretta, tali errori non appaiono.
Quindi, la domanda è dove e come deve scavare per scoprire perché si è rotto per il collegamento semplice e sta lavorando con i pool di connessione? O soluzione ragionevole?
Soluzione
Quando ho creato Nestor , ho avuto lo stesso tipo di problema. La soluzione era di ristabilire la connessione nel processo biforcuta. Vedere il codice relativo alla http : //github.com/francois/nestor/blob/master/lib/nestor/mappers/rails/test/unit.rb#L162
Dal mio molto sguardo limitato al codice Resque, credo che una chiamata a #establish_connection dovrebbe essere fatto proprio qui: https://github.com/resque/resque/blob/master/lib/resque/worker.rb#L123
Altri suggerimenti
Dopo aver fatto un po 'di ricerca / tentativi ed errori. Per chi sta venendo attraverso lo stesso problema. Per chiarire cosa GC menzionato.
Resque.after_fork = Proc.new { ActiveRecord::Base.establish_connection }
codice di cui sopra deve essere collocato in: /lib/tasks/resque.rake
Ad esempio:
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"
Spero che questo aiuti qualcuno, per quanto ha fatto per me.
Non è possibile passare un riferimento libpq attraverso un fork () (o ad un nuovo thread), a meno che l'applicazione prende molto vicino cura di non usarlo in conflitto modi. (Come, un mutex intorno ad ogni singolo tentativo di usarla, e non devi mai chiuderlo). Questo è lo stesso per entrambe le connessioni dirette e utilizzando pgbouncer. Se ha funzionato in pgbouncer, che era pura fortuna in manca una condizione di competizione per qualche ragione, e alla fine rompere.
Se i vostri usi di programma si biforcano, è deve creare la connessione dopo la forcella.
Modifica della configurazione di Apache e add
PassengerSpawnMethod conservative
Ho avuto questo problema con tutti i miei corsi Mailer e avevo bisogno di chiamare ActiveRecord::Base.verify_active_connections!
entro i metodi mailer al fine di garantire un collegamento è stato fatto.