2009-11-10 8 views
5

Je suis en train d'écrire un projet en Ruby qui utilise la gemme ActiveRecord pour l'interaction de base de données et j'essaye de consigner toute l'activité de base de données en utilisant l'attribut ActiveRecord::Base.logger avec le code suivantRuby Daemons causant ActiveRecord logger IOError

ActiveRecord::Base.logger = Logger.new(File.open('logs/database.log', 'a')) 

Cela fonctionne bien pour les migrations etc (qui, pour une raison quelconque, semblent exiger que l'exploitation soit activée, car cela donne une erreur NilClass quand il est désactivé) mais lorsque je tente d'exécuter le projet qui comprend un démon fileté appelant le ActiveRecord objet le script échoue avec l'erreur suivante

/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/logger.rb:504:in `write': closed stream (IOError) 

Des idées sur la façon de résoudre ce problème seraient grandement appréciées. Pour le moment, j'ai commencé à regarder à travers un autre code pour voir si les gens ont d'autres moyens de mise en œuvre de l'exploitation forestière ActiveRecord dans un plus thread-safe mode

Merci

Patrick

Répondre

1

Il se avère que pour les migrations pour travailler la variable ActiveRecord::Base.logger ne peut pas être nul, ce qui explique la première moitié du problème. Je ne suis pas encore capable de corriger IOError quand un fichier est utilisé à la place de STDERR.

+0

Est-ce que la tige de problème de synchronisation? Pourriez-vous utiliser BufferedLogger de Rails à la place, et voir si cela a résolu le problème? –

+0

Nous avons fini par écrire une simple application de journalisation pour nos besoins en utilisant DRB qui traitait les erreurs pour tous nos threads –

4

J'ai rencontré le même problème. Vous devez d'abord démoniser, puis puis charger l'environnement Rails.

+0

Pourriez-vous expliquer ce que vous entendez par "démoniser puis charger Rails env" –

+0

Daemons.run_proc ('your_daemon', daemon_options) {require File.expand_path (File.join (File.dirname (__ FICHIER__), '..', 'config', 'environment')) # faire des choses} –

+0

@LoganKoester Notez que si vous essayez d'obtenir les informations de dir sur '__FILE__' travailler après avoir été démonisé, car le processus perd cette information. Vous devrez sauvegarder ce chemin avant de démoniser. – Kelvin

4

la delayed_job ont daemons et activerecord, avant daemonize, obtenir les fichiers ont opend, puis rouvrira ses portes en daemonize

@files_to_reopen = [] 
ObjectSpace.each_object(File) do |file| 
    @files_to_reopen << file unless file.closed? 
end 

Daemons.run_proc("xxxxx_name",:dir=>pid_file,:dir_mode=>:normal) do 
    Dir.chdir(Rails.root) 
    # Re-open file handles 
    @files_to_reopen.each do |file| 
    begin 
     file.reopen file.path 
     file.sync = true 
    rescue ::Exception 
    end 
    end 
end 
+1

Ils font quelque chose de similaire dans lib/delayed/command.rb – m33lky

+0

N'oubliez pas d'ajouter une permission d'écriture. 'file.reopen file.path," a "' – Phil