@@ -32,9 +32,9 @@ import kotlin.Throws
3232 * class directly if you need to do low-level plumbing:
3333 *
3434 * ```java
35- * var dag = new DagDef("java_etl")
36- * .addTask ("extract", Extract.class)
37- * .addTask( "load", Load.class);
35+ * var dag = new DagDef("java_etl");
36+ * var extract = dag.task ("extract", Extract.class);
37+ * extract.before(dag.task( "load", Load.class) );
3838 * ```
3939 *
4040 * @param id Dag identifier. Must contain only ASCII alphanumeric characters,
@@ -62,12 +62,41 @@ class DagDef(
6262 definition : Class <out Task >,
6363 ): DagDef = addTask(TaskDef (id, definition))
6464
65+ /* *
66+ * Creates a task, registers it, and hands back its handle — so there is no
67+ * second `addTask` call to forget, and the handle is ready to wire edges
68+ * with [Deps.Flow.before].
69+ *
70+ * ```java
71+ * var extract = dag.task("extract", Extract.class);
72+ * var load = dag.task("load", Load.class);
73+ * extract.before(load);
74+ * ```
75+ *
76+ * @param id Task identifier, unique within this Dag.
77+ * @param definition Class that implements [Task]. Must have a public no-arg
78+ * constructor.
79+ * @return The handle representing this task.
80+ * @throws IllegalArgumentException if a task with the same ID is already
81+ * registered.
82+ */
83+ fun <T > task (
84+ id : String ,
85+ definition : Class <out Task >,
86+ ): TaskRef <T > {
87+ val def = TaskDef (id, definition)
88+ addTask(def)
89+ return TaskRef (def)
90+ }
91+
6592 /* *
6693 * Registers a task with this Dag.
6794 *
6895 * A [TaskDef] belongs to at most one [DagDef]; registering the same instance
6996 * with a second Dag, or twice with the same one, fails. Task IDs must be
70- * unique within a Dag.
97+ * unique within a Dag. Upstream tasks referenced via [TaskDef.dependsOn]
98+ * must be registered with the same Dag by the time it is added to a
99+ * [Bundle].
71100 *
72101 * @param task Task definition to register.
73102 * @return This Dag, for chaining.
@@ -84,13 +113,35 @@ class DagDef(
84113 task.owner = this
85114 return this
86115 }
116+
117+ /* *
118+ * Registers a task with this Dag, adding [upstreams] as its dependencies.
119+ *
120+ * Equivalent to `addTask(task.dependsOn(...))`; see [addTask] and
121+ * [TaskDef.dependsOn].
122+ *
123+ * @param task Task definition to register.
124+ * @param upstreams Tasks that [task] depends on (its upstream tasks).
125+ * @return This Dag, for chaining.
126+ * @throws IllegalArgumentException if the task already belongs to a Dag or a
127+ * task with the same ID is already registered.
128+ */
129+ fun addTask (
130+ task : TaskDef ,
131+ upstreams : List <TaskDef >,
132+ ): DagDef {
133+ upstreams.forEach { task.dependsOn(it) }
134+ return addTask(task)
135+ }
87136}
88137
89138/* *
90- * One task definition: its ID and the class that implements it.
139+ * One task definition: its ID, the class that implements it, and its upstream
140+ * dependencies.
91141 *
92142 * ```java
93143 * var extract = new TaskDef("extract", Extract.class);
144+ * var load = new TaskDef("load", Load.class).dependsOn(extract);
94145 * ```
95146 *
96147 * @param id Task identifier, unique within a [DagDef].
@@ -110,7 +161,22 @@ class TaskDef(
110161 validateTaskInput(definition)
111162 }
112163
164+ internal val upstreams = linkedSetOf<TaskDef >()
113165 internal var owner: DagDef ? = null
166+
167+ /* *
168+ * Declares that this task runs after [upstreams].
169+ *
170+ * Referenced tasks must be registered with the same [DagDef] as this task by
171+ * the time it is added to a [Bundle].
172+ *
173+ * @param upstreams Tasks this task depends on.
174+ * @return This task definition, for chaining.
175+ */
176+ fun dependsOn (vararg upstreams : TaskDef ): TaskDef {
177+ this .upstreams + = upstreams
178+ return this
179+ }
114180}
115181
116182/* *
0 commit comments