• Accueil / Salesforce / Orchestration et surveillance…
, Orchestration et surveillance des processus Apex avec des événements de plate-forme<span class="wtr-time-wrap after-title"><span class="wtr-time-number">10</span> minutes de lecture</span>

Orchestration et surveillance des processus Apex avec des événements de plate-forme10 minutes de lecture


Lorsqu’il s’agit d’implémenter des charges de travail asynchrones dans Apex, les développeurs ont un certain nombre d’options tel que Apex par lots et En file d’attente, chacun peut être piloté par des actions pilotées par l’utilisateur ou le système. Ce blog se concentre sur certains des aspects les plus avancés de l’implémentation de charges de travail asynchrones à l’aide de Événements de plate-forme et Apex.

Par rapport à d’autres approches, l’implémentation de charges de travail asynchrones à l’aide de Platform Events offre deux fonctionnalités uniques. Le premier vous aide à mieux calibrer et gérer dynamiquement les ressources en fonction des volumes de données pour rester dans les limites, tandis que la deuxième fonction fournit capacités de relance automatique en cas d’erreurs. Enfin, je veux souligner une approche que j’ai utilisée pour en ajouter télémétrie en temps réel personnalisée à la charge de travail à l’aide des événements de plate-forme.

Note latérale: Avant d’entrer dans les détails, le but de ce blog n’est pas de dire qu’une option asynchrone est meilleure qu’une autre, mais plutôt de mettre en évidence les fonctionnalités ci-dessus afin que vous puissiez mieux considérer vos options. J’inclus également une courte comparaison à la fin de ce blog avec Batch Apex.

Scénario d’affaires

Imaginons le scénario suivant pour illustrer l’utilisation des fonctionnalités décrites ci-dessous:

, Orchestration et surveillance des processus Apex avec des événements de plate-forme<span class="wtr-time-wrap after-title"><span class="wtr-time-number">10</span> minutes de lecture</span>

  • Processus d’affaires
    Imaginez que votre entreprise traite la génération de factures sur la plateforme et que les commandes qui en découlent arrivent et sont constamment mises à jour.
  • Traitement continu
    Afin d’éviter les arriérés ou les pics de factures en cours de traitement, vous souhaitez maintenir un flux continu du processus global. Pour cela, vous créez un événement de plate-forme appelé Générer une facture. Cet événement peut facilement être envoyé par un administrateur / constructeur déclaratif qui a peut-être configuré des règles sur l’objet Commandes à l’aide de Process Builder.
  • La gestion des ressources
    Les commandes arrivent dans toutes les formes et tailles, ce qui signifie que le traitement requis pour générer des factures peut également varier lorsque vous considérez des variables telles que le nombre de lignes de commande, les remises régionales des produits, les devises et les règles fiscales, etc. manière d’optimiser l’utilisation des ressources disponibles et est certainement une option, mais si les ressources le permettent, le traitement de plusieurs factures dans un contexte d’exécution est plus efficace.

Voici à quoi ressemble l’événement Generate Invoice Platform, il contient simplement une référence à l’ID de commande (bien qu’il puisse également faire référence à un Identifiant externe sur l’objet Order).

, Orchestration et surveillance des processus Apex avec des événements de plate-forme<span class="wtr-time-wrap after-title"><span class="wtr-time-number">10</span> minutes de lecture</span>

Pour les besoins de ce blog, nous ne nous concentrons pas sur la manière dont les événements sont envoyés / publiés. Vous pouvez publier des événements en utilisant des API programmatiques sur ou en dehors de la plate-forme ou en utilisant l’un des outils déclaratifs de la plate-forme, il existe en fait de nombreuses façons d’envoyer des événements. Pour ce blog, nous utiliserons simplement un extrait de code Apex de base pour générer les événements comme indiqué ci-dessous.

List events = new List();
for(Order order : 
       [select Id from Order 
          where Invoiced__c != true 
          order by OrderNumber asc]) {
   events.add(new GenerateInvoice__e(OrderId__c = order.Id));
}
EventBus.publish(events);        

Voici un gestionnaire Apex de base pour l’événement de plateforme ci-dessus qui délègue le traitement à une autre classe Apex:

trigger GenerateInvoiceSubscriber on GenerateInvoice__e (after insert) {
    Set orderIds = new Set();
    for (GenerateInvoice__e event : Trigger.New) {
        orderIds.add(event.OrderId__c);
    }
    OrderService.generateInvoices(orderIds);
}

Traitement de blocs d’événements et gestion des tentatives

Le diagramme suivant montre comment une version plus avancée du gestionnaire Apex ci-dessus peut être utilisée pour fonctionner de manière optimale dans les limites de processus morceaux des commandes en fonction de leur taille / complexité et aussi retenter ceux qui entraînent des erreurs en cours de route.

, Orchestration et surveillance des processus Apex avec des événements de plate-forme<span class="wtr-time-wrap after-title"><span class="wtr-time-number">10</span> minutes de lecture</span>

Pour orchestrer les choses de cette manière, vous devez utiliser certaines API Apex dans votre logique de gestionnaire pour informer la plate-forme de certaines choses. À la fin de ce blog, je partage également comment j’ai ajouté la télémétrie pour mieux visualiser cela avec une vidéo. Alors ne vous inquiétez pas à ce stade si ce n’est pas clair à 100% comment ce que vous voyez ci-dessous est possible, continuez simplement à lire et à regarder!

Contrôle du nombre d’événements passés à votre gestionnaire

Imaginez que l’extrait de code ci-dessus ait publié 1000 événements. La documentation de la plate-forme indique qu’elle peut transmettre jusqu’à un maximum de 2000 événements à un gestionnaire d’événements Apex à la fois, ce qui signifie que ce qui précède sera appelé une fois. Si vous êtes sur la plate-forme depuis un certain temps, vous saurez que 200 (et non 2000) est un nombre commun utilisé pour exprimer un nombre minimum d’enregistrements à utiliser lors du test des déclencheurs Apex et des meilleures pratiques de bulkkification. Alors pourquoi 2000 dans le cas des gestionnaires d’événements de plateforme? Eh bien, l’objectif principal de la plate-forme est de vider rapidement la file d’attente des messages d’événements de la plate-forme et tente donc de donner autant que possible au gestionnaire, juste au cas où il pourrait le traiter.

Comme nous l’avons exposé dans notre scénario ci-dessus, les commandes peuvent être de nature assez variable et donc, bien qu’un lot de 1000 commandes avec seulement quelques lignes de commande puisse être possible dans les limites d’exécution, inclure quelques commandes dans ce lot avec des centaines ou quelques mille éléments de campagne et il est plus probable que vous atteigniez les limites de processeur ou de segment de mémoire. Heureusement, contrairement à Batch Apex, vous pouvez contrôler la taille de chaque morceau individuel. Cela se fait en renvoyant une partie des 1000 blocs d’événements passés à votre gestionnaire à la plate-forme pour qu’ils les repassent dans un appel de gestionnaire séparé où les limites sont réinitialisées.

Vous trouverez ci-dessous un code de base qui illustre comment vous pouvez procéder à une pré-analyse des commandes pour déterminer la complexité (en nombre de lignes) et ainsi calibrer dynamiquement le nombre d’événements que votre code peut réellement traiter dans les limites. le orderIds La liste qui est passée à la classe de service est réinitialisée avec les commandes qui peuvent être traitées. L’élément clé ici est l’utilisation du Méthode setResumeCheckpoint qui indique à la plate-forme où reprendre une fois que ce gestionnaire a terminé son traitement.

trigger GenerateInvoiceSubscriber on GenerateInvoice__e (after insert) { 

    // Determine number overall order lines to process 
    //   vs maximum within limits (could be config)
    Integer maxLines = 40000;
    Set orderIds = new Set();
    for (GenerateInvoice__e event : Trigger.New) {
        orderIds.add(event.OrderId__c);
    }
    Map lineCountByOrderId = 
        new OrdersSelector().selectLineCountById(orderIds);

    // Bulkify events passed to the OrderService
    orderIds = new Set();
    Integer lineCount = 0;
    for (GenerateInvoice__e event : Trigger.New) {
        orderIds.add(event.OrderId__c);
        EventBus.TriggerContext.currentContext().setResumeCheckpoint(event.ReplayId);
        lineCount = lineCount + lineCountByOrderId.get(event.OrderId__c);
        if(lineCount>maxLines) { 
            break;
        }
    }

    OrderService.generateInvoices(orderIds);
}

Vous pouvez en savoir plus sur cette approche dans la documentation formelle ici.

Implémentation de la logique de nouvelle tentative

Il existe un certain nombre de raisons pour lesquelles des erreurs peuvent se produire lorsque votre code de gestionnaire est en cours d’exécution. Pour les erreurs qui représentent des situations transitoires, telles que les délais d’expiration et les verrous de ligne par exemple, vous devrez normalement demander à l’utilisateur de réessayer (par e-mail ou par notification) ou utiliser une tâche planifiée dynamiquement pour réessayer. Avec les gestionnaires d’événements de plate-forme dans Apex, lorsque le système RetryableException est lancé, la plate-forme réessayera automatiquement un lot d’événements après une période de temps, jusqu’à 9 fois (la taille des lots peut varier entre les tentatives). Il est généralement recommandé de ne pas laisser votre code réessayer au-dessus de 6, car lorsque le maximum est atteint, le la plate-forme désactive le gestionnaire / déclencheur.

Le code suivant est une illustration de base de l’utilisation de cette fonction et du suivi du nombre de tentatives avant d’atteindre le maximum. Dans cet exemple, si le maximum souple est atteint, les événements sont simplement perdus dans ce cas ou, si nécessaire, vous pouvez les écrire dans un objet personnalisé de préparation pour une nouvelle soumission ou simplement avoir du code tel que l’analyse ci-dessus pour les commandes non traitées et resoumettre les événements.

    // Invoke OrderService, support retries
    try {
        OrderService.generateInvoices(orderIds);
    } catch (Exception e) {
        // Only retry so many times, before giving up (thus avoid disabling the trigger)
        if (EventBus.TriggerContext.currentContext().retries 

Utilisation des événements de plate-forme pour surveiller l'activité

J'ai utilisé Platform Events pour publier des données de télémétrie sur l'exécution des gestionnaires ci-dessus, en créant un autre Platform Event appelé Télémétrie des abonnés et utilisé un Composant Web Lightning pour surveiller les événements en temps réel. Étant donné que les événements de plate-forme peuvent être déclarés comme étant en dehors de la transaction Apex standard, ils sont envoyés immédiatement à l'aide du paramètre «Publier immédiatement», ils sont envoyés même si une erreur se produit.

, Orchestration et surveillance des processus Apex avec des événements de plate-forme<span class="wtr-time-wrap after-title"><span class="wtr-time-number">10</span> minutes de lecture</span>

Pour publier dans cet événement, j'ai simplement ajouté l'extrait de code suivant en haut de mon gestionnaire.

// Emit telemetry
EventBus.publish(
    new SubscriberTelemetry__e(
        Topic__c = 'GenerateInvoice__e', 
        ApexTrigger__c = 'GenerateInvoiceSubscriber',
        Position__c = 
           [select Position from EventBusSubscriber
              where Topic = 'GenerateInvoice__e'][0].Position,
        BatchSize__c = Trigger.new.size(),
        Retries__c = EventBus.TriggerContext.currentContext().retries,
        LastError__c = EventBus.TriggerContext.currentContext().lastError));

La vidéo suivante me montre en cliquant sur un bouton pour publier un lot de 1000 événements, puis en surveillant les effets sur ma logique de segmentation et ma logique de nouvelle tentative. La vidéo comprend en fait la correction de certaines erreurs de données afin de mettre en évidence les capacités de nouvelle tentative. Les erreurs affichées sont provoquées par un code délibérément incorrect pour illustrer la logique de nouvelle tentative, par conséquent, le correctif des enregistrements de commande semble un peu étrange, veuillez donc l'ignorer. Enfin, notez que la plate-forme a choisi d'envoyer d'abord 83 événements à mon gestionnaire, puis des morceaux plus gros par la suite, mais dans d'autres tests, j'ai obtenu 1000 événements dans le premier bloc.

Événements par lots Apex vs Platform

Batch Apex fournit également un moyen d'orchestrer séquentiellement le traitement des enregistrements par blocs, j'ai donc pensé que je finirais ici par un résumé de certaines des autres différences. Comme vous pouvez le voir, l'un des éléments clés à prendre en compte est l'identité de l'utilisateur sous laquelle le code s'exécute. Cette solution de contournement n'est pas impossible dans le cas du gestionnaire d'événements de plate-forme, mais nécessite un certain codage pour définir explicitement le champ OwnerId sur les enregistrements si ces informations sont importantes pour vous. Dans l'ensemble, je pense que les événements de plate-forme offrent des options utiles pour passer à un mode de fonctionnement plus continu que par lots, à condition que vous soyez conscient des différences, cela pourrait vous convenir.

, Orchestration et surveillance des processus Apex avec des événements de plate-forme<span class="wtr-time-wrap after-title"><span class="wtr-time-number">10</span> minutes de lecture</span>

Note latérale: Pour Apex en file d'attente gestionnaires, vous aurez bientôt la possibilité d'implémenter ce que l'on appelle Finaliseurs de transaction qui vous permettent d'implémenter une logique de nouvelle tentative ou de journalisation.



Source de l'article traduit automatiquement en Français

Besoin d'aide ?
Voulez-vous utiliser Pardot à sa capacité maximale et avoir
+ DE LEADS QUALIFIÉS

Notre analyse de votre Pardot offerte dès aujourd'hui
Merci, vous pouvez compléter notre questionnaire
Nous allons revenir vers vous rapidement !

Fermer