Skip to main content

Utilisation de méthodes futures

Objectifs de formation

Dans cette unité, vous allez découvrir :

  • Quand utiliser des méthodes futures
  • Les limitations d’utilisation de méthodes futures
  • Comment utiliser des méthodes futures pour des appels externes
  • Les meilleures pratiques d’utilisation de méthodes futures
Remarque

Remarque

Vous souhaitez apprendre en français ? Dans ce badge, les validations de défi pratique Trailhead se font en anglais. Les traductions sont fournies entre parenthèses à titre de référence. Dans votre Trailhead Playground, veillez (1) à définir les États-Unis comme région, (2) à sélectionner l’anglais comme langue, et (3) à copier et coller uniquement les valeurs en anglais. Suivez les instructions ici.

Consultez le badge Trailhead dans votre langue pour découvrir comment profiter de l’expérience Trailhead traduite.

Vidéo de démonstration Trail Together

Vous souhaitez être guidé pas à pas pendant que vous travaillez sur cette étape ? Regardez cette vidéo qui fait partie de la série Trail Together sur Trailhead Live.

(Ce clip commence à 9 min 39 s, au cas où vous voudriez revenir en arrière et regarder à nouveau le début de l’étape.) 

Apex futur

Un code Apex futur est utilisé pour exécuter des processus ultérieurement dans un thread distinct, lorsque les ressources système sont disponibles.

Remarque : Techniquement, vous utilisez l’annotation @future pour identifier les méthodes exécutées de façon asynchrone. Cependant, l’expression « méthode identifiée avec l’annotation @future » est laborieuse. Par conséquent, elles sont communément appelées « méthodes futures », expression que nous allons employer dans ce module.

Lors de l’utilisation d’un traitement synchrone, tous les appels de méthode proviennent du même thread qui exécute le code Apex, et aucun traitement supplémentaire ne peut être effectué avant la fin du processus. Vous pouvez utiliser des méthodes futures pour toute opération que vous souhaitez exécuter de façon asynchrone dans son propre thread. Avec les méthodes futures, l’utilisateur peut exécuter d’autres opérations, et vous pouvez définir des limitations du gouverneur et d’exécution supérieures pour le processus. Le traitement asynchrone satisfait tout le monde.

Les méthodes futures sont généralement utilisées pour les opérations suivantes :
  • Des appels externes à des services Web externes. Si vous effectuez des appels externes à partir d’un déclencheur ou après l’exécution d’une opération DML, vous devez utiliser une méthode future ou pour file d'attente. Un appel externe dans un déclencheur garderait la connexion à la base de données ouverte pendant la durée de vie de l’appel externe, ce qui est interdit dans un environnement mutualisé.
  • Les opérations que vous souhaitez exécuter dans leur propre thread, lorsque les conditions sont favorables, par exemple un calcul ou un traitement d’enregistrements qui mobilise des ressources importantes.
  • L’isolation des opérations DML sur différents types de sObject afin d’éviter l’erreur d’opérations DML mixtes. Il s’agit d’un cas extrême, mais vous pouvez parfois rencontrer cette erreur. Pour plus informations, reportez-vous à sObjects That Cannot Be Used Together in DML Operations (en anglais).

Syntaxe d'une méthode future

Les méthodes futures sont des méthodes statiques qui peuvent renvoyer uniquement un type void. Les paramètres spécifiés 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. En particulier, les méthodes futures ne peuvent pas accepter des objets standard ou personnalisés en tant qu’arguments. Un modèle courant consiste à transmettre à la méthode une List (liste) d’ID d’enregistrement que vous souhaitez traiter de façon asynchrone.

public class SomeClass {
  @future
  public static void someFutureMethod(List<Id> recordIds) {
    List<Account> accounts = [Select Id, Name from Account Where Id IN :recordIds];
    // process account records to do awesome stuff
  }
}
Remarque

Un objet ne peut pas être transmis à des méthodes futures en tant qu’argument, car il peut changer entre l’appel de la méthode et son exécution. Souvenez-vous que les méthodes futures sont exécutées lorsque les ressources système sont disponibles. Dans ce cas, la méthode future peut inclure une ancienne valeur d’objet lors de son exécution, ce qui peut entraîner divers problèmes.

Il est important de noter que les méthodes futures ne sont pas nécessairement exécutées dans l’ordre dans lequel elles sont appelées. Nous ne le répéterons jamais assez : les méthodes futures ne sont pas nécessairement exécutées dans l’ordre dans lequel elles sont appelées. Lors de l’utilisation de méthodes futures, il se peut également que deux méthodes futures soient exécutées simultanément, ce qui peut entraîner un verrouillage d’enregistrement et une erreur d’exécution si les deux méthodes mettent à jour le même enregistrement.

Exemple de code d’appel externe

Pour exécuter un appel externe de service Web à un service externe ou une API, vous créez une classe Apex avec une méthode future marquée avec (callout=true). La classe ci-dessous contient les méthodes d’exécution de l’appel de façon synchrone et asynchrone lorsque les appels externes ne sont pas autorisés. Nous insérons un enregistrement dans un objet de journal personnalisé pour suivre le statut de l’appel externe, simplement parce que la consignation est toujours intéressante ! 

Remarque

La classe SmsMessage et le sObject SMS_Log__c dans l’exemple sont des hypothèses et affichés uniquement pour illustrer le modèle d’appel.

public class SMSUtils {
    // Call async from triggers, etc, where callouts are not permitted.
    @future(callout=true)
    public static void sendSMSAsync(String fromNbr, String toNbr, String m) {
        String results = sendSMS(fromNbr, toNbr, m);
        System.debug(results);
    }
    // Call from controllers, etc, for immediate processing
    public static String sendSMS(String fromNbr, String toNbr, String m) {
        // Calling 'send' will result in a callout
        String results = SmsMessage.send(fromNbr, toNbr, m);
        insert new SMS_Log__c(to__c=toNbr, from__c=fromNbr, msg__c=results);
        return results;
    }
}

Classes de test

Le test de méthodes futures est légèrement différent que le test Apex classique. Pour tester des méthodes futures, insérez votre code test entre les méthodes de test startTest() et stopTest(). Le système collecte tous les appels asynchrones effectués après startTest(). Lorsque stopTest() est exécuté, tous ces processus asynchrones collectés sont exécutés de façon synchrone. Vous pouvez ensuite affirmer que l’appel asynchrone fonctionne correctement.

Remarque

Le code test ne peut pas envoyer d’appels externes à des systèmes externes. Par conséquent, vous devez « simuler » l’appel externe pour la couverture de test. Pour des informations complètes sur la simulation d’appels externes à des fins de tests, consultez le module Apex Integration Services.

Notre classe d’appel externe fictive pour le test se présente comme suit. L’infrastructure de test Apex utilise cette réponse fictive au lieu de transmettre l’appel externe au point de terminaison de l’API REST.

@isTest
public class SMSCalloutMock implements HttpCalloutMock {
    public HttpResponse respond(HttpRequest req) {
        // Create a fake response
        HttpResponse res = new HttpResponse();
        res.setHeader('Content-Type', 'application/json');
        res.setBody('{"status":"success"}');
        res.setStatusCode(200);
        return res;
    }
}

La classe de test contient une seule méthode de test (dans notre exemple, testSendSms()). Elle teste la méthode asynchrone et la méthode synchrone, la première appelant la dernière.

@IsTest
private class Test_SMSUtils {
  @IsTest
  private static void testSendSms() {
    Test.setMock(HttpCalloutMock.class, new SMSCalloutMock());
    Test.startTest();
      SMSUtils.sendSMSAsync('111', '222', 'Greetings!');
    Test.stopTest();
    // runs callout and check results
    List<SMS_Log__c> logs = [select msg__c from SMS_Log__c];
    System.assertEquals(1, logs.size());
    System.assertEquals('success', logs[0].msg__c);
  }
}

Meilleures pratiques

L’invocation de chaque méthode future ajoute une requête à la file d’attente asynchrone. Par conséquent, évitez les modèles de conception qui ajoutent un nombre important de requêtes futures sur une courte période. Si votre conception peut ajouter 2000 requêtes ou plus à la fois, les requêtes peuvent être retardées en raison du contrôle du flux. Tenez compte des pratiques recommandées ci-dessous :
  • Assurez-vous que les méthodes futures sont exécutées aussi rapidement que possibles.
  • Si vous utilisez des appels externes de service Web, essayez de regrouper tous les appels externes de la même méthode future au lieu d’utiliser une méthode future séparée pour chaque appel externe.
  • Effectuez des tests complets à l’échelle. Effectuez un test pour déterminer si un déclencheur mettant en file d’attente des appels @future peut gérer une collection de déclencheur de 200 enregistrements. Vous pouvez ainsi déterminer si la conception des volumes actuels et futurs entraîne des délais.
  • Utilisez un code Apex par lot plutôt que des méthodes futures pour traiter simultanément un grand nombre d’enregistrements. Cette solution est plus efficace que la création d’une requête future pour chaque enregistrement.

À retenir

Les méthodes futures sont très efficaces, mais leur puissance doit être contrôlée. Lors de l’utilisation de méthodes futures, tenez compte des points suivants :
  • Les méthodes munies de l’annotation @future doivent être statiques et ne peuvent renvoyer qu’un type void.
  • Les paramètres spécifiés 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.
  • L’ordre d’exécution des méthodes futures ne correspond pas nécessairement à l’ordre dans lequel elles sont appelées. En outre, deux méthodes futures peuvent être exécutées simultanément, ce qui peut entraîner un verrouillage d’enregistrement si les deux méthodes mettent à jour le même enregistrement.
  • Les méthodes futures ne peuvent pas être utilisées dans des contrôleurs Visualforce dans getMethodName(), setMethodName(), ni dans le constructeur.
  • Vous ne pouvez pas appeler une méthode future à partir d’une méthode future. Vous ne pouvez pas non plus invoquer un déclencheur qui appelle une méthode future tout en exécutant une méthode future. Pour empêcher les appels de méthode future récursifs, suivez le lien « Preventing Recursive Future Method Calls in Salesforce » dans la section Ressources.
  • Les méthodes getContent() et getContentAsPDF() ne peuvent pas être utilisées dans des méthodes avec une annotation @future.
  • Vous êtes limité(e) à 50 appels futurs par invocation Apex avec une limite supplémentaire en nombre d’appels par période de 24 heures. Pour plus d’informations sur ces limitations, suivez le lien ci-dessous.
Formez-vous gratuitement !
Créez un compte pour continuer.
Qu’est-ce que vous y gagnez ?
  • Obtenez des recommandations personnalisées pour vos objectifs de carrière
  • Mettez en pratique vos compétences grâce à des défis pratiques et à des questionnaires
  • Suivez et partagez vos progrès avec des employeurs
  • Découvrez des opportunités de mentorat et de carrière