Modèles - Exécution parallèle

Vue d'ensemble

L'exécution parallèle permet aux services d'invoquer un nombre arbitraire d'autres services en fournissant un ensemble de services de rappel à exécuter après l'achèvement de chacune des cibles.

Les services cibles s'exécutent en parallèle, de manière asynchrone, et ne sont pas informés de la progression de l'exécution des autres services. Tous les services de rappel configurés s'exécutent également de manière asynchrone sans se bloquer mutuellement.

Le schéma ci-dessous illustre la fonctionnalité dans toute sa portée. Trois services cibles sont exécutés, chacun s'exécute indépendamment, chacun avec une liste de ses callbacks d'achèvement.

Exemples d'utilisation et API

Usage courant

Dans le cas le plus courant, l'utilisation sera la suivante. Un dictionnaire contenant les cibles et leurs requêtes ainsi qu'une liste de callbacks est fourni à self.patterns.parallel.invoke. Toutes les cibles sont invoquées en arrière-plan et, une fois qu'elles sont toutes terminées, chacun des callbacks est invoqué.

from zato.server.service import Service

class MyService(Service):

    def handle(self):

        # A dictionary of services to invoke along with requests they receive
        targets = {
            'service1': {'hello':'from-parallel-exec1'},
            'service2': {'hello':'from-parallel-exec2'},
        }

        # Callbacks to invoke when each of the services finishes
        callbacks = ['my.callback1', 'my.callback2']

        # On output a Correlation ID assigned to the call is returned
        cid = self.patterns.parallel.invoke(targets, callbacks)

ID de corrélation définis par l'utilisateur

Les utilisateurs peuvent fournir leurs propres ID de corrélation pour invoquer les services. Il est de la responsabilité de l'utilisateur de s'assurer que les ID sont suffisamment nombreux et qu'il n'y aura pas de doublons, si cela se produit - les résultats sont indéfinis.

from zato.server.service import Service

class MyService(Service):

    def handle(self):

        # A dictionary of services to invoke along with requests they receive
        targets = {
            'service1': {'hello':'from-parallel-exec1'},
            'service2': {'hello':'from-parallel-exec2'},
        }

        # Callbacks to invoke when both services above finish
        callbacks = ['my.callback1', 'my.callback2']

        # User-provided Correlation ID
        cid = '1632-5754-5628-5197'

        # CID returned is the one received on input
        cid = self.patterns.parallel.invoke(targets, callbacks, cid=cid)

Création de callbacks

Un callback est un service Zato ordinaire qui est invoqué après la fin de l'exécution de chacune des cibles, peu importe si l'une d'entre elles lève une exception ou non.

Chaque callback est invoqué de manière asynchrone, indépendamment de tout autre callback défini.

Lors de l'exécution, l'attribut self.channel de chaque callback sera défini à PARALLEL_EXEC_ON_TARGET.

En entrée, l'attribut self.request.payload d'une callback sera un dictionnaire Python - le format du dictionnaire est le même que dans self.patterns.fanout.invoke.

Similitudes avec Fan-out/Fan-in

Cette fonctionnalité est très similaire au modèle Fan-out/Fan-in - en plus des rappels sur cible de l'exécution parallèle, Fan-out/Fan-in ajoute des rappels qui ne sont exécutés que lorsque toutes les cibles sont terminées.