2017-02-13 2 views
0

Wie kann ich erkennen, ob ein bestimmter request noch aktiv ist?Schienen, wie man weiß, ob eine bestimmte Anfrage noch läuft

Zum Beispiel habe ich diese Anfrage uuid:

# my_controller.rb 
def my_action 
    request.uuid # -> ABC1233 
end 

Aus einer anderen Anfrage, wie kann ich wissen, ob die Anfrage mit UUID ABC1233 noch funktioniert?


Für die Neugierigen:

beanstalk directives Nach ich Cronjobs leite URL-Anforderungen verwendet wird.

Ich möchte nicht die nächste Iteration starten, wenn die vorherige noch läuft. Ich kann nicht einfach in einem ini/end Flag, das durch die Anfrage aktualisiert wird, weiterleiten, weil die Anfrage einige Male stirbt, bevor sie beendet wird.

Mit normalen Cron-Aufgaben habe ich dies ordnungsgemäß mit der PID des Prozesses verwalten. Aber ich glaube nicht, dass ich PID mehr verwenden kann, weil Prozesse in einem Webserver zwischen verschiedenen Anfragen wiederverwendet werden können.

Antwort

0

Schließlich habe ich meinen vorherigen Ansatz basierend auf PIDs wiederhergestellt.

ich so etwas wie dies umgesetzt:

# The Main Process 
module MyProcess 
    def self.run_forked 
    Process.fork do 
     SynchProcess.run 
    end 

    Process.wait 
    end 

    def self.run 
    RedisClient.set Process.pid # store the PID 

    ... my long process code is here 
    end 

    def self.still_alive?(pid) 
    !!Process.kill(0, pid) rescue false 
    end 
end 

# In one thread I can do 
MyProcess.run_forked 

# In another thread I can do 
pid = RedisClient.get 
MyProcess.still_alive?(pid) # -> true if the process still running 

ich diesen Code aus einer Rails-Anfrage nennen kann und auch wenn der Anforderungsprozess ein das Kind wiederverwendet wird, ist nicht und ich kann die PID des Kindes Prozess überwachen Prüfen Sie, ob der Ruby-Prozess noch läuft.

0

Ich denke nicht, dass Rails (oder genauer gesagt, Rack) Unterstützung dafür hat, da (nach meinem besten Wissen) jede Rails-Anfrage keine anderen Anfragen kennt. Sie können versuchen, Zugriff auf alle laufenden Threads (und sogar Prozesse) zu bekommen, aber eine solche Implementierung (wenn überhaupt möglich) erscheint mir hässlich .

Wie wäre es, es selbst zu implementieren?

class ApplicationController < ActionController::Base 
    before_filter :register_request 
    after_filter :unregister_request 

    def register_request 
     $redis.set request.uuid 
    end 

    def unregister_request 
     $redis.unset request.uuid 
    end 
end 

Sie werden immer noch was brauchen, um herauszufinden, mit Ausnahmen zu tun, da after_filters übersprungenen sind (vielleicht diesen ganzen Code in eine Middleware bewegen: auf dem vor Phase der Middleware es die UUID schreibt Redis und auf dem nach der Phase entfernt es den Schlüssel). Es gibt eine Reihe von anderen Möglichkeiten, um dies zu erreichen, ich bin sicher, und ersetzen Sie Redis natürlich mit Ihrer bevorzugten Ausdauer der Wahl.

+0

Ich implementiere so etwas, aber es ist nicht vertrauenswürdig, weil die Anfrage kann sterben oder kann getötet werden (in einer System-Ebene) und die "Unset" -Signal wird nie gesendet. Dies liegt daran, dass ich eine externe Methode brauche, um zu wissen, ob eine Anfrage noch am Leben ist. – fguillen

+0

Ich bin so verloren wie du dann. Natürlich können Sie Zeitstempel auch bei Redis speichern und periodisch "alte" löschen, aber das wissen Sie wahrscheinlich schon. Lassen Sie mich wissen, wenn Sie mehr finden, es ist ein interessantes Problem! –

+0

Überprüfen Sie meine Antwort: http://StackOverflow.com/a/42227927/316700 – fguillen

Verwandte Themen