QUEUEABLE – Regreso al @future

Anteriormente he hablado de Batch , y seguramente volveré con ello , pero hoy quiero hablar de otro proceso asíncrono al que no le tenia tanto cariño.

 ¿Conocéis @future?

Pues bien este es otro proceso asíncrono que podemos usar dentro de la plataforma Salesforce.

La gran cualidad de los procesos asíncronos es que tienen limites especiales los cuales son mayores a los procesos o transacciones síncronos.

Échale un vistazo a los Governos Limits en esta página: Governor limits

Como ves el número de registros, tanto como el tiempo , número de consultas SOQL es mayor que en una transacción síncrona.

Luego usar procesos asíncronos como @future o Batch Jobs es muy beneficiosos para algunos casos siempre y cuando no necesites el resultado .. ¡Ya!

Hoy me voy a centrar en @future y su “Futuro” la interfaz Queueable.

Pues bien, métodos @future se ejecutan cuando Salesforce tiene recursos disponibles.

Las limitaciones que existen en estos métodos son las siguientes:

  • Deben ser métodos estáticos : static
  • Solamente son de tipo void , no podemos devolver ningún otro tipo
  • No tenemos forma de saber en que estado se encuentran
  • No podemos cancelarlos
  • No son ejecutados en el orden que son llamados
  • No se pueden encadenar
  • Los parámetros que podemos usar son solamente “primitivos” , no podemos usar sObjets por ejemplo.

Esta es la nomenclatura usada :

 


public with sharing class FutureClass {

   @future
   static void myMethod(String a, Integer i) {

        System.debug('Method called with: ' + a + ' and ' + i+'... and I loved the sunny days :)');

       // Aquí va nuestro código, toda la lógica

    }

}

Es en este punto… donde aparece la ¡Interfaz Queueable!!

Que desde Winter 15 nos va a permitir:

  • Poder saber el estado de nuestro proceso asíncrono
  • Poder cancelarlo
  • Poder encadenar procesos
  • Poder usar cualquier tipo de parámetros

Y así es como se puede implementar:


public class AsyncExecutionExample implements Queueable {

   public void execute(QueueableContext context) {

      //escribo mi lógica

   }

}

Como veis el ejemplo nos muestra el método principal que debemos sobreescribir: execute

Dentro de dicho método es donde pondremos toda nuestra lógica, donde procesaremos todos los registros que necesitamos.

¿Cómo deberíamos entonces lanzar or llamar este proceso?


ID jobID = System.enqueueJob(new AsyncExecutionExample());

Entonces es aquí una vez el proceso se ha llamado podemos ver el estado en el que se encuentra haciendo una consulta a la tabla de procesos asíncronos :


AsyncApexJob jobInfo = [SELECT Status,NumberOfErrors FROM AsyncApexJob WHERE Id=:jobID];

Para encadenar procesos asíncronos de tipo Queueable solamente hemos de hacerlo dentro de nuestro execute:

 


public class AsyncExecutionExample implements Queueable {

   public void execute(QueueableContext context) {

      // Your processing logic here

      // Chain this job to next job by submitting the next job

       System.enqueueJob(new SecondJob());

       // o quizás hacer una llamada recursiva a nosotros mismos

   }

}

 

No olvidemos que debemos hacer Unit test a nuestro código con lo que como pasaba con @future , la llamada la haciemos entre las etiquetas Test.startTest()/ Test.stopTest() , en Queueable aún debemos seguir haciéndolo.

Quedaría de la siguiente manera:


@isTest

public class AsyncExecutionExampleTest {

    static testmethod void test1() {

          // startTest/stopTest block to force async processes

          //   to run in the test.

          Test.startTest();

          ID jobID = System.enqueueJob(new AsyncExecutionExample());

          Test.stopTest();

          // Validate that the job has run

          AsyncApexJob jobInfo = [SELECT Status,NumberOfErrors FROM AsyncApexJob WHERE Id=:jobID];

          System.assertEquals('Completed', jobInfo.Status);

          System.assertEquals(0, jobInfo.NumberOfErrors);

      }

}

Y para finalizar un pequeño ejemplo para hacer llamadas externas usando Queueable

public class MyQueueable implements Queueable,Database.AllowsCallouts  {
    public void execute(QueueableContext context) {
        
         HttpRequest req = new HttpRequest();
         req.setMethod('GET');
         req.setHeader('Content-Type', 'application/json');
         req.setEndPoint('https://maps.googleapis.com/maps/api/geocode/json?address=1600+Amphitheatre+Parkway,+Mountain+View,+CA&key=API_KEY');
         req.setHeader('Authorization', 'Bearer ' + UserInfo.getSessionId());
         HttpResponse response = new Http().send(req);
         ID jobID = System.enqueueJob(new AsyncExecutionExample());
   }
}

Hemos visto lo que ganamos cuando usamos Queueable, pero cuales son sus limitaciones:

  • Podemos encadenar solamente 2 procesos, no podemos encadenar hasta el “Infinito y más allá”

Entonces la siguiente pregunta sería cuando usar Queueable en lugar de Batch, pues bien, podríamos decir que usaremos Queueable cuando el volumen de registros a procesar sea mayor del permitido en un proceso síncrono pero sea proporcionalmente menor que el tamaño máximo de un proceso Batch, digamos para procesos asíncronos que solamente sean necesarios ejecutarse una vez o como máximo 2 , si no entonces necesitaremos implementar un proceso Batch. 🙂

 

 

 

 

 

2 thoughts on “QUEUEABLE – Regreso al @future

    • Pasarle un método por parámetro? El nombre de un método quizás? o un objeto o clase? Bueno no estoy segura a lo que te refieres exactamente pero podrías pasarle cualquier cosa. Solamente tendrás que crear un constructor en la clase y desde ahi podrías inicializar todos los parámetros o variables que luego puedes usar en el execute 🙂
      Ah! Otra cosa en Spring 15 ya se pueden encadenar más de 2

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s