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?

È stato utile?

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.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top