Caso de uso de workers en Rails para procesar ordenes









En el mundo de Ruby on Rails, un worker es un proceso que corre por afuera del ciclo normal de procesamiento de una aplicación. Cuando un usuario ingresa a una página, se envía un request al servidor de dicha página. Luego, el servidor lo procesa y devuelve el contenido de la página para que el navegador del usuario muestre dicho contenido. Es una operación que tarda milisegundos y hace que un servidor pueda atender a cientos de clientes simultáneamente. Pero, ¿qué sucede cuando el usuario hace una operación que demora varios minutos o incluso horas?

Problema Fulfillment para Shopify de Marketful

En el servicio de Fulfillment de Marketful, estamos integrados con Shopify para procesar las órdenes de ventas de nuestros Sellers. Una vez que se recibe el request de Shopify vía API, el sistema guarda la orden, resta del inventario y luego actualiza el inventario vía API en Shopify y en los demás portales en donde ese producto esté publicado. La operación se completa cuando recibimos respuesta de las APIs de Shopify y demás marketplaces de que la actualización de inventario se ejecutó correctamente. En caso que no respondan en 45 segundos, se intenta de nuevo. La operación puede tardar unos 5 segundos a 2 minutos. El problema se genera porque Shopify espera unos pocos segundos para obtener respuesta de nosotros acusando recibo de la orden. Tenemos dos problemas: 

1) La operación dura más tiempo que el que Shopify espera y 
2) En un día concurrido pueden llegar cientos de órdenes en pocos segundos.

Solución

La primera opción era aumentar la capacidad de procesamiento. Como utilizamos Heroku para hospedar nuestra plataforma era muy sencillo gracias a su servicio de auto-scaling donde se aumenta de forma automática la capacidad de procesamiento según el tráfico. Pero, nos fuimos por otra opción más económica y que resolvía el tema de responderle rápido a Shopify: crear un worker. 


Flujo de trabajo original donde todo se realizaba en el servidor web: 


Decidimos crear un worker que funciona en otro servidor y con otra memoria y capacidad de procesamiento. De esta forma, el servidor web trabaja por menos de 1 segundo que tarda en comunicarse con el worker y rápidamente responde a Shopify. Podemos procesar más de 100 órdenes en un segundo de esta forma. Con más servidores web tendríamos que haber aumentado a más de 100 servidores.


Otro dato interesante, es que el worker tiene la capacidad de hacer una fila con las tareas que se le asignan. De esta forma, si se reciben 100 órdenes en un segundo las va procesando una por una. Es posible que algunas órdenes tarden varios minutos en ser procesadas pero por la dinámica de nuestro negocio donde se despacha una vez al día, no era urgente que la orden se procesara en un segundo.

Funcionamiento actual

Esta solución fue diseñada para atender picos en la demanda. Si llega el punto donde lo normal sea procesar 100 órdenes por segundo, se pueden agregar más workers en Heroku y el sistema sería capaz de procesar más pedidos sin necesidad de modificar el código. De esta forma y utilizando el auto-scaling de Heroku, no tenemos límites tecnológicos a la capacidad de procesamiento de pedidos y sincronización de inventarios en Marketful.



En nuestro pipeline de desarrollo estamos ahora ampliando nuestra plataforma para que no solo sincronice los inventarios sino también para exportar publicaciones de Shopify a otros marketplaces tal como lo hicimos en el Seller Center para Woo Commerce. En ese caso, también utilizamos workers cuando un cliente nos pide sincronizar miles de publicaciones. De esta forma, generamos plataformas robustas y escalables a la medida de cualquier reto. 






Adolfo Yanes
Director de Tecnología

Comentarios