Utilizar Apex asíncrono
Objetivos de aprendizaje
Después de completar esta unidad, podrá:
- Saber cuándo utilizar Apex asíncrono
- Utilizar métodos futuros para gestionar una llamada web
- Trabajar con la interfaz por lotes para procesar un gran número de registros
- Comprender las ventajas del uso de la interfaz con capacidad de colocación en cola cuando necesite encontrarse a medio camino
Siga el proceso con Trail Together
¿Desea seguir el proceso con un experto a medida que realiza este paso? Mire este video que forma parte de la serie Trail Together.
(Este video comienza en el minuto 32:07, en caso de que desee rebobinar y mirar el comienzo del paso nuevamente).
Cuándo ser asíncrono
Como un desarrollador de .NET, probablemente ya estuvo expuesto al mundo de programación asíncrona. Daremos por supuesto que sabe lo que es y comprende las ventajas del uso de este tipo de modelo de programación. Lo que quizás no sepa es cuándo utilizar la programación asíncrona en la plataforma Lightning.
Las tres razones siguientes están habitualmente detrás de la selección de la programación asíncrona.
- Procesamiento de un gran número de registros. Este motivo es exclusivo al mundo de la plataforma multiusuario de la plataforma Lightning donde se aplican límites. Los límites asociados con procesos asíncronos más benignos que aquellos con procesos síncronos. Por lo tanto, si necesita procesar miles o incluso millones de registros, el procesamiento asíncrono es su mejor apuesta.
- Realización de llamadas a servicios web externos. El procesamiento de llamadas puede tardar mucho tiempo, pero en la plataforma Lightning, los desencadenadores no pueden realizar llamadas directamente.
- Creación de una experiencia de usuario mejor y más rápida reduciendo algo de la carga de procesamiento con llamadas asíncronas. ¿Por qué hacer todo a la vez? Si puede esperar, hágalo.
Métodos futuros
En situaciones donde necesita realizar una llamada a un servicio web o desea descargar un procesamiento sencillo en una tarea asíncrona, la creación de un método futuro podría ser la mejor opción.
Cambiar un método del procesamiento síncrono a asíncrono es increíblemente sencillo. Fundamentalmente, solo hay que agregar la anotación @future
a su método. A parte de eso, solo asegúrese de que el método es estático y devuelve solo un tipo no válido. Por ejemplo, para crear un método para la realización de una llamada de servicio web, podemos hacer algo parecido a esto:
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 } } }
A continuación, podríamos llamarlo justo como lo haríamos con cualquier otro método estático. ¡No puede ser más fácil!
Limitaciones futuras
Los métodos futuros ofrecen una magnífica opción para desarrolladores de Salesforce; sin embargo, no están exentos de desventajas. Estas son algunas limitaciones a tener en cuenta antes de utilizar un método futuro.
- No puede realizar un seguimiento de la ejecución porque no se devuelve ningún Id. de trabajo de Apex.
- Los parámetros deben ser tipos de datos primitivos o conjuntos de tipos de datos primitivos. Los métodos futuros no pueden tomar objetos sObject como argumentos, ya que podrían cambiar antes de que se ejecute el método @futuro.
- No puede concatenar métodos futuros y hacer que uno llame a otro. Use Apex colocable en cola si necesita que la ejecución se realice en cierto orden.
Aunque las llamadas asíncronas se realizan en ocasiones para evitar límites, aún tendrá que tener en cuenta los límites. Consulte el vínculo Execution Governors and Limits en Recursos.
Apex programado o por lotes
Otra herramienta asíncrona que siempre se ha utilizado es la interfaz por lotes. La razón número 1 para utilizarla es si necesita procesar un gran número de registros. Por ejemplo, si desea limpiar o archivar hasta 150 millones de registros, la interfaz por lotes es su respuesta. También puede usar la API masiva 2.0 en su código de Apex. Puede incluso programar sus lotes para ejecutarse en una hora concreta.
Para utilizarla, su clase implementa la interfaz Database.Batchable. También define los métodos start(), execute(), and finish(). A continuación puede invocar una clase por lotes utilizando el método Database.executeBatch. Por ejemplo, el siguiente código crea una clase por lotes que procesa todas las cuentas en una organización y luego envía un email una vez hecho.
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'); } }
A continuación podría invocar la clase por lotes utilizando código anónimo como este:
MyBatchableClass myBatchObject = new MyBatchableClass(); Database.executeBatch(myBatchObject);
Limitaciones por lotes
La interfaz por lotes es genial, pero como ocurre con todo, tenga en cuenta sus limitaciones.
- La solución de problemas puede ser molesta.
- Los trabajos se colocan en cola y están sujetos a la disponibilidad del servidor, que puede tardar en ocasiones más de lo que se espera.
- ¿Hicimos referencia ya a los límites?
Y se hizo un Apex colocable en cola
Durante mucho tiempo, los métodos futuros y la interfaz por lotes eran las formas principales que tenían los desarrolladores para llevar a cabo procesamientos asíncronos. Pero, ¿recuerda todas estas limitaciones de las que hablamos? Bien, estaban causando problemas a algunos desarrolladores, así que había un clamor general solicitando una solución mejor.
En Winter ’15, Salesforce respondió con Apex colocable en cola. Representa lo mejor de los métodos futuros y la interfaz colocable en cola, todo englobado en una única herramienta asíncrona fantástica. Los desarrolladores forzados a utilizar la interfaz por lotes más lenta para sortear limitaciones de métodos futuros pueden ahora acudir a una herramienta con más sentido. Apex colocable en cola proporciona las siguientes ventajas para los métodos futuros.
- Tipos no primitivos: Las clases pueden aceptar variables de parámetro de tipos de datos no primitivos, como los sObject o los tipos de Apex personalizados.
- Monitoreo: Cuando envía su trabajo, se devuelve un Id. de trabajo que puede utilizar para identificar el trabajo y monitorear su progreso.
- Concatenación de trabajos: Puede concatenar un trabajo con otro trabajo iniciando un segundo trabajo desde un trabajo en ejecución. La concatenación de trabajos es útil para procesamientos secuenciales.
¿Cómo funciona entonces? ¡Nos complace que preguntara!
Como la Apex colocable en cola incluye lo mejor de los métodos futuros, es mucho más sencilla de implementar que la Apex por lotes. Simplemente no tiene esas fastidiosas limitaciones de las que hablamos. Para demostrar cómo funciona, utilicemos el código de muestra que utiliza un método futuro para realizar una llamada web e implementémoslo utilizando la Apex colocable en cola.
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 } } }
Para invocar la Apex colocable en cola, necesita algo como lo siguiente:
List<Contact> contacts = [SELECT Id, LastName, FirstName, Email FROM Contact WHERE Is_Active__c = true]; Id jobId = System.enqueueJob(new MyQueueableClass(contacts));
Más información
Junto con las interfaces colocables en cola, Salesforce también presentó Apex Flex Queue en Spring ’15, que eliminó la limitación de cinco lotes simultáneos. También permite a los desarrolladores monitorear y gestionar el orden de los trabajos en cola. Consulte los vínculos en Recursos para obtener más información.
Este módulo presentó a los desarrolladores de .NET las opciones asíncronas disponibles en la plataforma Lightning. Para obtener información más detallada acerca de este tema, incluyendo pruebas, trabajos de monitoreo y mejores prácticas, consulte el módulo Apex asíncrono.
Recursos
- El módulo Apex asíncrono de Trailhead trata Apex futuro, colocable en cola, por lotes y programado de forma detallada
- Límites de ejecución y reguladores en la Guía del desarrollador de código de Apex