Skip to content

Commit d36bd24

Browse files
committed
feat: #9 cancel next tasks in task group if the current task fails
1 parent 6a6ddfc commit d36bd24

File tree

10 files changed

+41
-31
lines changed

10 files changed

+41
-31
lines changed

api-nodes/Http/Controllers/NextTaskController.php

+8-4
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ public function __invoke(Node $node)
2020

2121
$taskGroup = $node->taskGroups()->inProgress()->first();
2222

23-
$task = $taskGroup ? $this->getNextTaskFromGroup($taskGroup) : $this->pickNextTask($node);
23+
$task = $taskGroup ? $this->getNextTaskFromGroup($node, $taskGroup) : $this->pickNextTask($node);
2424
if ($task) {
2525
if ($task instanceof Response) {
2626
return $task;
@@ -38,7 +38,7 @@ public function __invoke(Node $node)
3838
], 204);
3939
}
4040

41-
protected function getNextTaskFromGroup(NodeTaskGroup $taskGroup)
41+
protected function getNextTaskFromGroup(Node $node, NodeTaskGroup $taskGroup)
4242
{
4343
if ($taskGroup->tasks()->running()->first()) {
4444
return new Response([
@@ -49,7 +49,7 @@ protected function getNextTaskFromGroup(NodeTaskGroup $taskGroup)
4949
$task = $taskGroup->tasks()->pending()->first();
5050

5151
if ($task) {
52-
$task->start();
52+
$task->start($node);
5353

5454
return $task;
5555
}
@@ -63,9 +63,13 @@ protected function pickNextTask(Node $node)
6363
return $query->where('node_id', $node->id)->orWhere('node_id', null);
6464
})->pending()->first();
6565

66+
if (!$taskGroup) {
67+
return null;
68+
}
69+
6670
$task = $taskGroup->tasks()->first();
6771

68-
$taskGroup->startTask($node, $task);
72+
$task->start($node);
6973

7074
return $task;
7175
}

api-nodes/Http/Controllers/TaskController.php

+2-2
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ public function complete(NodeTask $task, Request $request)
2222

2323
$result = TaskResultCast::RESULT_BY_TYPE[$task->type]::validateAndCreate($request->all());
2424

25-
$task->taskGroup->completeTask($task, $result);
25+
$task->complete($result);
2626

2727
return new Response('', 204);
2828
}
@@ -39,7 +39,7 @@ public function fail(NodeTask $task, Request $request)
3939

4040
$result = ErrorResult::validateAndCreate($request->all());
4141

42-
$task->taskGroup->failTask($task, $result);
42+
$task->fail($result);
4343

4444
return new Response('', 204);
4545
}

app/Casts/TaskResultCast.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ public function get(Model $model, string $key, mixed $value, array $attributes):
3232
return ErrorResult::from($value);
3333
}
3434

35-
if ($model->is_ended) {
35+
if ($value != null) {
3636
return self::RESULT_BY_TYPE[$model->type]::from($value);
3737
}
3838

app/Http/Controllers/NodeController.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ public function show(Node $node)
4444
{
4545
$initTaskGroup = $node->tasks()->inProgress()->ofType(InitSwarmTaskPayload::class)->first()?->taskGroup->with('tasks')->first();
4646
if (!$initTaskGroup) {
47-
$initTaskGroup = $node->tasks()->failed()->ofType(InitSwarmTaskPayload::class)->first()?->taskGroup->with('tasks')->first();
47+
$initTaskGroup = $node->tasks()->unsuccessful()->ofType(InitSwarmTaskPayload::class)->first()?->taskGroup->with('tasks')->first();
4848
}
4949

5050
return Inertia::render('Nodes/Show', ['node' => $node, 'initTaskGroup' => $initTaskGroup]);

app/Models/NodeTask.php

+11-3
Original file line numberDiff line numberDiff line change
@@ -97,8 +97,12 @@ public function getIsFailedAttribute()
9797
return $this->status === TaskStatus::Failed;
9898
}
9999

100-
public function start(): void
100+
public function start(Node $node): void
101101
{
102+
if ($this->taskGroup->is_pending) {
103+
$this->taskGroup->start($node);
104+
}
105+
102106
$this->status = TaskStatus::Running;
103107
$this->started_at = now();
104108
$this->save();
@@ -116,7 +120,8 @@ public function complete(AbstractTaskResult $result): void
116120
$this->taskGroup->save();
117121
}
118122

119-
event(new self::TYPE_TO_EVENT_COMPLETED[$this->type]($this));
123+
$eventMap = self::TYPE_TO_EVENT_COMPLETED;
124+
event(new $eventMap[$this->type]($this));
120125
}
121126

122127
public function fail(AbstractTaskResult $result): void
@@ -129,6 +134,9 @@ public function fail(AbstractTaskResult $result): void
129134
$this->taskGroup->status = TaskStatus::Failed;
130135
$this->taskGroup->save();
131136

132-
event(new self::TYPE_TO_EVENT_FAILED[$this->type]($this));
137+
$this->taskGroup->tasks()->pending()->update(['status' => TaskStatus::Canceled]);
138+
139+
$eventMap = self::TYPE_TO_EVENT_FAILED;
140+
event(new $eventMap[$this->type]($this));
133141
}
134142
}

app/Models/NodeTask/TaskStatus.php

+2-2
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,12 @@ enum TaskStatus: string
88
case Running = 'running';
99
case Completed = 'completed';
1010
case Failed = 'failed';
11-
case Cancelled = 'cancelled';
11+
case Canceled = 'canceled';
1212

1313
public function isEnded(): bool
1414
{
1515
return $this->value === TaskStatus::Completed->value
1616
|| $this->value === TaskStatus::Failed->value
17-
|| $this->value === TaskStatus::Cancelled->value;
17+
|| $this->value === TaskStatus::Canceled->value;
1818
}
1919
}

app/Models/NodeTaskGroup.php

+1-15
Original file line numberDiff line numberDiff line change
@@ -43,25 +43,11 @@ public function node(): BelongsTo
4343
return $this->belongsTo(Node::class);
4444
}
4545

46-
public function startTask(Node $node, NodeTask $task): void
46+
public function start(Node $node): void
4747
{
4848
$this->status = TaskStatus::Running;
4949
$this->node_id = $node->id;
5050
$this->started_at = now();
5151
$this->save();
52-
53-
$task->start();
54-
}
55-
56-
public function completeTask(NodeTask $task, AbstractTaskResult $result): void
57-
{
58-
59-
60-
$task->complete($result);
61-
}
62-
63-
public function failTask(NodeTask $task, AbstractTaskResult $result): void
64-
{
65-
$task->fail($result);
6652
}
6753
}

app/Traits/HasTaskStatus.php

+10
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,16 @@ public function scopeFailed(Builder $builder): Builder
3232
return $builder->where($builder->qualifyColumn('status'), TaskStatus::Failed);
3333
}
3434

35+
public function scopeUnsuccessful(Builder $builder): Builder
36+
{
37+
return $builder->whereIn($builder->qualifyColumn('status'), [TaskStatus::Failed, TaskStatus::Canceled]);
38+
}
39+
40+
public function getIsPendingAttribute() : bool
41+
{
42+
return $this->status === TaskStatus::Pending;
43+
}
44+
3545
public function getIsRunningAttribute() : bool
3646
{
3747
return $this->status === TaskStatus::Running;

resources/js/Components/NodeTasks/TaskResult.vue

+4
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,10 @@ const classes = computed(() => {
5454
<path fill-rule="evenodd" d="M2 12C2 6.477 6.477 2 12 2s10 4.477 10 10-4.477 10-10 10S2 17.523 2 12Zm7.707-3.707a1 1 0 0 0-1.414 1.414L10.586 12l-2.293 2.293a1 1 0 1 0 1.414 1.414L12 13.414l2.293 2.293a1 1 0 0 0 1.414-1.414L13.414 12l2.293-2.293a1 1 0 0 0-1.414-1.414L12 10.586 9.707 8.293Z" clip-rule="evenodd"/>
5555
</svg>
5656

57+
<svg v-if="task.status === 'canceled'"
58+
class="w-4 h-4 me-2 text-gray-800 dark:text-white" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none" viewBox="0 0 24 24">
59+
<path stroke="currentColor" stroke-linecap="round" stroke-width="2" d="m6 6 12 12m3-6a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z"/>
60+
</svg>
5761

5862

5963

resources/js/Pages/Nodes/Show.vue

+1-3
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,7 @@ defineProps([
3232

3333
<SectionBorder v-if="$props.node.online" />
3434

35-
<NewSwarmCluster v-if="$props.node.online && $props.node.swarm_id === null" :node="$props.node"/>
36-
37-
<SectionBorder v-if="$props.initTaskGroup" />
35+
<NewSwarmCluster v-if="$props.node.online && $props.node.swarm_id === null" :node="$props.node"/>
3836
<InitSwarmProgress v-if="$props.initTaskGroup" :taskGroup="$props.initTaskGroup" />
3937
</ShowLayout>
4038
</template>

0 commit comments

Comments
 (0)