Article
· 16 hr il y a 5m de lecture

L'interopérabilité Python: mise à jour du support des opérations asynchrones

Cela fait longtemps que je n'ai pas écrit de post de mise à jour sur l'IoP.

image

Quelles sont les nouveautés depuis la publication de l'interface en ligne de commande de l'IoP?

Deux nouvelles fonctionnalités importantes ont été ajoutées à l'IoP:
- Rebranding: le module grongier.pex a été renommé en iop pour refléter le nouveau nom du projet.
- Support des opérations asynchrones: L'interface de programmation prend désormais en charge les fonctions asynchrones et les coroutines.

Rebranding

Le module grongier.pex a été renommé en iop pour refléter le nouveau nom du projet.

Le module grongier.pex est encore disponible pour des raisons de rétrocompatibilité, mais il sera supprimé à l'avenir.

Support des opérations asynchrones

L'IoP supporte les appels asynchrones depuis longtemps, mais il n'était pas possible d'utiliser les fonctions asynchrones et les coroutines directement dans l'IoP..

Avant d'aborder cette nouvelle fonctionnalité, je vais expliquer le fonctionnement des appels asynchrones dans InterSystems IRIS et présenter deux exemples d'utilisation des appels asynchrones dans l'IoP.

Appels asynchrones hérités

Examinons le fonctionnement des appels asynchrones hérités du passé:

from iop import BusinessProcess
from msg import MyMessage


class MyBP(BusinessProcess):

    def on_message(self, request):
        msg_one = MyMessage(message="Message1")
        msg_two = MyMessage(message="Message2")

        self.send_request_async("Python.MyBO", msg_one,completion_key="1")
        self.send_request_async("Python.MyBO", msg_two,completion_key="2")

    def on_response(self, request, response, call_request, call_response, completion_key):
        if completion_key == "1":
            self.response_one = call_response
        elif completion_key == "2":
            self.response_two = call_response

    def on_complete(self, request, response):
        self.log_info(f"Received response one: {self.response_one.message}")
        self.log_info(f"Received response two: {self.response_two.message}")

En fait, ils fonctionnent de la même manière que les appels asynchrones dans IRIS. La méthode send_request_async envoie une requête à une opération métier (Business Operation) et la méthode on_response est appelée lorsque la réponse est reçue.

Vous pouvez distinguer les réponses par le paramètre completion_key.

Envoi de plusieurs requête de synchronisation

Il ne s'agit pas vraiment d'une nouvelle fonctionnalité, mais il convient de mentionner qu'il est possible d'envoyer plusieurs requêtes de synchronisation en parallèle:

from iop import BusinessProcess
from msg import MyMessage


class MyMultiBP(BusinessProcess):

    def on_message(self, request):
        msg_one = MyMessage(message="Message1")
        msg_two = MyMessage(message="Message2")

        tuple_responses = self.send_multi_request_sync([("Python.MyMultiBO", msg_one),
                                                        ("Python.MyMultiBO", msg_two)])

        self.log_info("All requests have been processed")
        for target,request,response,status in tuple_responses:
            self.log_info(f"Received response: {response.message}")

Ici, nous envoyons deux requêtes à la même opération métier (Business Operation) en parallèle.

La réponse est un tuple contenant la cible, la requête, la réponse et le statut de chaque appel.

C'est très utile lorsque vous devez envoyer plusieurs requêtes et que vous ne vous souciez pas de l'ordre des réponses.

Fonctions asynchrones et coroutines

Voyons maintenant comment utiliser les fonctions asynchrones et les coroutines dans l'IoP:

import asyncio

from iop import BusinessProcess
from msg import MyMessage


class MyAsyncNGBP(BusinessProcess):

    def on_message(self, request):

        results = asyncio.run(self.await_response(request))

        for result in results:
            print(f"Received response: {result.message}")

    async def await_response(self, request):
        msg_one = MyMessage(message="Message1")
        msg_two = MyMessage(message="Message2")

        # utilisation d'asyncio.gather pour envoyer plusieurs requêtes de manière asynchrone
        # utilisation de la méthode send_request_async_ng
        tasks = [self.send_request_async_ng("Python.MyAsyncNGBO", msg_one),
                 self.send_request_async_ng("Python.MyAsyncNGBO", msg_two)]

        return await asyncio.gather(*tasks)

Dans cet exemple, nous envoyons plusieurs demandes à la même opération métier (Business Operation) en parallèle à l'aide de la méthode send_request_async_ng.

Si vous avez lu attentivement ce post jusqu'à ce point, veuillez ajouter le commentaire "Boomerang". C'est peut-être peu de choses pour vous, mais pour moi c'est très important. Je vous remercie!

La méthode await_response est une coroutine qui envoie plusieurs requêtes et attend que toutes les réponses soient reçues.
Grâce à la fonction asyncio.gather, nous pouvons attendre que toutes les réponses soient reçues en parallèle.

Les avantages de l'utilisation des fonctions asynchrones et des coroutines sont les suivants :

  • Meilleures performances: vous pouvez envoyer plusieurs requêtes en parallèle.
  • Simplicité de lecture et de maintenance: vous pouvez utiliser le mot-clé await pour attendre les réponses.
  • Plus de flexibilité: vous pouvez utiliser le module asyncio pour créer des flux de travail complexes.
  • Plus de contrôle: vous pouvez utiliser le module asyncio pour gérer les exceptions et les timeouts.

Conclusion

Quelle est la différence entre send_request_async, send_multi_request_sync et send_request_async_ng?

  • send_request_async: envoie une requête à une opération métier (Business Operation) et attend la réponse si la méthode on_response est implémentée et le paramètre completion_key est utilisé.
    • avantage: vous pouvez utiliser les appels asynchrones comme vous en avez l'habitude.
    • inconvénient: il peut être difficile à maintenir si vous avez besoin d'envoyer plusieurs requêtes en parallèle.
  • send_multi_request_sync : envoie plusieurs requêtes à la même opération métier (Business Operation) en parallèle et attend que toutes les réponses soient reçues.
    • avantage: facile à utiliser.
    • inconvénient: vous ne pouvez pas contrôler l'ordre des réponses (c'est-à-dire que la liste des réponses n'est pas ordonnée).
  • send_request_async_ng: envoie plusieurs requêtes à la même opération métier (Business Operation) en parallèle et attend que toutes les réponses soient reçues.
    • avantage: vous pouvez contrôler l'ordre des réponse.
    • inconvénient : vous devez utiliser des fonctions asynchrones et des coroutines.

Joyeux multitraitement!

Discussion (0)0
Connectez-vous ou inscrivez-vous pour continuer