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

Presentación de aplicación de ejemplo y detección de Diagnósticos de caché

Objetivos de aprendizaje

Después de completar esta unidad, podrá:

  • Explicar el patrón para almacenar y actualizar datos en caché.
  • Decidir qué estructura de datos utilizar para el valor en caché.
  • Diagnosticar su utilización de la memoria caché.

Presentación de la aplicación de ejemplo

Echemos un vistazo a la aplicación de ejemplo, que muestra cómo utilizar la memoria caché de la organización para almacenar y recuperar tipos de cambio de divisas. Los tipos de cambio fluctúan a lo largo del día, por lo que esta aplicación de ejemplo no devuelve los tipos en tiempo real. La aplicación solo ofrece una instantánea diaria de los tipos de cambio. Como lo que nos interesa no son unos valores precisos en tiempo real, sino únicamente los valores diarios, almacenar en caché los tipos de cambio de divisas es una buena opción. Cuando se recuperan tipos de cambio de forma repetida, obtenerlos de la memoria caché permite ahorrar mucho tiempo y mejorar el desempeño de la aplicación.

Descripción general de la aplicación de ejemplo

Basamos nuestra aplicación de ejemplo de tipos de cambio en una página de Visualforce y un controlador de Apex que contiene la lógica para recuperar tipos de cambio. La primera vez que alguien accede a esta página, se obtienen los tipos de cambio a través de una llamada de API a un servicio web externo. Las siguientes ejecuciones de esta página devuelven los tipos de la memoria caché siempre que estos tengan una antigüedad inferior a un día. Para cada tipo de cambio, esta página muestra la divisa base, la divisa de destino para la conversión y el tipo de conversión. Para fines ilustrativos, se devuelve un conjunto pequeño de divisas.

Página de Visualforce que muestra los tipos de cambio de divisa

Este ejemplo es el marcado de la página de Visualforce. Esta página se asocia con el controlador de Apex ExchangeRates.

<apex:page controller="ExchangeRates" action="{!init}">
    
   <apex:pageBlock title="Rates">
      <apex:pageBlockTable value="{!Rates}" var="rate">
         <apex:column value="{!rate.Base_Currency__c}"/>
         <apex:column value="{!rate.To_Currency__c}"/>
         <apex:column value="{!rate.Rate__c }"/>
      </apex:pageBlockTable>
   </apex:pageBlock>
   
</apex:page>

Controlador de Apex de ejemplo

Nuestro controlador de Apex de ejemplo es el que realiza el trabajo pesado. Obtiene los tipos de cambio, los almacena en Salesforce y en la memoria caché, y los recupera de la memoria caché. A continuación le mostramos un desglose de las operaciones que realiza el controlador de ejemplo, seguido del código fuente.

La primera vez que se ejecuta el ejemplo, se producen las siguientes operaciones.

  • Los tipos de cambio se obtienen de una llamada de API a un extremo externo.
  • El resultado (en formato JSON) que devuelve la llamada de API se analiza y se guarda en Exchange_Rate__c sObjects en Salesforce.
  • El método getCachedRates() almacena la matriz de Exchange_Rate__c sObjects en la memoria caché de la organización.

En las posteriores ejecuciones del ejemplo:

  • El ejemplo muestra lo actualizados que están los datos almacenados. Para este fin, realiza una consulta SOQL para obtener el valor createdDate del primer registro Exchange_Rate__c que se devuelva.
  • Si la antigüedad de la fecha es mayor de un día, los tipos de cambio se obtienen de la llamada de API, como en la primera ejecución.
  • Si la fecha tiene menos de un día de antigüedad, los tipos se toman de la memoria caché de la organización. Si hay un porcentaje de error de caché, los tipos de cambio se consultan de Exchange_Rate__c sObjects y se almacenan en la memoria caché de la organización.
Nota

Nota

El controlador de Apex utiliza una clase de Apex auxiliar que se denomina RateLib y que no se muestra aquí. Esta clase auxiliar contiene métodos para hacer la llamada de API saliente a un servicio de tipos de cambio, analizar el resultado de JSON de la llamada de API y almacenar los registros Exchange_Rate__c.

public class ExchangeRates {
    private String currencies = 'EUR,GBP,CAD,PLN,INR,AUD,SGD,CHF,MYR,JPY,CNY';
    public String getCurrencies() { return currencies;}
    public Exchange_Rate__c[] rates {get; set;}

    //                                                                          
    // Checks if the data is old and gets new data from an external web service 
    // through a callout. Calls getCachedRates() to manage the cache.           
    // 
    public void init() {
        // Let's query the latest data from Salesforce
        Exchange_Rate__c[] latestRecords = ([SELECT CreatedDate FROM Exchange_Rate__c 
                        WHERE Base_Currency__c =:RateLib.baseCurrencies 
                              AND forList__c = true 
                        ORDER BY CreatedDate DESC
                        LIMIT 1]);
        
        // If what we have in Salesforce is old, get fresh data from the API
        if ( latestRecords == null  
            || latestRecords.size() == 0 
            || latestRecords[0].CreatedDate.date() < Datetime.now().date()) {
            // Do API request and parse value out
            String tempString = RateLib.getLoadRate(currencies);
            Map<String, String> apiStrings = RateLib.getParseValues(
                tempString, currencies);
            
            // Let's store the data in Salesforce
            RateLib.saveRates(apiStrings);

            // Remove the cache key so it gets refreshed in getCachedRates()
            Cache.Org.remove('Rates');
        }
        // Call method to manage the cache
        rates = getCachedRates();
    }

    //                                                                          
    // Main method for managing the org cache.                                  
    // - Returns exchange rates (Rates key) from the org cache.                 
    // - Checks for a cache miss.                                               
    // - If there is a cache miss, returns exchange rates from Salesforce       
    //    through a SOQL query, and updates the cached value.                   
    //
    public Exchange_Rate__c[] getCachedRates() {
        // Get the cached value for key named Rates
        Exchange_Rate__c[] rates = (Exchange_Rate__c[])Cache.Org.get(
            RateLib.cacheName+'Rates');
        
        // Is it a cache miss? 
        if(rates == null) {
            // There was a cache miss so get the data via SOQL
            rates = [SELECT Id, Base_Currency__c, To_Currency__c, Rate__c 
                        FROM Exchange_Rate__c 
                        WHERE Base_Currency__c =:RateLib.baseCurrencies 
                              AND forList__c = true
                              AND CreatedDate = TODAY];
            // Reload the cache
            Cache.Org.put(RateLib.cacheName+'Rates', rates);
        }
        return rates;
    }
}

Para descargar el código fuente del ejemplo de tipos de cambio y jugar con él en su organización de Developer, consulte la sección Recursos.

Mejores prácticas de gestión de la caché

Patrón de almacenamiento en caché

La clase de Apex ExchangeRates contiene métodos que encapsulan la lógica de inicialización y actualización de la caché. Si los datos no se encuentran o si están obsoletos, el método init() recupera nuevos tipos de cambio de divisa mediante una llamada de API y, a continuación, los almacena en Salesforce. El método getCachedRates() gestiona la caché de manera interna. Si no se encuentra el valor que se almacenó en la caché, este método recupera una matriz de tipos de cambio de Salesforce y la almacena en la caché.

Puesto que nuestra aplicación utiliza datos externos, recupera los datos de un servicio web mediante llamadas de API. También almacena los datos como registros de Salesforce como copia de seguridad para actualizar la caché. Las aplicaciones que no utilizan datos externos recuperan los registros de Salesforce mediante SOQL y los almacenan en la caché. En este caso, el proceso de gestión de la caché es más sencillo y la implementación de método de almacenamiento en caché requiere menos tiempo. Por ejemplo, si su aplicación solo utiliza datos locales de SOQL, no necesitaría el método init(), sino solo el método getCachedRates().

Se recomienda incluir toda la lógica de gestión de la caché en un método. De este modo, la caché se manipula solo en un lugar en su aplicación. La gestión central de la caché reduce la probabilidad de que se comentan errores al acceder a cachés no válidas (errores de caché) o al sobrescribir valores que se almacenaron en la caché de manera accidental.

Decidir qué valores se deben almacenar en la caché

Este ejemplo almacena en la caché una matriz de sObjects. ¿Es este enfoque la mejor opción de estructura de datos para almacenar? Todas las opciones conllevan un costo. El almacenamiento de volúmenes pequeños de datos, como, por ejemplo, valores de campos en lugar de sObjects, puede reducir el tamaño de utilización de su caché. Sin embargo, si almacena menos datos en cada clave, es posible que necesite una lógica compleja para volver a crear los datos y los sObjects, lo que requerirá más tiempo de procesamiento. Además, una matriz de sObject que se almacena en una clave utiliza menos espacio de caché que el tamaño total necesario para almacenar sObjects individuales en claves distintas. Almacenar elementos pequeños en lugar de una lista de elementos repercute en el desempeño de la caché debido al sobredimensionamiento de la serialización y al tiempo de asignación de la caché. Por ejemplo, en lugar de almacenar una lista de tipos de cambio (a la que se hace referencia con la variable de tipos de cambio de este fragmento de código):

Cache.Org.put('Rates', rates);

Puede almacenar los tipos de cambio individuales como campos con su propia clave de caché, tal como se indica a continuación.

Cache.Org.put('DollarToEuroRate', rateEUR);
Cache.Org.put('DollarToChineseYuan', rateCNY);
Cache.Org.put('DollarToJapaneseYen', rateJPY);
// etc.

La decisión de la estructura de datos que se debe almacenar en la caché depende de lo que haga su aplicación con los datos. Por ejemplo, si la aplicación convierte divisas a la misma moneda base, almacene al menos un tipo de cambio para cada divisa de destino. Puede almacenar cada tipo de cambio de divisa como clave individual. Sin embargo, para que resulte más fácil mostrar los tipos de cambio en una página de Visualforce, almacene los datos en caché como una lista de sObjects. Los sObjects pueden incrementar el espacio de almacenamiento, ya que contienen campos de sistema, como, por ejemplo, la fecha de creación; sin embargo, reducen el tiempo de procesamiento de la lógica e incrementan el desempeño de la caché y la aplicación. Recuerde que el objetivo principal de utilizar la caché es reducir el tiempo de ejecución de la aplicación.

Diagnosticar la utilización de la memoria caché

Hizo un gran trabajo para implementar la caché de plataforma. Ahora, ¿cómo puede saber si está haciendo el mejor uso de la caché? Hay un par de formas en las que puede comprobar los datos de desempeño. Una de ellas es visualizar la información de diagnóstico en Configuración (solo disponible en Salesforce Classic).

Antes de acceder a la página de diagnósticos, active el permiso de diagnóstico de caché para su usuario.

  1. En Configuración, ingrese usuarios en el cuadro Búsqueda rápida y, a continuación, seleccione Usuarios.
  2. Haga clic en el nombre de su usuario y, a continuación, en Modificar.
  3. Seleccione Diagnósticos de caché y haga clic en Guardar.

A continuación, acceda a la página de diagnósticos de un tipo específico de caché en una partición.

  1. En Configuración, ingrese caché en el cuadro Búsqueda rápida y, a continuación, seleccione Caché de plataforma.
  2. Haga clic en la partición de la que desee comprobar la información de diagnóstico.
  3. En la caché de la sesión o de la organización, haga clic en Diagnósticos.

    Página de partición que contiene vínculos a las páginas de diagnóstico de cada tipo de caché

Si hace clic en Diagnósticos para la caché de la organización, la página Diagnósticos de caché de la organización se abrirá en una ficha nueva. Esta página muestra dos gráficos. El primero (Capacidad y utilización de la caché de la organización) muestra su límite de utilización de caché. En nuestro caso, estamos muy por debajo del límite, con un 0,02%. El segundo gráfico (Contribución por contenido) es un gráfico de anillos que muestra la distribución de caché por claves.

Nota

Nota

Como nuestro ejemplo utiliza la caché de la organización, vamos a revisar la página de diagnósticos solo para la caché de la organización. También se proporciona una página de diagnóstico similar para la caché de sesión de aplicaciones que utilicen la caché de sesión.

La siguiente imagen muestra un gráfico de distribución de contenido con cuatro claves de caché. Una de las claves de caché, Rates, se utiliza en nuestro ejemplo de tipos de cambio. La clave Rates consume más de la mitad del espacio.

Página de diagnósticos de la caché de la organización

Después de los gráficos, se muestran los detalles de las claves de caché. Esta lista proporciona el tamaño de cada valor en caché correspondiente a una clave y al número de veces a la que se accedió a la caché. Como alternativa a llamar al método remove() en Apex, puede eliminar una caché manualmente de esta lista. El botón Eliminar permite a los administradores gestionar la caché sin tener que modificar código.

La clave DollarToEuroRate utiliza mucho menos espacio que la clave Rates. Esto es de esperar, ya que DollarToEuroRate solo almacena un valor, mientras que Rates almacena una matriz de sObjects.

Utilice la información de la página de diagnósticos para determinar si desea ajustar la utilización de su caché. Por ejemplo, si un valor de caché tiene un número de accesos bajo, lo cual indica que se utiliza con muy poca frecuencia, considere si realmente es necesario hacer esto, especialmente si el volumen es grande. O, si está próximo a alcanzar el límite de utilización de caché, vuelva a considerar qué desea almacenar en caché. Puede que desee eliminar valores de caché innecesarios o adquirir más capacidad de caché.

¡Felicitaciones! Ya sabe cómo utilizar la caché de plataforma para almacenar en caché los datos de su aplicación y recuperarlos rápidamente. También aprendió mejores prácticas de almacenamiento en caché y cómo diagnosticar la utilización de la memoria caché. ¡Ya está listo para seguir de cerca las aventuras de la ardilla y almacenar en caché sus preciados recursos!