Skip to content

TinyOrch Source Code Analysis

Internal Lookup Functions

static int find_flow(const tiny_orch_t *orch, const char *name)

Iterates the flows[] table, matching name. All public API flow lookups go through this function to avoid code duplication.

Flow Definition

create — Create a Flow

Check for duplicate name → find a free slot → initialize state to DEFINED. The step table is populated by subsequent step() calls.

step — Add a Step

tiny_orch_err_t tiny_orch_step(tiny_orch_t *orch, ...)

Key validation chain:

1. Check if the flow exists
2. Check if step_index is out of bounds
3. bench_get(src_name) → does it exist? What type is it?
4. bench_get_tool_fn(tool_name) → is it registered? What is the input type?
5. src_type == tool_in_type ? → pass
6. Record step {src_name, tool_name, dst_name}
7. Update step_count = max(step_count, step_index + 1)

Step Index

Indices need not be contiguous. step(flow, 0, ...) + step(flow, 2, ...) produces two steps; index 1 is automatically skipped.

Execution Engine

execute_step — Execute a Single Step

static tiny_orch_err_t execute_step(tiny_orch_t *orch,
                                     const tiny_orch_step_t *step)

Flow:

1. bench_get(step.src)           → get source data pointer + type
2. bench_get_tool_fn(step.tool)  → get function pointer + input/output types
3. fn(src_data, dst_data)        → call tool
4. bench_put(step.dst, dst_data, dst_len, fn_out_type)
                                 → update destination slot type

The tool function's dst_data comes from bench_get(step.dst) — the destination slot must be pre-allocated via put before execution.

go — Execute a Flow

tiny_orch_err_t tiny_orch_go(tiny_orch_t *orch, const char *flow_name)

Iterates through steps[], skipping unused indices, executing execute_step in order. Updates last_executed on each successful step. On failure, sets state to ERROR and returns the specific error code.

run — One-Shot Single Step

Constructs a temporary tiny_orch_step_t and calls execute_step directly. Does not modify any flow state.

MQTT Command Parsing

In the MQTT callback, ORCH,* commands are parsed into corresponding TinyOrch API calls:

MQTT Command C API Call
ORCH,CREATE,name tiny_orch_create(orch, name)
ORCH,STEP,name,idx,src,tool,dst tiny_orch_step(orch, name, idx, src, tool, dst)
ORCH,GO,name tiny_orch_go(orch, name)
ORCH,RUN,src,tool,dst tiny_orch_run(orch, src, tool, dst)
ORCH,STATUS,name tiny_orch_status(orch, name, &state)
ORCH,LIST tiny_orch_list_flows(orch, names, max)
ORCH,DESTROY,name tiny_orch_destroy(orch, name)

Commands are first copied to a null-terminated local buffer before parsing, avoiding sscanf issues caused by non-null-terminated MQTT data.