diff --git a/src/compose/images.ts b/src/compose/images.ts index e57185c6..67f8bcb6 100644 --- a/src/compose/images.ts +++ b/src/compose/images.ts @@ -125,29 +125,26 @@ const runningTasks: { [imageName: string]: ImageTask } = {}; function reportEvent(event: 'start' | 'update' | 'finish', state: Image) { const { name: imageName } = state; - // Emit by default if a start event is reported - let emitChange = event === 'start'; - // Get the current task and update it in memory - const currentTask = - event === 'start' ? createTask(state) : runningTasks[imageName]; + const currentTask = runningTasks[imageName] ?? createTask(state); runningTasks[imageName] = currentTask; - // TODO: should we assert that the current task exists at this point? - // On update, update the corresponding task with the new state if it exists - if (event === 'update' && currentTask) { - const [updatedTask, changed] = currentTask.update(state); - runningTasks[imageName] = updatedTask; - emitChange = changed; - } + const stateChanged = (() => { + switch (event) { + case 'start': + return true; // always report change on start + case 'update': + const [updatedTask, changedAfterUpdate] = currentTask.update(state); + runningTasks[imageName] = updatedTask; + return changedAfterUpdate; // report change only if the task context changed + case 'finish': + const [, changedAfterFinish] = currentTask.finish(); + delete runningTasks[imageName]; + return changedAfterFinish; // report change depending on the state of the task + } + })(); - // On update, update the corresponding task with the new state if it exists - if (event === 'finish' && currentTask) { - [, emitChange] = currentTask.finish(); - delete runningTasks[imageName]; - } - - if (emitChange) { + if (stateChanged) { events.emit('change'); } } @@ -172,7 +169,7 @@ export function imageFromService(service: ServiceInfo): Image { export async function triggerFetch( image: Image, opts: FetchOptions, - onFinish = _.noop, + onFinish: (success: boolean) => void, serviceName: string, ): Promise { const appUpdatePollInterval = await config.get('appUpdatePollInterval'); @@ -202,8 +199,7 @@ export async function triggerFetch( let success: boolean; try { const imageName = normalise(image.name); - image = _.clone(image); - image.name = imageName; + image = { ...image, name: imageName }; // Look for a matching image on the engine const img = await inspectByName(image.name); @@ -214,8 +210,7 @@ export async function triggerFetch( // Create image on the database if it already exists on the engine await markAsSupervised({ ...image, dockerImageId: img.Id }); - onFinish(true); - return; + success = true; } catch (e) { if (!NotFoundError(e)) { if (!(e instanceof ImageDownloadBackoffError)) {