Suivez votre progression
Accueil Trailhead
Accueil Trailhead

Utilisation d'un Apex asynchrone

Objectifs de formation

Une fois cette unité terminée, vous pourrez :

  • Déterminer quand utiliser le langage Apex asynchrone
  • Utiliser des méthodes futures pour gérer un appel externe Web
  • Travailler avec une interface de traitement par lot pour traiter un grand nombre d'enregistrements
  • Comprendre les avantages de l'utilisation de l'interface pour file d'attente à mi-chemin

Recours à la programmation asynchrone

En tant que développeur .NET, vous avez probablement été confronté(e) à la programmation asynchrone. Nous supposons que vous savez de quoi il s'agit et que vous comprenez les avantages de l'utilisation de ce type de modèle de programmation. Peut-être ignorez-vous quand la programmation asynchrone doit être utilisée sur la plate-forme Lightning.

Le choix de la programmation asynchrone est généralement motivé par les trois situations suivantes :

  • Traitement d'un grand nombre d'enregistrements. Cette situation est unique à l'univers mutualisé de la plate-forme Lightning, dans lequel les limites décident. Les limites associées aux processus asynchrones sont supérieures à celles des processus synchrones. Par conséquent, si vous devez traiter des milliers voire des millions d'enregistrements, le processus asynchrone est le meilleur choix.

  • Appels externes vers des services Web externes. Le traitement des appels externes peut être long, mais sur la plate-forme Lightning, les déclencheurs peuvent effectuer directement des appels externes.

  • Création d'une expérience utilisateur plus efficace et plus rapide en déchargeant une partie du traitement vers des appels asynchrones. Pourquoi tout faire en une seule fois ? Si une tâche peut attendre, laissez-la patienter.

Méthodes futures

Lorsque vous devez effectuer un appel externe vers un service Web ou décharger un traitement simple vers une tâche asynchrone, la création d'une méthode future peut représenter la meilleure solution.

Modifier une méthode depuis un traitement synchrone vers un traitement asynchrone est extrêmement aisé. Il suffit principalement d'ajouter l'annotation @future à votre méthode. Pour le reste, assurez-vous seulement que la méthode est statique et renvoie uniquement un type void. Par exemple, pour créer une méthode d'exécution d'un appel externe vers un service Web, vous pouvez utiliser une méthode semblable à :

public class MyFutureClass {
    // Include callout=true when making callouts
    @future(callout=true)    
    static void myFutureMethod(Set<Id> ids) {

        // Get the list of contacts in the future method since
        // you cannot pass objects as arguments to future methods
        List<Contact> contacts = [SELECT Id, LastName, FirstName, Email
            FROM Contact WHERE Id IN :ids];

        // Loop through the results and call a method
        // which contains the code to do the actual callout
        for (Contact con: contacts) {
            String response = anotherClass.calloutMethod(con.Id,
                con.FirstName,
                con.LastName,
                con.Email);

            // May want to add some code here to log
            // the response to a custom object
        }
    }
}

Vous pouvez ensuite l'appeler comme n'importe quelle autre méthode statique. Rien de sorcier !

Limitations futures

Les méthodes futures existent depuis plusieurs années. Elles offrent aux développeurs Salesforce des possibilités intéressantes, mais présentent aussi des inconvénients. Avant d'utiliser une méthode future, considérez les limitations ci-dessous.

  • Vous ne pouvez pas suivre l'exécution, car aucun ID de tâche Apex n'est renvoyé.
  • Les paramètres doivent être des types de données primitifs, des groupes de types de données primitifs ou des collections de types de données primitifs. Les méthodes futures ne peuvent pas accepter des objets en tant qu’arguments.
  • Vous ne pouvez pas enchaîner les méthodes futures et elles ne peuvent pas s'appeler mutuellement.

Bien que les appels asynchrones soient parfois configurés pour éviter les limitations, tenez compte de ces limitations. Suivez le lien Execution Governors and Limits dans la section Ressources.

Apex par lot ou planifié

Un autre outil asynchrone utilisé depuis longtemps est l'interface de traitement par lot. Elle est utilisée principalement lorsque vous devez traiter un grand nombre d'enregistrements. Par exemple, si vous devez mettre à jour ou archiver jusqu'à 50 millions d'enregistrements, l'interface de traitement par lot est la solution. Vous pouvez même planifier l'exécution de vos lots à une heure spécifique.

Pour l'utiliser, votre classe implémente l'interface Database.Batchable. Vous pouvez également définir des méthodes start(), execute() et finish(). Vous pouvez même invoquer une classe par lot en utilisant la méthode Database.executeBatch. Par exemple, le code suivant crée une classe qui traite par lot tous les comptes d'une organisation, puis envoie un e-mail une fois l'opération terminée.

global class MyBatchableClass implements
            Database.Batchable<sObject>,
            Database.Stateful {  

    // Used to record the total number of Accounts processed
    global Integer numOfRecs = 0;

    // Used to gather the records that will be passed to the interface method
    // This method will only be called once and will return either a
    // Database.QueryLocator object or an Iterable that contains the records
    // or objects passed to the job.            
    global Database.QueryLocator start(Database.BatchableContext bc) {
        return Database.getQueryLocator('SELECT Id, Name FROM Account');                
    }

    // This is where the actual processing occurs as data is chunked into
    // batches and the default batch size is 200.
    global void execute(Database.BatchableContext bc, List<Account> scope) {
        for (Account acc : scope) {
            // Do some processing here
            // and then increment the counter variable
            numOfRecs = numOfRecs + 1;
        }     
    }

    // Used to execute any post-processing that may need to happen. This
    // is called only once and after all the batches have finished.
    global void finish(Database.BatchableContext bc) {
        EmailManager.sendMail('someAddress@somewhere.com',
                              numOfRecs + ' Accounts were processed!',
                              'Meet me at the bar for drinks to celebrate');            
    }

}

Vous pouvez même invoquer la classe par lot en utilisant le code anonyme tel que :

MyBatchableClass myBatchObject = new MyBatchableClass();
Database.executeBatch(myBatchObject);
Note

Remarque

Nous n'avons pas abordé dans cette unité l'Apex planifié, mais sachez qu'il est semblable à l'interface de traitement par lot. Il implémente l'interface planifiable et vous pouvez l'utiliser pour invoquer un code Apex à des heures spécifiques. Pour en savoir plus, suivez le module Asynchronous Apex.

Limitations du traitement par lot

L'interface de traitement par lot est très pratique, mais comme pour les autres, vous devez tenir compte de ses limitations.

  • Le dépannage peut être un problème.
  • Les tâches sont mises en file d'attente et dépendent de la disponibilité du serveur. Leur traitement peut ainsi s'avérer plus long que prévu.
  • Avons-nous déjà parlé de limitations ?

Apex pour file d'attente

Pendant longtemps, les méthodes futures et l'interface de traitement par lot étaient les principales méthodes dont les développeurs disposaient pour un traitement asynchrone. Vous rappelez-vous de toutes les limitations que nous avons évoquées ? Elles présentaient des problèmes pour certains développeurs, qui attendaient une meilleure solution.

Dans la version Winter ’15, Salesforce a répondu avec l'Apex pour file d'attente. Il représente la meilleure solution pour les méthodes futures et l'interface de traitement par lot, toutes incluses dans un super outil asynchrone. Les développeurs, qui devaient utiliser l'interface de traitement par lot plus lente pour contourner les limitations des méthodes futures, disposent désormais d'un outil plus pratique. Apex pour file d'attente offre les avantages suivants par rapport aux méthodes futures :

  • Types non primitifs : les classes peuvent accepter des variables de types de données non primitifs, tels que des sObjects ou des types Apex personnalisés.
  • Surveillance : lorsque vous soumettez votre tâche, un jobId est renvoyé, que vous pouvez utiliser pour identifier la tâche et suivre sa progression.
  • Chaînage des tâches : vous pouvez chaîner une tâche à une autre en démarrant la deuxième tâche à partir d’une tâche en cours d’exécution. Le chaînage des tâches est utile pour le traitement séquentiel.

Comment fonctionne-t-il ? Bonne question.

Comme Apex pour file d'attente inclut les meilleures méthodes futures, il est beaucoup plus facile à implémenter qu'Apex par lot. Il n'impose pas ces fichues limitations que nous avons évoquées. Pour examiner son fonctionnement, prenons un exemple de code qui a utilisé une méthode future afin d'exécuter un appel externe Web et de l'implémenter en utilisant Apex pour file d'attente.

public class MyQueueableClass implements Queueable {
    private List<Contact> contacts;

    // Constructor for the class, where we pass
    // in the list of contacts that we want to process
    public MyQueueableClass(List<Contact> myContacts) {
        contacts = myContacts;
    }

    public void execute(QueueableContext context) {
        // Loop through the contacts passed in through
        // the constructor and call a method
        // which contains the code to do the actual callout
        for (Contact con: contacts) {
            String response = anotherClass.calloutMethod(con.Id,
                    con.FirstName,
                    con.LastName,
                    con.Email);

            // May still want to add some code here to log
            // the response to a custom object
        }
    }
}

Pour invoquer Apex pour file d'attente, vous avez besoin d'un code semblable au suivant :

List<Contact> contacts = [SELECT Id, LastName, FirstName, Email
    FROM Contact WHERE Is_Active__c = true];
Id jobId = System.enqueueJob(new MyQueueableClass(contacts));

En savoir plus

Avec les interfaces pour file d'attente, Salesforce a également introduit la File d'attente Flex Apex dans la version Spring ’15, qui élimine la limitation de cinq lots simultanés. Elle permet également aux développeurs de surveiller et de gérer l'ordre des tâches en file d'attente. Pour plus d'informations, suivez les liens de la section Ressources.

Ce module a présenté aux développeurs .NET les options asynchrones disponibles sur la plate-forme Lightning. Pour aller plus loin sur ce thème, notamment le test, la surveillance des tâches et les meilleures pratiques, suivez le module Asynchronous Apex.

Ressources