El problema fundamental que aborda esta re-arquitectura es la limitación inherente de la escalabilidad de un singleton coordinador en un sistema distribuido de ejecución duradera. Originalmente diseñado para flujos de trabajo activados por humanos, el sistema Workflows de Cloudflare se encontró con un cambio cuantitativo en el patrón de carga: la proliferación de agentes autónomos que generan miles de instancias de flujo de trabajo por segundo. Este cambio expuso el cuello de botella de un único Durable Object (DO) a nivel de cuenta, que gestionaba toda la metadata y el ciclo de vida de las instancias, limitando la concurrencia y la tasa de creación.

La solución implica la descentralización de la lógica de coordinación y la distribución de la gestión de estado. Al introducir componentes intermedios que actúan como coordinadores de subconjuntos (por ejemplo, por flujo de trabajo), se logra una escalabilidad horizontal. Este patrón es común en sistemas distribuidos donde un coordinador central se convierte en un punto de contención a medida que la carga aumenta, y la respuesta es siempre distribuir la responsabilidad y el estado.

Arquitectura del Sistema

La arquitectura original (V1) de Workflows se basaba en Durable Objects (DOs) de Cloudflare, que proporcionan coordinación y almacenamiento con respaldo SQLite. Un DO 'Account' centralizaba la gestión de todos los flujos de trabajo e instancias para una cuenta, mientras que cada instancia de flujo de trabajo era ejecutada por un DO 'Engine' dedicado. Este diseño, aunque simple, generó un cuello de botella en el DO 'Account' debido a la alta tasa de creación y finalización de instancias.

La arquitectura V2 introduce dos componentes clave para la escalabilidad horizontal: 'SousChef' y 'Gatekeeper'. 'SousChef' es un DO que gestiona la metadata y el ciclo de vida de un subconjunto de instancias dentro de un flujo de trabajo específico, actuando como un coordinador secundario del 'Account'. Esto permite la aislación por flujo de trabajo y distribuye la carga de gestión de metadata. 'Gatekeeper' es un sistema de leasing que distribuye 'slots' de concurrencia entre los 'SousChefs'. Cuando se crea una instancia, se asigna a un 'SousChef', que solicita un slot al 'Account' a través de 'Gatekeeper'. Las comunicaciones entre 'SousChefs' y 'Account' se realizan en ciclos periódicos (una vez por segundo) y se agrupan en llamadas JSRPC para evitar la sobrecarga del 'Account'. La fuente de verdad para la existencia de una instancia se traslada a su 'Engine' individual, y se utilizan 'Durable Object Alarms' para garantizar la ejecución de tareas en segundo plano y la fiabilidad del ciclo de vida de la instancia, incluso frente a fallos o desalojos de DOs.

Flujo de Creación de Instancia V2

  1. 1 Cliente Solicita creación de instancia de Workflow
  2. 2 Control Plane Verifica versión del control plane y caché local de workflow
  3. 3 Account DO Si no está en caché, obtiene metadata de workflow (nombre, ID, versión) y la ...
  4. 4 SousChef DO Se asigna aleatoriamente un SousChef. Almacena payload y fecha de creación de...
  5. 5 SousChef DO Solicita un slot de concurrencia al Account a través de Gatekeeper (batching ...
  6. 6 Gatekeeper Distribuye slots de concurrencia entre SousChefs
  7. 7 SousChef DO Si se concede el slot, activa la ejecución de la instancia en su Engine
  8. 8 Engine DO Establece una 'alarm' para garantizar la ejecución de tareas en segundo plano
CapaTecnologíaJustificación
orchestration Cloudflare Durable Objects Primitiva fundamental para coordinación, estado duradero y ejecución de lógica de negocio distribuida. Actúan como actores con estado.
storage SQLite (respaldo de Durable Objects) Almacenamiento de estado duradero para cada Durable Object, garantizando persistencia y consistencia local.
messaging Durable Object Alarms Mecanismo de ejecución asíncrona 'at-least-once' para tareas en segundo plano y recuperación de fallos, desacoplando operaciones críticas del hot-path.

Trade-offs

Ganancias
  • ▲▲ Concurrencia de instancias
  • Tasa de creación de instancias
  • Rendimiento de listado de instancias
  • Latencia de operaciones en instancias
Costes
    export class AccountOld extends DurableObject {
      constructor(state: DurableObjectState, env: Env) {
        super(state, env);
        if (this.currentVersion === ControlPlaneVersions.SOUS_CHEFS) {
          this.sousChef = new SousChef(this.ctx, this.env);
          // await this.sousChef.setup() // Asumiendo que setup es asíncrono y se llama aquí o en otro lugar
        }
      }
    
      async updateInstance(params: UpdateInstanceParams) {
        if (this.currentVersion === ControlPlaneVersions.SOUS_CHEFS) {
          assert(this.sousChef !== undefined, 'SousChef must exist on v2');
          return this.sousChef.updateInstance(params);
        }
        // old logic remains the same
      }
    
      // @RequiresVersion<AccountOld>(ControlPlaneVersions.V1)
      // async getMetadata() { /* ... */ }
    }
    El constructor de AccountOld detecta la versión del control plane y, si es V2, inicializa una instancia de SousChef. Los métodos existentes delegan a la nueva lógica de SousChef si la versión es V2.

    Fundamentos Teóricos

    Este problema de escalabilidad de un coordinador central y su solución mediante la distribución de estado y responsabilidad resuena con principios fundamentales de sistemas distribuidos. La limitación de un singleton central es un tema recurrente en la literatura, a menudo abordado con técnicas de sharding, particionamiento o jerarquías de coordinación. Conceptos como el 'Consistent Hashing' o 'Rendezvous Hashing' son ejemplos de cómo distribuir la carga de manera uniforme entre un conjunto de nodos. La idea de un 'leasing system' como 'Gatekeeper' se alinea con los principios de coordinación distribuida y gestión de recursos compartidos, donde se otorgan permisos temporales para realizar operaciones, similar a los algoritmos de consenso o exclusión mutua distribuida. La evolución de un coordinador centralizado a una arquitectura más distribuida con coordinadores intermedios (SousChef) es una aplicación práctica del principio de dividir y conquistar para mejorar la escalabilidad y la tolerancia a fallos, un concepto explorado en trabajos seminales sobre sistemas distribuidos y bases de datos distribuidas.