2016-12-12 5 views
2

Ist es möglich, Anfragen asynchron an AWS zu senden? In der wirklichen Bedeutung.Asynchrone Anfrage an Amazon Firehose

Die Nachrichten wird nicht geliefert, wenn ich versuche, sie in einer Weise zu senden:

 $firehose = new FirehoseClient($args); 
     /** @var Promise\Promise $promise */ 
     $promise = $firehose->putRecordAsync($record); 
     $promise->then(function ($result) { 
      echo 'test'; 
     }); 

aber wenn ich am Ende des Skripts hinzu:

$promise->wait() 

es funktioniert, aber synchron. Gibt es eine Möglichkeit, es asynchron zu machen?

Ich habe auch versucht, einen anderen Handler zu verwenden:

$curl = new CurlMultiHandler(); 
    $handler = HandlerStack::create($curl); 
    $args = [ 
     'http_handler' => $handler, 
     'region' => '#REGION#', 
     'version' => 'latest', 
     'credentials' => $credentials, 
     'debug' => true 
    ]; 
    $firehose = new FirehoseClient($args); 

    while (!Promise\is_settled($promise)) { 
     $curl->tick(); 
    } 

Im Grunde funktioniert es, aber immer im Sync-Modus. Was ich brauche, ist eine Anfrage an AWS zu senden und nicht auf die Antwort zu warten.

+0

php nicht asynchron ist können Sie versuchen, Kaninchen mq mit oder irgendwie Ihr Skript über cron Rufwarteschlange mit – bxN5

+0

Ich weiß, dass PHP nicht async, aber es gibt eine curl Funktion: curl_multi_exec welche sollte eine Anfrage im Hintergrund senden können? Außerdem sollte ich die offizielle AWS-Dokumentation verstehen: https://docs.aws.amazon.com/aws-sdk-php/v3/guide/guide/promises.html. Es scheint, dass es eine Art von Async geben sollte. Bitte korrigieren Sie mich, falls ich falsch liege. – user1119698

+0

@Roman, es gibt eine Möglichkeit, asynchronen Code mit Event-Loops in PHP zu schreiben, nachdem Generatoren (Coroutinen) hinzugefügt wurden. –

Antwort

1

Die beste Lösung für Ihr Problem ist die Verwendung einer Event-Loop-Implementierung, wie zum Beispiel ReactPHP.

Leider ist Guzzle (besser gesagt, cURL selbst) nicht kompatibel, um in einer Event-Schleife sofort zu funktionieren.

Persönlich habe ich ein gleiches Problem durch die Implementierung eines bridge gelöst, um Guzzle-Abfragen Event-Loop-freundlich zu laufen. Bitte werfen Sie einen Blick auf the examples.

So könnte der Code wie folgt aussehen:

run(function ($loop) use ($genFn) { 
    $httpHandler = new CurlMultiHandler($loop); 
    $stack = HandlerStack::create($httpHandler); 

    $httpClient = new Client([ 
     'handler' => $stack, 
    ]); 

    $promise = $httpClient->getAsync('https://google.com')->then(
     function ($result) { echo 'Query completed!'; }, 
     function ($reason) { echo 'Query failed.'; } 
    ); 

    /* 
    * The promise isn't completed yet, but the event loop will take care of it. 
    * We don't need to call Promise::wait()! 
    */ 
}); 
+0

Es scheint besser als Standard warten(), aber meiner Meinung nach ist es nicht vollständig async. Wenn Sie eine Druckfunktion (zB "TEST") an der und der run() -Funktion platzieren, können Sie sehen, dass es einige Zeit wartet, um es zu drucken. Korrigieren Sie mich, wenn ich falsch liege. Ich möchte nur ein Stück schicken von Daten zu Amazon Firehose und ich möchte keine Zeit verschwenden Prozess/Anfrage senden, aber ich fühle, dass auch auf diese Weise am Ende von run() Prozess wartet das Skript für einige Zeit, um alle Daten zu senden. – user1119698

0

Ich habe nicht mit Async-Code in PHP gearbeitet, aber ich habe solche Dinge in Python.

Aus allgemeiner Sicht können Sie keine Vorteile einer einzelnen Async-Anfrage erhalten, die vom Synchronisierungscode umgeben ist. Sie sollten in einer vollständig asynchronen Umgebung arbeiten (d. H. Sie benötigen eine Art äußere Ereignisschleife). ReactPHP scheint einer von denen zu sein.

Sie können auch davon profitieren, mehrere API-Anfragen gleichzeitig zu machen und auf alle zusammen zu warten. Wie in diesem Beispiel http://docs.aws.amazon.com/aws-sdk-php/v3/guide/guide/promises.html#executing-commands-concurrently Es wird schneller arbeiten als mehrere Synchronisierungsaufrufe hintereinander.

Ich hoffe es hilft.

Verwandte Themen