Promesses de la AWS SDK for PHP version 3 - AWS SDK for PHP

Les traductions sont fournies par des outils de traduction automatique. En cas de conflit entre le contenu d'une traduction et celui de la version originale en anglais, la version anglaise prévaudra.

Promesses de la AWS SDK for PHP version 3

Le kit AWS SDK for PHP utilise les promesses pour permettre les flux de travail asynchrones. Cette asynchronicité rend possible l’envoi simultané de demandes HTTP. La spécification de promesse utilisée par le kit SDK est Promesses/A+.

Qu'est-ce qu'une promesse ?

Une promesse représente le résultat final d’une opération asynchrone. Le principal moyen d'interagir avec une promesse est via sa méthode then. Cette méthode enregistre les rappels pour recevoir la valeur finale d'une promesse ou la raison pour laquelle la promesse ne peut pas être exécutée.

Le kit AWS SDK for PHP s’appuie sur le package Composer guzzlehttp/promesses pour son implémentation de promesses. Les promesses Guzzle prennent en charge les flux de travail bloquants et non bloquants, et peuvent être utilisées avec n'importe quelle boucle d'événements non bloquants.

Note

Les demandes HTTP sont envoyées simultanément dans le kit AWS SDK for PHP à l'aide d'un seul thread, dans lequel les appels non bloquants sont utilisés pour transférer une ou plusieurs demandes HTTP tout en réagissant aux changements d'état (par exemple : exécution ou rejet de promesses).

Promesses dans le kit SDK

Les promesses sont utilisées dans l'ensemble du kit SDK. Par exemple, les promesses sont utilisées dans la plupart des abstractions de haut niveau fournies par le kit SDK : les programmes de pagination, les programmes d’attente, les groupes de commande, les chargements partitionnés, les transferts de répertoires/de compartiments S3, etc.

Tous les clients fournis par le kit SDK renvoient des promesses lorsque vous appelez l'une des méthodes suffixées Async. Par exemple, le code suivant montre comment créer une promesse pour obtenir les résultats d'une opération Amazon DescribeTable DynamoDB.

$client = new Aws\DynamoDb\DynamoDbClient([ 'region' => 'us-west-2', 'version' => 'latest', ]); // This will create a promise that will eventually contain a result $promise = $client->describeTableAsync(['TableName' => 'mytable']);

Notez que vous pouvez appeler describeTable ou describeTableAsync. Ces méthodes sont des méthodes __call magiques utilisées sur un client et alimentées par le modèle d'API et le numéro version associé au client. En appelant des méthodes telles que describeTable sans le suffixe Async, le client se bloquera pendant l'envoi d'une demande HTTP et renverra un objet Aws\ResultInterface ou lèvera une Aws\Exception\AwsException. En ajoutant le suffixe Async au nom de l'opération (c.-à-d. describeTableAsync), le client créera une promesse qui sera exécutée avec un objet Aws\ResultInterface ou rejetée avec un Aws\Exception\AwsException.

Important

Lorsque la promesse est renvoyée, le résultat est peut-être déjà arrivé (par exemple, lors de l'utilisation d'un gestionnaire fictif), ou la demande HTTP n'a peut-être pas été initiée.

Vous pouvez enregistrer un rappel avec la promesse en utilisant la méthode then. Cette méthode accepte deux rappels, $onFulfilled et $onRejected, tous deux facultatifs. Le rappel $onFulfilled est appelé si la promesse est exécutée, et le rappel $onRejected est appelé si la promesse est rejetée (c.-à-d. en cas d'échec).

$promise->then( function ($value) { echo "The promise was fulfilled with {$value}"; }, function ($reason) { echo "The promise was rejected with {$reason}"; } );

Exécution simultanée de commandes

Plusieurs promesses peuvent être composées conjointement de manière à être exécutées simultanément. Cette action peut être réalisée en intégrant le kit SDK à une boucle d'événements non bloquants, ou en générant plusieurs promesses et en attendant qu'elles se terminent simultanément.

use GuzzleHttp\Promise\Utils; $sdk = new Aws\Sdk([ 'version' => 'latest', 'region' => 'us-east-1' ]); $s3 = $sdk->createS3(); $ddb = $sdk->createDynamoDb(); $promises = [ 'buckets' => $s3->listBucketsAsync(), 'tables' => $ddb->listTablesAsync(), ]; // Wait for both promises to complete. $results = Utils::unwrap($promises); // Notice that this method will maintain the input array keys. var_dump($results['buckets']->toArray()); var_dump($results['tables']->toArray());
Note

CommandPoolIl fournit un mécanisme plus puissant pour exécuter plusieurs opérations d'API simultanément.

Enchaîner des promesses

L'un des principaux avantages des promesses est qu'elles sont composables, vous permettant ainsi de créer des pipelines de transformation. Les promesses sont composées en créant des chaînes de rappels then, suivis de rappels then. La valeur de retour d'une méthode then est une promesse qui est exécutée ou rejetée en fonction du résultat des rappels fournis.

$promise = $client->describeTableAsync(['TableName' => 'mytable']); $promise ->then( function ($value) { $value['AddedAttribute'] = 'foo'; return $value; }, function ($reason) use ($client) { // The call failed. You can recover from the error here and // return a value that will be provided to the next successful // then() callback. Let's retry the call. return $client->describeTableAsync(['TableName' => 'mytable']); } )->then( function ($value) { // This is only invoked when the previous then callback is // fulfilled. If the previous callback returned a promise, then // this callback is invoked only after that promise is // fulfilled. echo $value['AddedAttribute']; // outputs "foo" }, function ($reason) { // The previous callback was rejected (failed). } );
Note

La valeur de retour d'un rappel de promesse est l'argument $value fourni aux promesses en aval. Si vous souhaitez fournir une valeur aux chaînes de promesses en aval, vous devez renvoyer une valeur dans la fonction de rappel.

Transfert des refus

Vous pouvez enregistrer un rappel à appeler lorsqu'une promesse est rejetée. Si une exception est levée dans un rappel, la promesse est rejetée avec l'exception et les promesses suivantes de la chaîne sont rejetées avec l'exception. Si une valeur est renvoyée à partir d'un rappel $onRejected, les promesses suivantes de la chaîne de promesse sont exécutées avec la valeur de retour du rappel $onRejected.

En attente de promesses

Vous pouvez forcer des promesses à s'exécuter de manière synchrone en utilisant la méthode wait d'une promesse.

$promise = $client->listTablesAsync(); $result = $promise->wait();

Si une exception se produit lors de l'appel de la fonction wait d'une promesse, la promesse est rejetée avec l'exception et l'exception est levée.

use Aws\Exception\AwsException; $promise = $client->listTablesAsync(); try { $result = $promise->wait(); } catch (AwsException $e) { // Handle the error }

L'appel de la méthode wait d'une promesse qui a été exécutée ne déclenche pas la fonction wait. Cela renvoie simplement la valeur précédemment fournie.

$promise = $client->listTablesAsync(); $result = $promise->wait(); assert($result ### $promise->wait());

Appeler la méthode wait d'une promesse qui a été rejetée lève une exception. Si la raison du rejet est une instance de \Exception, la raison est levée. Sinon, une GuzzleHttp\Promise\RejectionException est levée et la raison peut être obtenue en appelant la méthode getReason de l'exception.

Note

Les appels d’opérations d’API dans le kit AWS SDK for PHP sont rejetés avec les sous-classes de la classe Aws\Exception\AwsException. Toutefois, la raison fournie à une méthode then peut être différente en raison de l'ajout d'un intergiciel personnalisé modifiant une raison de rejet.

Annulation de promesses

Les promesses peuvent être annulées à l'aide de la méthode cancel() d'une promesse. Si une promesse a déjà été résolue, appeler cancel() n'aura aucun effet. L'annulation d'une promesse annule la promesse et toutes les promesses en attente de la livraison de la promesse. Un promesse annulée est rejetée avec une GuzzleHttp\Promise\RejectionException.

Combiner les promesses

Vous pouvez combiner des promesses dans des promesses agrégées afin de créer des flux de travail plus sophistiqués. Le package guzzlehttp/promise contient différentes fonctions que vous pouvez utiliser pour combiner des promesses.

Vous pouvez trouver la documentation de l'API pour toutes les fonctions de collecte de promesses sur namespace- GuzzleHttp .Promise.

each et each_limit

Utilisez les Aws\CommandInterface commandes CommandPoollorsque vous avez une file d'attente de tâches à exécuter simultanément avec une taille de pool fixe (les commandes peuvent être stockées en mémoire ou produites par un itérateur paresseux). Le CommandPool veille à ce qu'un nombre fixe de commandes soit envoyées simultanément jusqu'à ce que l'itérateur fourni soit épuisé.

Le CommandPool fonctionne uniquement avec les commandes exécutées par le même client. Vous pouvez utiliser la fonction GuzzleHttp\Promise\each_limit pour effectuer des commandes d'envoi de différents clients simultanément avec une taille de groupe fixe.

use GuzzleHttp\Promise; $sdk = new Aws\Sdk([ 'version' => 'latest', 'region' => 'us-west-2' ]); $s3 = $sdk->createS3(); $ddb = $sdk->createDynamoDb(); // Create a generator that yields promises $promiseGenerator = function () use ($s3, $ddb) { yield $s3->listBucketsAsync(); yield $ddb->listTablesAsync(); // yield other promises as needed... }; // Execute the tasks yielded by the generator concurrently while limiting the // maximum number of concurrent promises to 5 $promise = Promise\each_limit($promiseGenerator(), 5); // Waiting on an EachPromise will wait on the entire task queue to complete $promise->wait();

Coroutines prometteuses

La bibliothèque de promesses Guzzle propose une fonction particulièrement puissante qui autorise l'utilisation des coroutines de promesses rendant l'écriture de flux de travail asynchrones plus semblable à celle de flux de travail synchrones classiques. En effet, le kit AWS SDK for PHP utilise les promesses de coroutine dans la plupart des abstractions de haut niveau.

Supposons que vous souhaitiez créer plusieurs compartiments, charger un fichier dans le compartiment une fois ce dernier disponible et effectuer ces actions simultanément pour bénéficier d'un processus aussi rapide que possible. Pour ce faire, combinez simplement plusieurs promesses de coroutine à l'aide de la fonction de promesse all().

use GuzzleHttp\Promise; $uploadFn = function ($bucket) use ($s3Client) { return Promise\coroutine(function () use ($bucket, $s3Client) { // You can capture the result by yielding inside of parens $result = (yield $s3Client->createBucket(['Bucket' => $bucket])); // Wait on the bucket to be available $waiter = $s3Client->getWaiter('BucketExists', ['Bucket' => $bucket]); // Wait until the bucket exists yield $waiter->promise(); // Upload a file to the bucket yield $s3Client->putObjectAsync([ 'Bucket' => $bucket, 'Key' => '_placeholder', 'Body' => 'Hi!' ]); }); }; // Create the following buckets $buckets = ['foo', 'baz', 'bar']; $promises = []; // Build an array of promises foreach ($buckets as $bucket) { $promises[] = $uploadFn($bucket); } // Aggregate the promises into a single "all" promise $aggregate = Promise\all($promises); // You can then() off of this promise or synchronously wait $aggregate->wait();