
Con este nuevo post abrimos una nueva etapa y dejamos atras la introducción a Dapr compuesta por la serie de 8 capítulos que comenzaba con esta introducción. Continuaremos en este y otros más que seguirán, con temas algo más diversos y prácticos. En esta ocasión, veremos como jugar con la caducidad de los estados y eventos, es decir veremos como usar los TTL (Time to Live) para los Building Blocks: State Management y Publish & Subscribe.
Como viene siendo habitual, nos centraremos en los ejemplos usados en los capítulos 2/N y 4/N de esta serie de 8 capítulos.
State Management TTL
Dapr habilita el Time to Live (TTL o tiempo de vida) de cada request por cada State Store. No se pueden recuperar una vez que hayan expirado.
No todos los componentes son compatibles con el TTL, por lo que es importante echar un ojo a este listado para conocerlos. Para aquellos que no lo son, simplemente serán ignorados a pesar de habérselo indicado a Dapr.
Pub/Sub TTL
Dapr habilita el TTL por mensaje, por lo que la aplicación en cuestión establece el TTL para cada uno de estos mensaje y los subscriptores no los reciben una vez que hayan expirado.
A diferencia de lo que ocurre con los State Store, para los Pub/Sub si que es compatible el TTL para todos los componentes.
Nota. Si existen mensajes que son consumidos por subscriptores que no usan Dapr, el mensaje expirado no es eliminado automáticamente. Por lo que para cada subscriptor tendremos que hacerlo programáticamente añadiendo algo de lógica.
Configurando y ejecutando las aplicaciones
Ahora que ya conocemos de que se trata esto del TTL, vamos a verlo en la practica. En concreto, lo que necesitamos es hacer uso de la propiedad «ttlInSeconds«, que veremos a continuación en los ejemplos.
Configurando «StateManagement»
- Para nuestro ejemplo (en github), en la clase «Program.cs«, añadimos una entrada más en nuestro array «Examples«, es decir, la entrada número 4.
- Creamos una nueva clase «StateStoreTTLExample.cs«, copia de la ya existente «StateStoreExample.cs«
- [Opción 1] Añadimos el siguiente código a nuestro componente «localredis.yaml» (carpeta components/local), para que nos quede así:
apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
name: statestore
namespace: default
spec:
type: state.redis
version: v1
metadata:
- name: redisHost
value: localhost:6379
- name: redisPassword
value: ""
- name: ttlInSeconds
value: 10
- [Opción 2] Modificamos el código del método «RunAsync» para que sea similar al siguiente:
var metadata = new Dictionary<string, string>
{
{ "ttlInSeconds", $"{ttlSecs}" }
};
await client.SaveStateAsync(storeName,
stateKeyName,
state,
null,
metadata,
cancellationToken: cancellationToken);
Vemos que tenemos dos opciones, donde la opción 1, permite definir por configuración el TTL que afectará a todos los request del State Store, mientras que con la opción 2, tendremos más posibilidades de personalización dado que podremos aplicar TTLs diferentes a cada mensaje o incluso, aplicar unos TTLs u otros dependiendo de cierta lógica.
Además, la opción 2 permite sobreescribir («override«) el valor del TTL especificado por configuración a través de la opción 1.
Ejecutando «StatementManagement»
Ejecutamos la siguiente instrucción mediante línea de comandos, desde la carpeta donde se encuentra el proyecto:
dapr run --app-id DaprClient --components-path ./components/local -- dotnet run 4
Y, simplemente seguimos las instrucciones. Es decir, la aplicación se queda esperando 5 segundos (que es el valor dado por la opción 2) antes de que el mensaje expire. Si durante este tiempo comprobamos el valor del mensaje veremos que es correcto y realmente existe. A partir de dicho tiempo, el mensaje desaparece.

Nota: Para hacer esta comprobación, (en redis en concreto para el ejemplo) he usado este pluging de VSCode, donde puedo ver el valor de TTL, y, que a medida que refresco va disminuyendo hasta que es eliminado.

Nota: Para persisitr los stados (ignorando cualquier TTL para una key), bastará con indicar el varlo -1 para la propiedad ttlInSeconds.
Configurando «PublishSubscribe»
Para este otro ejemplo (en github), modificamos el código del método «RunAsync» de la clase «PublishEventExample» y, en concreto, añadimos el parámetro metadata en la llamada a «PublishEventAsync«:
var metadata = new Dictionary<string, string>
{
{"ttlInSeconds", "10"}
};
await client.PublishEventAsync(pubsubName,
topicName: "forecast",
eventData,
metadata,
cancellationToken);
Nota: Para este Building Block, el uso de TTL vía componente (configuración) o es posible, por lo que solo podremos hacer uso de el programáticamente. Esto es debido a que el TTL afecta a cada mensaje y no al Topic en general.
Ejecutando «PublishSubscriber»
Con la siguiente instrucción desde línea de comandos, ejecutamos el publicador (Publisher), que se encarga de enviar el mensaje al Azure Servcie Bus vía Dapr. Recordemos que nuestro componente en este caso es «servicebus-publish.pubsub.yaml«.
dapr run --app-id publisher --components-path ../dapr/components -- dotnet run 0
Una vez que finaliza la ejecución al comprar los mensajes desde el Portal de Azure o bien desde la aplicación «Service Bus Explorer«, podemos ver que la propiedad TimeToLive tiene el valor que le hemos pasado.


Ahora que hemos comprobado que los mensajes se reciben con el TimeToLive (TTL) podemos hacer varias pruebas y comprobar que una vez transcurrido el TTL el mensaje desaparece.
De la misma manera si ejecutamos la aplicación Subscriber podemos corroborar el mismo comportamiento. Ejecutamos para ello la siguiente instrucción (posicionados en la carpeta Subscriber):
dapr run --app-id subscriber --app-port 5000 --components-path ../dapr/components -- dotnet run

Si especificamos para el TTL el valor «-1» o no lo especificamos, el valor que tomar el TimeToLive en Azure Service Bus es el valor de un TimeSpan.MaxValue.
Happy #Dapr coding !!!
Reblogueó esto en El Bruno.
Me gustaMe gusta