mirror of
https://github.com/apache/airflow.git
synced 2026-11-04 07:12:48 +00:00
A mixed-language Dag is declared in Python: the `@task.stub` per task, the queue that routes it to the Node coordinator, and the order between them all live there. The SDK said otherwise. The only way to attach a handler was `new Dag(dagId)` plus `dag.task(taskId, fn)`, so every mixed-language bundle constructed a Dag object for a Dag it does not own. `new TaskHandler(dagId, taskId, handler)` binds a function to the task it implements and carries nothing else: no schedule, no task order, no dag_id of its own. A handler is a value with no call signature, so wiring one the way a natively declared task is wired is a compile error rather than a runtime throw. `Dag` becomes exclusively the native case, and a dag_id is one or the other: a native Dag attaches its own tasks, so registering a handler for one is rejected rather than silently becoming a second, disagreeing source for its task list. `Registerable` gains its second arm rather than the bundle gaining a second verb, so one `register` call still lists everything a bundle provides in any mixture. What that changes underneath is the key: a bundle now holds one entry per dag_id and dispatches on the `(dag_id, task_id)` pair, so one bundle can provide for several Dags and the same task_id under two of them is two different handlers. The example and the end-to-end test both exercise that, with `typescript_example` and the new `typescript_taskflow_example` each declaring a `build_message` served from one bundle.mjs.