2010-03-31 4 views
19

In Thrift ist es möglich, use the oneway modifier einen Anruf als asynchron zu spezifizieren.Rückrufe in Thrift Asynchronous Functions?

Scheinbar ist es nicht möglich, einen Callback zu definieren, der ausgeführt werden soll, wenn die Ausführung der Funktion abgeschlossen ist.

Es scheint, dass die einzige Möglichkeit, die ich habe, ist, meinem Thrift-Client (PHP) einige "Server" -Fähigkeiten, so dass, wenn die schwere Berechnung auf der Serverseite abgeschlossen ist, kann ich eine Benachrichtigung senden . Dies bedeutet, dass ich eine neue .Thrift-Datei mit neuen Definitionen, neuen Diensten und dem ganzen Rest haben sollte und dass ich php-serverseitigen Code mit Thrift erzeugen sollte.

Auch wenn dies machbar ist, sieht es für mich wie ein Overkill aus und ich frage mich, ob es eine cleverere Möglichkeit gibt, den Callback zu implementieren.

Ich freue mich auf ein Feedback von Ihnen, Jungs.

Antwort

19

Roberto, leider hat das Thrift-Framework keine solche eingebaute Funktionalität. Dort kann eine Reihe von Alternativen sein, abhängig davon, was Ihre PHP-Client-Sitzung während der Zeit tun soll, die Sie normalerweise auf den rechenintensiven Thrift-Server gewartet hätten (wenn Sie nicht oneway verwendet hätten.)

Ich kann mir vorerst vorstellen, dass Sie sich in einer Situation befinden, in der Sie, nachdem Sie eine Webanwendung programmiert haben, bei der ein Benutzer (oder mehrere Benutzer parallel) jeweils eine rechenintensive Aufgabe auslösen können besagte Benutzer, während die Aufgaben weiterlaufen.

Von Anfang an haben Sie absolut recht, wenn Sie versuchen, die Lösung zu vermeiden, die Sie vermeiden möchten. Ihre PHP-Client-Sitzungen keine Callback-Schnittstelle, ohne blockieren bedienen kann (es sei denn, Sie Ihr Loch graben tiefer sogar, indem Sie versuchen pcntl_fork oder eine andere PHP threading band-aid zu verwenden.)

Die einfachste und IMHO beste Ausweg aus dieser ist zwei Schalter aus ein ereignisgesteuertes Modell (ich mag benachrichtigt werden, wenn der Server erfolgt) zu einem Wahlmodell (ich mit dem Server regelmäßig erkundigen, ob es erfolgt.) Es gibt mehrere Möglichkeiten, ein Abrufmodell Implementierung mit mehreren Implementierungsoptionen auf dem Server als auch auf den Client-Seiten, wie zB:

  1. während der Aufrufphase:

    • die Die PHP-Client-Sitzung weist einen eindeutigen Wert job_id zu; die Sitzung macht dann den asynchronen oneway Aufruf void compute(..., job_id) auf die rechenintensiven Thrift Server,

    - oder -

    • die PHP-Client-Sitzung macht einen synchronen Aufruf job_id start_compute(...) zu der rechenintensive Thrift-Server; der Server weist den einzigartigen job_id Wert, laicht dann die eigentliche rechenintensive Aufgabe in einem separaten Thread/Ablauf, direkt an den Sitzungs PHP Client zurückgegeben mit den zugeordneten job_id
  2. während der Berechnungsphase:

    • der PHP-Client-Sitzung Erlös den Status der rechenintensiven Arbeit über einen synchronenstatus get_status(job_id) Aufruf der rechenintensiven Thrift Server in regelmäßigen Abstände zu überprüfen,

    - oder -

    • die PHP-Client-Sitzung, um sofort beendet wertvolle Ressourcen freizugeben, nach dem Einschalten der job_id an den Browser vorbei und auch den Browser anweist Überprüfen Sie regelmäßig den Status des rechenintensiven Jobs job_id (z. B. über META REFRESH, oder über eine XHR (AJAX) Anfrage von Javascript, etc.); der Browsercheck laicht eine kurze PHP-Client-Sitzung, die die synchronenstatus get_status(job_id) Aufruf der rechenintensiven Thrift-Server führt, endet unmittelbar nach dem Status Weiterleitung auf
    • an den Browser (was auch immer es sein mag)
+2

Diese Art von Ansatz scheint für C++ - Client/Server auch notwendig zu sein – Ghita

8

Ich habe eine Antwort auf einen anderen Kanal als Stack Overflow erhalten. Da der Autor mir die Erlaubnis gab, hier seine Antwort zu veröffentlichen, dachte ich, dass es für jemand anderen in der Gemeinschaft nützlich sein könnte.

Hey Robert,

Ja, hat dies vor Listen auf dem Apache kommen. Es gibt keine elegante Möglichkeit zu tun, was Sie mit Thrift verlangen. Es ist im Grunde nicht für bidirektionale Messaging konzipiert.

Es gibt Hacks, um diesen, wie zum Beispiel: - clientseitige Polling - Aufruf send_method() auf der Client-Seite warten, dann recv_method(), statt nur Methode() - auch den Client machen Implementieren Sie einen Thrift-Server

Aber offensichtlich keiner von diesen ist wahr bidirektionale Messaging. Wir haben versucht , um die Thrift-Schnittstellen als so einfach wie möglich zu halten und konzentrierte sich auf den Kern RPC Anwendungsfall, der bedeutet, einige Sachen wie diese aus.

Wahrscheinlich nicht die Antwort, die Sie waren Hoffnung für.

Cheers, mcslee

0

Nun Java Asynchronous Nachricht hat Anrufe durch Verweis Zukunft Gegenstand. Dies kann in einem RPC-Modell unter Verwendung von Message Pack implementiert werden. Ich bin mir nicht sicher, ob PHP etwas ähnliches hat.

3

Anstatt zu versuchen Callbacks mit Thrift zu implementieren (etwas, das das Protokoll erheblich schwerer gemacht hätte, schätze ich), benutze ich einen leichtgewichtigen Nachrichtendienst (STOMP - http://stomp.github.com), um den Client über asynchrone Ereignisse zu informieren.

Mein Ansatz ist, dass der Thrift-Client einen bestimmten STOMP-Kanal abonniert, und der Thrift-Server wird immer dann auf demselben Kanal senden, wenn ein asynchrones Ereignis auftritt. Der Client kann dann den Server nach zusätzlichen Informationen über das Ereignis abfragen.