Skip to content

Handoff row

The physical worldMQTTSDKDashboardhandoffunitsMachines.handoffProgressMachines.handoffDecisionslots

Each hop between stations is one row naming the units that move; it resolves with a receipt or a typed error code.

The situation

Units move from one machine to the next in groups. The sender releases them, the receiver scans them in, and sometimes only some arrive. The workflow needs to know exactly which, and decide what happens next.

The recipe

Park a handoff row on the receiver’s role. Its metadata says what moves:

workflows/unit-route.ts
import { conditionalAccumulator, Machines } from '@hotmeshio/long-tail';
const result = await conditionalAccumulator(`handoff-${routeKey}-s2-a1`, {
role: 'bond-cell',
type: Machines.ROW_TYPE.HANDOFF,
description: 'U1, U2: cut-01 to bond-01',
metadata: {
siteId: 'site-1', lineId: 'line-1',
units: [{ unitId: 'U1', carrierId: 'C-7' }, { unitId: 'U2', carrierId: 'C-7' }],
jobId: `${routeKey}-bond`, senderJobId: `${routeKey}-cut`,
fromMachine: 'cut-01', toMachine: 'bond-01',
recipeId: 'RCP-BOND-A', recipeVersion: '2', process: 'bond', attempt: 1,
},
accumulate: {},
timeout: '30m',
});

The gateway records each release and each arrival as items, and resolves the row once every unit is in: { received: true, receiver: 'bond-01', units: ['U1', 'U2'] }. Otherwise it resolves { received: false, errorCode, detail } with codes such as dispatch-refused, no-reply, sender-rejected or jam. Machines.handoffProgress(units, items) reads { released, arrived, missing }, and Machines.handoffDecisions(errorCode) offers the default retry, manual and scrap choices that fit.

The guarantee

When a sender finishes a unit, the release and the trace and lots facets land in the same statement, so the rows that used a lot are one containment query. A handoff that ends without every unit withdraws only the jobs none of whose units arrived. See Machines.