Improve types & remove some lodash from state engine

Signed-off-by: Christina Ying Wang <christina@balena.io>
This commit is contained in:
Christina Ying Wang 2024-01-09 13:07:35 -08:00
parent 4596149d0e
commit b9a6a6b685
2 changed files with 22 additions and 26 deletions

View File

@ -292,7 +292,7 @@ export class App {
private compareServices(
current: Service[],
target: Service[],
containerIds: Dictionary<string>,
containerIds: UpdateState['containerIds'],
): {
installPairs: Array<ChangingPair<Service>>;
removePairs: Array<ChangingPair<Service>>;
@ -496,14 +496,11 @@ export class App {
private generateStepsForService(
{ current, target }: ChangingPair<Service>,
context: {
availableImages: Image[];
downloading: string[];
targetApp: App;
containerIds: Dictionary<string>;
networkPairs: Array<ChangingPair<Network>>;
volumePairs: Array<ChangingPair<Volume>>;
servicePairs: Array<ChangingPair<Service>>;
},
} & UpdateState,
): Nullable<CompositionStep> {
if (current?.status === 'Stopping') {
// There's a kill step happening already, emit a noop to ensure
@ -664,7 +661,7 @@ export class App {
target: Service,
targetApp: App,
needsDownload: boolean,
availableImages: Image[],
availableImages: UpdateState['availableImages'],
networkPairs: Array<ChangingPair<Network>>,
volumePairs: Array<ChangingPair<Volume>>,
servicePairs: Array<ChangingPair<Service>>,
@ -728,7 +725,7 @@ export class App {
private dependenciesMetForServiceStart(
target: Service,
targetApp: App,
availableImages: Image[],
availableImages: UpdateState['availableImages'],
networkPairs: Array<ChangingPair<Network>>,
volumePairs: Array<ChangingPair<Volume>>,
servicePairs: Array<ChangingPair<Service>>,
@ -785,14 +782,14 @@ export class App {
// block the killing too much, potentially causing a deadlock)
private dependenciesMetForServiceKill(
targetApp: App,
availableImages: Image[],
availableImages: UpdateState['availableImages'],
) {
return this.targetImagesReady(targetApp.services, availableImages);
}
private targetImagesReady(
targetServices: Service[],
availableImages: Image[],
availableImages: UpdateState['availableImages'],
) {
return targetServices.every((service) =>
availableImages.some(

View File

@ -21,6 +21,7 @@ import { lock } from '../lib/update-lock';
import { checkTruthy } from '../lib/validation';
import App from './app';
import type { UpdateState } from './app';
import * as volumeManager from './volume-manager';
import * as networkManager from './network-manager';
import * as serviceManager from './service-manager';
@ -159,9 +160,11 @@ export async function inferNextSteps(
keepImages = false,
keepVolumes = false,
delta = true,
downloading = [] as string[],
availableImages = [] as Image[],
containerIdsByAppId = {} as { [appId: number]: Dictionary<string> },
downloading = [] as UpdateState['downloading'],
availableImages = [] as UpdateState['availableImages'],
containerIdsByAppId = {} as {
[appId: number]: UpdateState['containerIds'];
},
} = {},
) {
const currentAppIds = Object.keys(currentApps).map((i) => parseInt(i, 10));
@ -651,7 +654,7 @@ export function bestDeltaSource(
function saveAndRemoveImages(
current: InstancedAppState,
target: InstancedAppState,
availableImages: imageManager.Image[],
availableImages: UpdateState['availableImages'],
skipRemoval: boolean,
): CompositionStep[] {
type ImageWithoutID = Omit<imageManager.Image, 'dockerImageId' | 'id'>;
@ -670,9 +673,8 @@ function saveAndRemoveImages(
.filter((img) => img[1] != null)
.value();
const availableWithoutIds: ImageWithoutID[] = _.map(
availableImages,
(image) => _.omit(image, ['dockerImageId', 'id']),
const availableWithoutIds: ImageWithoutID[] = availableImages.map((image) =>
_.omit(image, ['dockerImageId', 'id']),
);
const currentImages = _.flatMap(current, (app) =>
@ -692,18 +694,16 @@ function saveAndRemoveImages(
const targetServices = Object.values(target).flatMap((app) => app.services);
const targetImages = targetServices.map(imageManager.imageFromService);
const availableAndUnused = _.filter(
availableWithoutIds,
const availableAndUnused = availableWithoutIds.filter(
(image) =>
!_.some(currentImages.concat(targetImages), (imageInUse) => {
!currentImages.concat(targetImages).some((imageInUse) => {
return _.isEqual(image, _.omit(imageInUse, ['dockerImageId', 'id']));
}),
);
const imagesToDownload = _.filter(
targetImages,
const imagesToDownload = targetImages.filter(
(targetImage) =>
!_.some(availableImages, (available) =>
!availableImages.some((available) =>
imageManager.isSameImage(available, targetImage),
),
);
@ -713,10 +713,9 @@ function saveAndRemoveImages(
);
// Images that are available but we don't have them in the DB with the exact metadata:
const imagesToSave: imageManager.Image[] = _.filter(
targetImages,
const imagesToSave: imageManager.Image[] = targetImages.filter(
(targetImage) => {
const isActuallyAvailable = _.some(availableImages, (availableImage) => {
const isActuallyAvailable = availableImages.some((availableImage) => {
// There is an image with same image name or digest
// on the database
if (imageManager.isSameImage(availableImage, targetImage)) {
@ -734,7 +733,7 @@ function saveAndRemoveImages(
});
// There is no image in the database with the same metadata
const isNotSaved = !_.some(availableWithoutIds, (img) =>
const isNotSaved = !availableWithoutIds.some((img) =>
_.isEqual(img, targetImage),
);