Empiece a realizar un seguimiento de su progreso
Inicio de Trailhead
Inicio de Trailhead

Controlar procesos mediante Apex para inclusión en cola

Objetivos de aprendizaje

Después de completar esta unidad, tendrá conocimientos sobre lo siguiente:
  • Cuándo usar la interfaz Queueable.
  • Diferencias entre métodos de inclusión en cola y métodos futuros.
  • Sintaxis de Apex para inclusión en cola.
  • Mejores prácticas para métodos de inclusión en cola.

Queueable Apex

Apex para inclusión en cola se presentó en Winter '15 y es un conjunto extraordinario de métodos futuros con un #ingredienteEspecial. Hemos aprovechado la simplicidad de los métodos futuros y la capacidad de Apex por lotes, y los hemos combinado para crear Apex para inclusión en cola. De este modo, dispone de una estructura de clases que la plataforma serializa por usted, una interfaz simplificada sin métodos start y finish, e incluso puede usar otros elementos además de argumentos primitivos. La llamada se realiza mediante un método System.enqueueJob() sencillo, el cual devuelve un Id. de trabajo que puede monitorear. El trabajo se realiza con el mínimo esfuerzo.

Apex para inclusión en cola le permite enviar trabajos para su procesamiento asíncrono mediante un mecanismo similar al de los métodos futuros, pero con una serie de ventajas adicionales:
  • Tipos no primitivos: La clase Queueable puede contener variables de miembro de tipos de datos no primitivos, como sObjects o tipos de Apex personalizados. A estos objetos se puede acceder cuando se ejecuta el trabajo.
  • Monitoreo: Cuando envía su trabajo mediante la invocación del método System.enqueueJob, el método devuelve el Id. del registro AsyncApexJob. Puede usar este Id. para identificar su trabajo y monitorear el progreso, ya sea mediante la interfaz de usuario de Salesforce en la página Trabajos de Apex o mediante programación con una consulta al registro desde AsyncApexJob.
  • Encadenamiento de trabajos: Puede encadenar un trabajo con otro trabajo mediante el inicio de un segundo trabajo desde un trabajo en ejecución. El encadenamiento de trabajos es útil si necesita realizar un procesamiento secuencial.

Comparación de métodos de inclusión en cola y métodos futuros

Dado que los métodos de inclusión en cola tienen una funcionalidad equivalente a la de los métodos futuros, en la mayoría de los casos deseará probablemente usar métodos de inclusión en cola en lugar de métodos futuros. No obstante, esto no significa necesariamente que deba retroceder y refactorizar todos los métodos futuros justo ahora.

Otro motivo por el que usar métodos futuros en lugar de métodos de inclusión en cola es que la funcionalidad se ejecuta en ocasiones de forma síncrona y en otras ocasiones de forma asíncrona. Es mucho más fácil refactorizar un método de este modo que convertirlo en una clase de inclusión en cola. Esto es útil cuando detecta que parte del código existente se debe cambiar a la ejecución asíncrona. En este caso, no tiene más que crear un método futuro similar que encapsule el método síncrono del modo siguiente:

@future
static void myFutureMethod(List<String> params) {
    // call synchronous method
    mySyncMethod(params);
}

Sintaxis de inclusión en cola

Para poder usar Apex para inclusión en cola, solo tiene que implementar la interfaz Queueable.

public class SomeClass implements Queueable { 
    public void execute(QueueableContext context) {
        // awesome code here
    }
}

Código de ejemplo

Un caso común es el uso de un conjunto de registros de sObject, la ejecución de parte del procesamiento, como una llamada a un extremo de REST externo o la realización de determinados cálculos, y la actualización posterior en la base de datos de forma asíncrona. Dado que los métodos @future se limitan a tipos de datos primitivos (o matrices o colecciones de primitivos), en este caso Apex para inclusión en cola es una opción ideal. En el siguiente código se usa una colección de registros de cuenta, se establece parentId para cada registro y, a continuación, se actualizan los registros en la base de datos.

public class UpdateParentAccount implements Queueable {
    
    private List<Account> accounts;
    private ID parent;
    
    public UpdateParentAccount(List<Account> records, ID id) {
        this.accounts = records;
        this.parent = id;
    }

    public void execute(QueueableContext context) {
        for (Account account : accounts) {
          account.parentId = parent;
          // perform other processing or callout
        }
        update accounts;
    }
    
}

Para agregar esta clase a un trabajo de la cola, ejecute el siguiente código:

// find all accounts in ‘NY’
List<Account> accounts = [select id from account where billingstate = ‘NY’];
// find a specific parent account for all records
Id parentId = [select id from account where name = 'ACME Corp'][0].Id;

// instantiate a new instance of the Queueable class
UpdateParentAccount updateJob = new UpdateParentAccount(accounts, parentId);

// enqueue the job for processing
ID jobID = System.enqueueJob(updateJob);

Después de enviar la clase de inclusión en cola para la ejecución, el trabajo se agrega a la cola y se procesa cuando los recursos del sistema están disponibles.

Puede usar el nuevo Id. del trabajo para monitorear el progreso, bien en la página Trabajos de Apex o mediante programación con un consulta a AsyncApexJob:

SELECT Id, Status, NumberOfErrors FROM AsyncApexJob WHERE Id = :jobID

Prueba de Apex para inclusión en cola

En el siguiente ejemplo de código se muestra cómo probar la ejecución de un trabajo apto para la inclusión en cola en un método de prueba. Es muy similar a la prueba de Apex por lotes. Para garantizar que el proceso apto para la inclusión en cola se ejecuta en el método de prueba, el trabajo se envía a la cola en el bloque entre Test.startTest y Test.stopTest. El sistema ejecuta todos los procesos asíncronos iniciados en un método de prueba de forma síncrona después de la declaración Test.stopTest. A continuación, el método de prueba examina los resultados del trabajo apto para inclusión en cola mediante la consulta de los registros de cuenta que ha actualizado el trabajo.

@isTest
public class UpdateParentAccountTest {

    @testSetup 
    static void setup() {
        List<Account> accounts = new List<Account>();
        // add a parent account
        accounts.add(new Account(name='Parent'));
        // add 100 child accounts
        for (Integer i = 0; i < 100; i++) {
            accounts.add(new Account(
                name='Test Account'+i
            ));
        }
        insert accounts;
    }
    
    static testmethod void testQueueable() {
        // query for test data to pass to queueable class
        Id parentId = [select id from account where name = 'Parent'][0].Id;
        List<Account> accounts = [select id, name from account where name like 'Test Account%'];
        // Create our Queueable instance
        UpdateParentAccount updater = new UpdateParentAccount(accounts, parentId);
        // startTest/stopTest block to force async processes to run
        Test.startTest();        
        System.enqueueJob(updater);
        Test.stopTest();        
        // Validate the job ran. Check if record have correct parentId now
        System.assertEquals(100, [select count() from account where parentId = :parentId]);
    }
    
}

Encadenamiento de trabajos

Una de las mejores funciones de Apex para inclusión en cola es el encadenamiento. Si alguna vez necesita ejecutar trabajos secuencialmente, Apex para inclusión en cola puede facilitar mucho este proceso. Para encadenar un trabajo con otro trabajo, envíe el segundo trabajo desde el método execute() de la clase de inclusión en cola. Solo puede agregar un único trabajo desde un trabajo en ejecución, lo que significa que solo puede existir un trabajo secundario para cada trabajo principal. Por ejemplo, si tiene una segunda clase llamada SecondJob que implementa la interfaz Queueable, puede agregar esta clase a la cola en el método execute() del modo siguiente:

public class FirstJob implements Queueable { 
    public void execute(QueueableContext context) { 
        // Awesome processing logic here    
        // Chain this job to next job by submitting the next job
        System.enqueueJob(new SecondJob());
    }
}

Una vez más, el proceso de prueba sigue un patrón ligeramente distinto. No puede encadenar trabajos para la inclusión en cola en una prueba de Apex, ya que esto genera un error. Para evitar errores graves, puede comprobar si Apex se está ejecutando en el contexto de la prueba mediante una llamada a Test.isRunningTest() antes de encadenar los trabajos.

Aspectos que recordar

Apex para inclusión en cola es una herramienta nueva extraordinaria, pero hay una serie de aspectos a los que debe prestar atención:
  • La ejecución de un trabajo en cola solo cuenta una vez en el caso del límite compartido para ejecuciones de métodos de Apex de forma asíncrona.
  • Puede agregar hasta 50 trabajos a la cola con System.enqueueJob mediante una sola transacción.
  • Al encadenar trabajos, solo puede agregar un único trabajo desde un trabajo en ejecución con System.enqueueJob, lo que significa que solo puede existir un trabajo secundario para cada trabajo principal. El inicio de varios trabajos secundarios desde el mismo trabajo apto para la inclusión en cola no es aceptable.
  • No se aplica ningún límite a la profundidad de los trabajos encadenados, lo que significa que puede encadenar un trabajo con otro trabajo y repetir este proceso con cada nuevo trabajo secundario que se vaya a vincular a un nuevo trabajo secundario. No obstante, en el caso de las organizaciones con Developer Edition y una edición de prueba, la profundidad de la pila máxima para los trabajos encadenados equivale a 5, lo que significa que puede encadenar trabajos cuatro veces y que el número máximo de trabajos de la cadena es 5, incluido el trabajo principal apto para inclusión en cola inicial.

Recursos

Nota

Nota

Recuerde, este módulo está pensado para Salesforce Classic. Cuando inicie su organización para realizar prácticas, cambie a Salesforce Classic para completar este reto.