[Arquitectura de Software] El Patrón de Diseño Pipeline – De Cero a Héroe

En este artículo, exploraremos las diferentes formas de implementar el patrón de diseño pipeline empezando por lo más básico hasta llegar a soluciones más complejas.

El Patrón Pipeline

El patrón pipeline es un patrón de diseño de software que proporciona la capacidad de construir y ejecutar una secuencia de operaciones.

https://www.hojjatk.com/2012/11/chain-of-responsibility-pipeline-design.html

Este patrón se utiliza mejor junto con el patrón plugin, para construir dinámicamente la tubería cuando la aplicación se inicia.

Secuencia

La implementación más básica de un pipeline sería una simple secuencia de operaciones.

La interfaz de una operación puede ser invocada para procesar datos.

El pipeline procesa cada operación una a una. La clase del pipeline también implementa la interfaz IOperation por lo que se pueden combinar.

La operación se puede escribir en una clase dedicada.

O utilizar un wrapper para crear automáticamente una operación a partir de un lambda.

Las operaciones de la tubería deben ser registradas antes de que la tubería sea invocada.

Interruptor de circuito

La primera característica que quieres añadir a tu tubería es añadir un interruptor de circuito.

Cada operación devolverá el resultado : fallo o éxito.

Si una operación falla, la ejecución del pipeline debe detenerse.

Asíncrono

Otro requisito podría ser tener un pipeline que pueda lidiar con operaciones asíncronas.

Cada operación tendrá que llamar a la siguiente operación en el pipeline, después de que hayan terminado de procesar los datos.

El pipeline es un poco más complejo, porque necesita establecer la siguiente operación cuando se registra una nueva operación. Otra solución es utilizar un constructor.

Esta operación es asíncrona y se ejecutará en un hilo dedicado, cuando se acabe el tiempo, invocará la siguiente operación para continuar el pipeline.

La operación genérica se puede utilizar tanto con una simple acción, o utilizar un interruptor incorporado si se utiliza una función.

Este sencillo ejemplo utiliza varias de las funciones que hemos implementado.

¡Ahora ya sabes cómo hacer tu pipeline asíncrono!

Sería aún mejor si tuviera otra llamada de retorno a la operación anterior para que pudiera tener el resultado que va a contracorriente a través de la tubería.

Plugin

La razón principal para utilizar el patrón de diseño de la tubería es a menudo el requisito de ser capaz de añadir plugins que, o bien añadir operaciones a una tubería existente o para enganchar una operación en medio de ella.

El pipeline es realmente básico, pero esta vez, las operaciones están expuestas.

Tomemos una aplicación simple con un pipeline que sólo mostrará los 3 pasos en la consola. Esta aplicación también soporta plugins para modificar el pipeline.

El primer plugin enganchará otra operación en el segundo slot del pipeline.

El segundo plugin añadirá una nueva operación al final del pipeline.

La aplicación y los plugins están juntos, podemos invocar el pipeline.

Batch

Otra característica útil es poder procesar datos por lotes en el mismo pipeline que elementos individuales.

La tubería de lotes envuelve una tubería y llama a cada operación en cada elemento.

Cada elemento está envuelto, por lo que podemos recordar el resultado del interruptor.

Esta operación comprueba si el entero tiene el orden de magnitud requerido.

La tubería va a comprobar el orden de magnitud de un lote de enteros.

El pipeline sólo invoca la siguiente operación para los elementos que no han fallado.

Pipeline de alto rendimiento

El patrón de diseño Pipeline también puede estar refiriéndose a una arquitectura de software mucho más específica y orientada al rendimiento.

Algunos proyectos utilizan un pipeline para optimizar el procesamiento de una gran cantidad de datos ejecutando cada operación del pipeline en un hilo dedicado.

Cada hilo consumirá y producirá datos de una cola concurrente que actuará de buffer.

En esta ocasión, utilizaremos operaciones asíncronas con un interruptor.

Si la operación tiene éxito, debe invocar la siguiente, o terminar si falla.

El pipeline está diseñado para saltarse el circuit-breaker. Tenga éxito o falle, siempre continuará la secuencia del pipeline padre y llamará a la siguiente operación.

El escenario es un poco complejo, así que no lo explicaré todo. La idea es tener diferentes hilos para procesar los pedidos entrantes. Cuando se termina de procesar un pedido, se comprueba el estado del mismo.

Cada procesador de pedidos está aislado en un hilo dedicado, por lo que se puede optimizar la forma de almacenar los datos y tener acceso directo a la memoria sin utilizar bloqueos.

El procesador de pedidos de pago es el único hilo que puede acceder a los saldos de los usuarios. Puede obtener o actualizar cualquier saldo sin preocuparse de los problemas de concurrencia.

El pipeline está procesando la secuencia de operaciones lo más rápido posible.

Conclusión

El Patrón de Diseño Pipeline tiene una gran cantidad de formas muy diferentes de ser implementado, desde una simple Cadena de Comandos hasta un Flujo de Trabajo más complejo.

Se pueden requerir muchas características como interruptor, asíncrono o buffer, pero la mayoría de las veces, se quiere utilizar pipelines cuando se quiere tener plugins que puedan enganchar en el flujo de ejecución del pipeline.

Deja una respuesta

Tu dirección de correo electrónico no será publicada.