Cancelling the running task (executing of a scaffolder template)

Signed-off-by: Bogdan Nechyporenko <bnechyporenko@bol.com>
This commit is contained in:
Bogdan Nechyporenko
2023-03-09 15:40:47 +01:00
parent cec2e622d6
commit e27ddc36da
597 changed files with 6911 additions and 1680 deletions
+11 -3
View File
@@ -24,10 +24,11 @@ import { TemplateParameterSchema } from '../types';
* @public
*/
export type ScaffolderTaskStatus =
| 'cancelled'
| 'completed'
| 'failed'
| 'open'
| 'processing'
| 'failed'
| 'completed'
| 'skipped';
/**
@@ -96,7 +97,7 @@ export type ScaffolderTaskOutput = {
* @public
*/
export type LogEvent = {
type: 'log' | 'completion';
type: 'log' | 'completion' | 'cancelled';
body: {
message: string;
stepId?: string;
@@ -196,6 +197,13 @@ export interface ScaffolderApi {
getTask(taskId: string): Promise<ScaffolderTask>;
/**
* Sends a signal to a task broker to cancel the running task by taskId.
*
* @param taskId - the id of the task
*/
cancelTask(taskId: string): Promise<void>;
listTasks?(options: {
filterByOwnership: 'owned' | 'all';
}): Promise<{ tasks: ScaffolderTask[] }>;
@@ -44,6 +44,7 @@ export type ScaffolderStep = {
* @public
*/
export type TaskStream = {
cancelled: boolean;
loading: boolean;
error?: Error;
stepLogs: { [stepId in string]: string[] };
@@ -66,6 +67,7 @@ type ReducerLogEntry = {
type ReducerAction =
| { type: 'INIT'; data: ScaffolderTask }
| { type: 'CANCELLED' }
| { type: 'LOGS'; data: ReducerLogEntry[] }
| { type: 'COMPLETED'; data: ReducerLogEntry }
| { type: 'ERROR'; data: Error };
@@ -111,7 +113,7 @@ function reducer(draft: TaskStream, action: ReducerAction) {
}
if (
['cancelled', 'failed', 'completed'].includes(currentStep.status)
['cancelled', 'completed', 'failed'].includes(currentStep.status)
) {
currentStep.endedAt = entry.createdAt;
}
@@ -131,6 +133,11 @@ function reducer(draft: TaskStream, action: ReducerAction) {
return;
}
case 'CANCELLED': {
draft.cancelled = true;
return;
}
case 'ERROR': {
draft.error = action.data;
draft.loading = false;
@@ -151,6 +158,7 @@ function reducer(draft: TaskStream, action: ReducerAction) {
export const useTaskEventStream = (taskId: string): TaskStream => {
const scaffolderApi = useApi(scaffolderApiRef);
const [state, dispatch] = useImmerReducer(reducer, {
cancelled: false,
loading: true,
completed: false,
stepLogs: {} as { [stepId in string]: string[] },
@@ -196,6 +204,9 @@ export const useTaskEventStream = (taskId: string): TaskStream => {
switch (event.type) {
case 'log':
return collectedLogEvents.push(event);
case 'cancelled':
dispatch({ type: 'CANCELLED' });
return undefined;
case 'completion':
emitLogs();
dispatch({ type: 'COMPLETED', data: event });
@@ -24,10 +24,10 @@ import { act, fireEvent } from '@testing-library/react';
import React from 'react';
import { Workflow } from './Workflow';
import { analyticsApiRef } from '@backstage/core-plugin-api';
import { ScaffolderApi } from '../../../api/types';
import { scaffolderApiRef } from '../../../api/ref';
import { ScaffolderApi, scaffolderApiRef } from '../../../api';
const scaffolderApiMock: jest.Mocked<ScaffolderApi> = {
cancelTask: jest.fn(),
scaffold: jest.fn(),
getTemplateParameterSchema: jest.fn(),
getIntegrationsList: jest.fn(),