2009-10-21 12 views
7

Ich habe eine Rails-Anwendung, in der eine kleine Anzahl von Aktionen erhebliche Rechenzeit benötigt. Anstatt die Komplexität der Verwaltung dieser Aktionen als Hintergrundaufgaben zu bewältigen, habe ich festgestellt, dass ich die Verarbeitung in mehrere Threads aufteilen kann und mithilfe von JRuby mit einem Multicore-Server sicherstellen kann, dass alle Threads in einer angemessenen Zeit abgeschlossen werden. (Der Kunde hat bereits ein starkes Interesse daran gezeigt, diesen Ansatz gegenüber laufenden Aufgaben im Hintergrund zu halten.)In Threads in einer Rails-Anwendung protokollieren

Das Problem besteht darin, dass das Schreiben in den Rails-Logger innerhalb dieser Threads nicht funktioniert. In der Protokolldatei wird nichts angezeigt. Ich habe ein paar Hinweise auf dieses Problem gefunden, aber keine Lösungen. Es würde mir nichts ausmachen puts in meinen Code einzufügen, um beim Debuggen zu helfen, aber stdout scheint vom Glassfish Gem App Server aufgefressen zu sein.

Hat jemand erfolgreich Logging in einem Rails Ruby Thread gemacht, ohne jedes Mal ein neues Log zu erstellen?

+0

Update: Ich habe festgestellt, dass Puts in Threads in der Glassfish-Protokolldatei angezeigt werden. Ich bin nicht sicher, warum ich das vorher nicht gesehen habe; Ich könnte es ursprünglich in einem Thread getestet haben, der von einem anderen (Nicht-Haupt) -Thread erzeugt wurde. Wie auch immer, ich sehe zu Debugging-Zwecken Schreibvorgänge in STDOUT in der Protokolldatei, also bin ich glücklich. –

Antwort

4

Ich kratzte mich am Kopf mit dem gleichen Problem. Für mich war die Antwort wie folgt:

Thread.new do 
    begin 
    ... 
    ensure 
    Rails.logger.flush 
    end 
end 
+0

Sieht gut aus! Vielen Dank! –

+0

Funktioniert nicht für mich, mit EM – skrat

0

Ich verstehe Ihre Bedenken über die Hintergrundaufgaben, aber denken Sie daran, dass das Ausspinnen von Threads in Rails eine beängstigende Sache sein kann. Das Framework macht fast keine Vorkehrungen für das Multithreading, das heißt, Sie müssen alle Rails-Objekte als nicht threadsicher behandeln. Selbst die Datenbankverbindung wird schwierig.

Wie für den Logger: Die Standard-Ruby Logger-Klasse sollte threadsicher sein. Aber selbst wenn Rails das nutzt, haben Sie keine Kontrolle darüber, was die Rails-App damit macht. Zum Beispiel "bremst" der Benchmarking-Mechanismus den Logger durch Umschalten der Ebenen.

Ich würde vermeiden, die Schienen Logger zu verwenden. Wenn Sie die Threads verwenden möchten, erstellen Sie einen neuen Logger innerhalb des Threads, der die Nachrichten für diesen Vorgang protokolliert. Wenn Sie für jeden Thread kein neues Protokoll erstellen möchten, können Sie auch versuchen, in Ihrer Laufzeitumgebung ein threadsiches Protokollierungsobjekt zu erstellen, auf das jeder der Threads zugreifen kann.

An Ihrer Stelle würde ich wahrscheinlich einen anderen Blick auf die Hintergrund-Job-Lösungen haben. Während DRb wie ein Albtraum aussieht, scheint "bj" nett und leicht; obwohl es etwas Arbeit erforderte, um es mit JRuby laufen zu lassen. Es gibt auch die Alternative, einen Java-Scheduler von JRuby zu verwenden, siehe http://www.jkraemer.net/2008/1/12/job-scheduling-with-jruby-and-rails

+0

Vielen Dank für die Informationen und Vorschläge, aber an dieser Stelle werde ich mit dem Threading-Ansatz bleiben, da es außer der Protokollierung funktioniert. Ich verwende keine fragwürdigen Edelsteine ​​/ Plugins in irgendeinem der Threads und bin vorsichtig bei der Verwendung von Mutexen, um Rennbedingungen zu verhindern. Mein Interesse an der Verwendung der Rails-Logger war einfach Debugging und ich habe es geschafft, indem Sie Threads nur wenn JRUBY_VERSION definiert ist und sonst den gleichen Code sequenziell ausgeführt wird. Danke trotzdem! –

Verwandte Themen