Saltar al contenido principal

Visión general

Los Combinadores (Combiner), Separadores (Separator) y Transformadores (Transformer) son los tres componentes del Modelador (Modeler) que reorganizan el flujo de entidades en lugar de simplemente enrutarlas o retrasarlas. Son la forma en que modelas el ensamblaje, desensamblaje, agrupación, kitting, empaque y cualquier operación donde las entidades que entran no son las mismas que las entidades que salen. Estos componentes parecen simples — una caja con entradas y salidas — pero cada uno tiene un comportamiento específico que vale la pena entender antes de construir una operación de ensamblaje o desensamblaje, especialmente en cómo interactúan con la capacidad de Estación (Station), el traspaso de atributos y el contexto multi-entidad del DSL.

Combinador

Un Combinador (Combiner) fusiona múltiples entidades de entrada en una sola entidad de salida. Úsalo para modelar ensamblaje (partes → producto), agrupación (artículos individuales → palet), kitting (componentes → kit) o cualquier operación donde varios elementos se convierten en uno.

Lotes de entrada

El campo input_batch del Combinador tiene exactamente dos modos, elegidos desde un toggle binario Static / DSL Expression en el panel de configuración:
  • Static — un mapa {entity_type: quantity}. {tube: 1, tray: 1, label: 1} significa “espera hasta tener uno de cada antes de ensamblar”. Esta es la forma canónica de ensamblaje: diferentes recuentos de diferentes tipos de entrada alimentando una salida.
  • DSL Expression — una expresión booleana de disparo evaluada cada vez que llega una entidad. Cuando la expresión devuelve true, cada entidad acumulada se combina en una salida. Úsalo cuando la composición del lote depende del estado en tiempo de ejecución.
El modo DSL tiene dos campos en el esquema: input_entity_types (un arreglo de slugs de entidad que el Combinador acepta para validación del grafo) y batch_expr (el disparador booleano). batch_expr se ejecuta en contexto multi-entidad sobre las entidades actualmente acumuladas, por lo que puedes escribir disparadores como COUNT(1) >= MIN_BATCH AND SUM(weight) >= LOAD_THRESHOLD.

Contexto multi-entidad para atributos de salida

Una asignación de atributo de salida del Combinador se ejecuta en contexto multi-entidad — varias entidades de entrada están en alcance a la vez. Las referencias de atributo desnudas como weight son ambiguas (¿de qué entrada?), por lo que deben envolverse en funciones de agregación:
# Atributo de salida: total_weight — suma de los pesos de entrada
SUM(weight)

# Atributo de salida: priority — máximo entre entradas
MAX(priority)

# Atributo de salida: is_rush — verdadero si alguna entrada es urgente
ANY(is_rush)

# Atributo de salida: qc_passed — verdadero solo si todas las entradas pasaron
ALL(qc_passed)
Las asignaciones de atributos de salida usan el desplegable estándar de 6 estrategias (Fixed, DSL Expression, Round Robin, Random Choice, Random, Weighted) — igual que las Fuentes (Source), Transformadores y salidas del Separador. El patrón de agregación mostrado arriba usa el modo DSL Expression.

Eventos del Combinador

Un Combinador emite tres eventos de ciclo de vida (etiquetas de UI):
  • entity consumed — se dispara para cada entidad de entrada consumida (contexto entidad-única, la entrada)
  • batch assembled — se dispara cuando se cierra el lote (contexto multi-entidad, todas las entradas)
  • entity created — se dispara cuando se emite la entidad de salida (contexto entidad-única, la salida)
El filtro entity_type en los hooks solo es válido en entity consumed (para que puedas reaccionar solo al consumo de un tipo de entrada específico).

Lotes parciales al final de la simulación

Una simulación puede terminar con entidades sentadas en un Combinador que aún no ha alcanzado su umbral de lote. Esas entidades son abandonadas: nunca se combinan, nunca producen una salida y nunca alcanzan los Sumideros (Sink) downstream. No aparecen en las métricas de rendimiento.
Las entidades de lote parcial al final de la simulación desaparecen silenciosamente. Para simulaciones cortas con tamaños de lote grandes, esto puede afectar materialmente el rendimiento reportado. O elige una duración que permita que el último lote esperado se cierre, o diseña el modelo para que los lotes no cumplidos se manifiesten como un evento explícito.

Separador

Un Separador (Separator) divide una entidad de entrada en múltiples entidades de salida. Úsalo para modelar desensamblaje (kit → componentes), desagrupación (palet → artículos individuales) o cualquier operación de “uno entra, muchos salen”.

Entidad de entrada y lote de salida

El panel de configuración del Separador tiene dos controles de nivel superior:
  • Input Entity — un solo desplegable de tipos de entidad definidos en el modelo. El Separador solo acepta entidades de este tipo.
  • Output Batch — un mapa {output_entity_type: count_expression}. Cada fila es un tipo de entidad más una expresión del DSL (una cadena) que devuelve el recuento de ese tipo a emitir por entrada. Una fila que dice component: "4" significa “emitir 4 entidades de tipo component por entrada”. Los recuentos variables pueden leer atributos de entrada: component: "input_quantity".
Las expresiones de recuento de salida se ejecutan en contexto entidad-única con los atributos de la entidad de entrada en alcance (weight, priority, etc.).

Atributos de salida

Cada tipo de salida tiene sus propias asignaciones de atributos en el campo separado attribute_assignments del esquema (nota el plural: es attribute_assignments en Separador, distinto del singular attribute_assignment en Combinador y Transformador). attribute_assignments es un mapa anidado: {output_entity_type: {attribute_name: assignment}}. Cada asignación usa el desplegable de 6 estrategias. Las asignaciones de atributos de salida se ejecutan en contexto entidad-única con los atributos de la entidad de entrada en alcance — las referencias a weight, priority, etc. leen la entrada, y la asignación produce valores para la entidad de salida que se está creando. Un patrón común: dividir una cantidad entre las salidas de manera uniforme (weight / output_count) o copiar una clasificación de la entrada a cada salida.
Las salidas del Separador no heredan automáticamente los atributos de la entrada. Cada atributo de salida que te importe debe ser asignado explícitamente — más comúnmente con DSL Expression haciendo referencia al atributo de entrada por nombre. Omitir una asignación le da a ese atributo de salida el valor por defecto del tipo (0, "" o FALSE), no el valor de la entrada.

Eventos del Separador

Un Separador emite tres eventos de ciclo de vida:
  • entity consumed — se dispara cuando se consume la entrada (contexto entidad-única, la entrada)
  • entity created — se dispara para cada entidad de salida (contexto entidad-única, la salida). Solo este evento acepta el filtro entity_type.
  • batch created — se dispara una vez después de que se producen todas las salidas (contexto multi-entidad, todas las salidas)

Interacción con la capacidad de Estación

El linaje del Separador en una estación a menudo se malinterpreta. El modelo correcto:
  • La entidad de entrada consume un slot de capacidad cuando entra en la estación.
  • El Separador divide esa entrada en varias entidades de salida. Las salidas son descendientes de la entrada — comparten el linaje de la entrada.
  • El slot único se libera solo cuando todos los descendientes han salido de la estación. Si se produjeron tres salidas, el slot permanece ocupado hasta que las tres salgan.
Las salidas no consumen cada una su propio slot. Comparten el slot del ancestro a través de la regla de rastreo de linaje. Así que una estación con capacidad 5 puede contener 5 entradas de Separador a la vez sin importar cuántas salidas produzca cada una — pero el slot de cada entrada permanece ocupado más tiempo si produce más salidas (porque la condición de “todos los descendientes han salido” tarda más en satisfacerse).
Las claves de capacidad de Estación son solo tipos de entidades que entran. Incluir un tipo de salida creado internamente en el mapa de capacidad de una estación falla la validación: el esquema requiere que las entradas de capacidad coincidan con tipos que realmente entran en la estación, no tipos creados dentro de ella.

Transformador

Un Transformador (Transformer) produce una nueva entidad de salida de un tipo diferente, reemplazando la entrada en el flujo. El número de entidades no cambia (uno entra, uno sale), pero los componentes downstream ven una entidad de tipo diferente después del Transformador. Usa un Transformador para modelar operaciones donde la cosa sobre la que se está trabajando se convierte en una cosa diferente después del procesamiento: materia prima → WIP, WIP → producto terminado, pieza en bruto → pintada, componente → componente inspeccionado.

Asignación de atributos en la salida

Un Transformador emite una nueva entidad de un tipo diferente, con su propio mapa attribute_assignment (singular). Cada asignación usa el desplegable de 6 estrategias — elige DSL Expression cuando el valor sea computado. Las asignaciones se ejecutan en contexto entidad-única con los atributos de la entidad de entrada accesibles y pueden referenciar:
  • Los atributos de la entidad de entrada — útil para llevar el contexto hacia adelante
  • El estado de simulaciónSIM_TIME para marcar cuándo ocurrió la transformación
  • Variables de estado y constantes — para aplicar valores específicos del turno o la operación
Los atributos de salida del Transformador no heredan de la entrada. Ningún atributo se transfiere automáticamente. Cada atributo de salida que quieras debe ser asignado explícitamente — típicamente como DSL Expression haciendo referencia al atributo de entrada por nombre (weight, priority, customer_id). Las asignaciones faltantes toman el valor cero del tipo, que es pérdida silenciosa de datos.

Eventos del Transformador

Un Transformador emite dos eventos de ciclo de vida:
  • entity consumed — la entrada que se está consumiendo
  • entity created — la salida que se está emitiendo
Ambos se ejecutan en contexto entidad-única. No hay evento de lote: el Transformador es estrictamente 1-entra, 1-sale.

Cuándo usar un Transformador vs. un Proceso

Si todo lo que necesitas es “la entidad se retrasa por X minutos, opcionalmente reteniendo un recurso”, usa un Proceso (Process). Usa un Transformador cuando:
  • El enrutamiento downstream de la entidad depende de su tipo (enviada a diferentes procesos para diferentes tipos)
  • El análisis de resultados agrupa por tipo de entidad (rendimiento por producto, no agregado)
  • La entidad conceptualmente se convierte en algo diferente como parte de la operación
Un Transformador no consume tiempo de procesamiento por sí mismo: si la transformación toma tiempo real, combínalo con un Proceso precedente.

Contextos del DSL en estos componentes

SuperficieContexto
Combiner attribute_assignment (atributos de salida)Multi-entidad (todas las entradas)
Combiner batch_expr (disparador DSL)Multi-entidad (entradas acumuladas)
Combiner hook on_entity_consumedEntidad-única (la entrada)
Combiner hook on_batch_assembledMulti-entidad (todas las entradas)
Combiner hook on_entity_createdEntidad-única (la salida)
Separator output_batch expresiones de recuentoEntidad-única (la entrada)
Separator attribute_assignments (por salida)Entidad-única (la entrada)
Separator hook on_entity_consumedEntidad-única (la entrada)
Separator hook on_entity_createdEntidad-única (la salida, por salida)
Separator hook on_batch_createdMulti-entidad (todas las salidas)
Transformer attribute_assignment (atributos de salida)Entidad-única (la entrada)
Transformer hooksEntidad-única
Las cuatro superficies multi-entidad en la plataforma están todas en Combinadores y Separadores: Combiner attribute_assignment, Combiner batch_expr, Combiner on_batch_assembled, Separator on_batch_created. Cada otra superficie del DSL es sin-entidad o entidad-única.

Colocación obligatoria en Estación

Combinador, Separador y Transformador deben colocarse cada uno dentro de una Estación. El campo station_id por defecto es null en el esquema, pero la validación rechaza modelos donde no está establecido: cada componente de batching necesita un contenedor de estación.

Event Hooks y Listeners

Los tres componentes llevan tanto una sección Event Hooks como una sección separada Event Listeners en el panel de configuración, exactamente como cualquier otro componente de flujo. Los listeners reaccionan a emisiones de tema y siempre se ejecutan en contexto sin-entidad. Ver Sistema de Eventos para el patrón completo.

Patrones

Celda de ensamblaje: Fuentes → Búferes (Buffer) → Combinador dentro de una Estación → Sumidero. Cada Fuente alimenta un tipo de componente diferente; el modo Static del Combinador declara {tube: 1, tray: 1, label: 1}; la Estación modela la restricción física del espacio de trabajo. Empaque de kit: Proceso (recoger componentes) → Combinador (agrupar en kit) → Proceso (sellar/etiquetar) → Sumidero. El Combinador produce la entidad del kit; los procesos downstream operan en kits. Desensamblaje para retrabajo: Enrutador (Router) (enviar candidatos de retrabajo aquí) → Separador (dividir el kit de vuelta en componentes) → búferes de componentes individuales. Los atributos de cada salida se asignan explícitamente (rework_reason, original_kit_id). Línea de pintura: Fuente (partes en bruto) → Proceso (pintar) → Transformador (raw_part → painted_part) → Proceso (inspeccionar) → Enrutador (enrutar por qc_passed). El cambio de tipo después de pintar permite que los procesos downstream se especialicen en painted_part.

Consejos

  • Los Combinadores son donde vive la agregación. Si estás tratando de calcular una suma o máximo a través de un grupo de entidades en cualquier otro lugar, probablemente estés peleando con el modelo: reestructura para que la agregación ocurra en una salida de Combinador.
  • La capacidad basada en linaje es la razón por la que las estaciones con Combinadores o Separadores pueden comportarse de manera contraintuitiva. Los slots se consumen al entrar y se liberan cuando todos los descendientes del linaje salen — no basado en el tamaño del lote o la aritmética del recuento de salidas.
  • Transformador sobre Proceso cuando el tipo importa downstream. Los Procesos cambian estado; los Transformadores cambian identidad. Usa cada uno para su propósito.
  • El traspaso de atributos nunca es automático en Transformadores o Separadores. Cada atributo de salida deseado debe ser asignado explícitamente.
  • El modo DSL del Combinador es para lotes de forma en tiempo de ejecución. Si el tamaño de tu lote es constante, el modo Static con un mapa {type: count} es más claro y más rápido.