Skip to content

Commit 95eda18

Browse files
committed
style: use guard clauses in processFleetResult
This function is getting a little complex to read now. Refactoring to use the guard clause pattern makes the flow clearer. Now it's more like a sequence of checks followed by a final `throw`.
1 parent 7a1302d commit 95eda18

File tree

1 file changed

+51
-47
lines changed

1 file changed

+51
-47
lines changed

lambdas/functions/control-plane/src/aws/runners.ts

Lines changed: 51 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -166,54 +166,58 @@ async function processFleetResult(
166166
): Promise<string[]> {
167167
const instances: string[] = fleet.Instances?.flatMap((i) => i.InstanceIds?.flatMap((j) => j) || []) || [];
168168

169-
if (instances.length !== runnerParameters.numberOfRunners) {
170-
logger.warn(
171-
`${
172-
instances.length === 0 ? 'No' : instances.length + ' off ' + runnerParameters.numberOfRunners
173-
} instances created.`,
174-
{ data: fleet },
175-
);
176-
const errors = fleet.Errors?.flatMap((e) => e.ErrorCode || '') || [];
177-
let failedCount = 0;
178-
179-
// Educated guess of errors that would make sense to retry based on the list
180-
// https://docs.aws.amazon.com/AWSEC2/latest/APIReference/errors-overview.html
181-
const scaleErrors = [
182-
'UnfulfillableCapacity',
183-
'MaxSpotInstanceCountExceeded',
184-
'TargetCapacityLimitExceededException',
185-
'RequestLimitExceeded',
186-
'ResourceLimitExceeded',
187-
'MaxSpotInstanceCountExceeded',
188-
'MaxSpotFleetRequestCountExceeded',
189-
'InsufficientInstanceCapacity',
190-
];
191-
192-
if (
193-
errors.some((e) => runnerParameters.onDemandFailoverOnError?.includes(e)) &&
194-
runnerParameters.ec2instanceCriteria.targetCapacityType === 'spot'
195-
) {
196-
logger.warn(`Create fleet failed, initatiing fall back to on demand instances.`);
197-
logger.debug('Create fleet failed.', { data: fleet.Errors });
198-
const numberOfInstances = runnerParameters.numberOfRunners - instances.length;
199-
const instancesOnDemand = await createRunner({
200-
...runnerParameters,
201-
numberOfRunners: numberOfInstances,
202-
onDemandFailoverOnError: ['InsufficientInstanceCapacity'],
203-
ec2instanceCriteria: { ...runnerParameters.ec2instanceCriteria, targetCapacityType: 'on-demand' },
204-
});
205-
instances.push(...instancesOnDemand);
206-
return instances;
207-
} else if ((failedCount = countScaleErrors(errors, scaleErrors)) > 0) {
208-
logger.warn('Create fleet failed, ScaleError will be thrown to trigger retry for ephemeral runners.');
209-
logger.debug('Create fleet failed.', { data: fleet.Errors });
210-
throw new ScaleError('Failed to create instance, create fleet failed.', failedCount);
211-
} else {
212-
logger.warn('Create fleet failed, error not recognized as scaling error.', { data: fleet.Errors });
213-
throw Error('Create fleet failed, no instance created.');
214-
}
169+
if (instances.length === runnerParameters.numberOfRunners) {
170+
return instances;
215171
}
216-
return instances;
172+
173+
logger.warn(
174+
`${
175+
instances.length === 0 ? 'No' : instances.length + ' off ' + runnerParameters.numberOfRunners
176+
} instances created.`,
177+
{ data: fleet },
178+
);
179+
180+
const errors = fleet.Errors?.flatMap((e) => e.ErrorCode || '') || [];
181+
182+
if (
183+
errors.some((e) => runnerParameters.onDemandFailoverOnError?.includes(e)) &&
184+
runnerParameters.ec2instanceCriteria.targetCapacityType === 'spot'
185+
) {
186+
logger.warn(`Create fleet failed, initatiing fall back to on demand instances.`);
187+
logger.debug('Create fleet failed.', { data: fleet.Errors });
188+
const numberOfInstances = runnerParameters.numberOfRunners - instances.length;
189+
const instancesOnDemand = await createRunner({
190+
...runnerParameters,
191+
numberOfRunners: numberOfInstances,
192+
onDemandFailoverOnError: ['InsufficientInstanceCapacity'],
193+
ec2instanceCriteria: { ...runnerParameters.ec2instanceCriteria, targetCapacityType: 'on-demand' },
194+
});
195+
instances.push(...instancesOnDemand);
196+
return instances;
197+
}
198+
199+
// Educated guess of errors that would make sense to retry based on the list
200+
// https://docs.aws.amazon.com/AWSEC2/latest/APIReference/errors-overview.html
201+
const scaleErrors = [
202+
'UnfulfillableCapacity',
203+
'MaxSpotInstanceCountExceeded',
204+
'TargetCapacityLimitExceededException',
205+
'RequestLimitExceeded',
206+
'ResourceLimitExceeded',
207+
'MaxSpotInstanceCountExceeded',
208+
'MaxSpotFleetRequestCountExceeded',
209+
'InsufficientInstanceCapacity',
210+
];
211+
212+
const failedCount = countScaleErrors(errors, scaleErrors);
213+
if (failedCount > 0) {
214+
logger.warn('Create fleet failed, ScaleError will be thrown to trigger retry for ephemeral runners.');
215+
logger.debug('Create fleet failed.', { data: fleet.Errors });
216+
throw new ScaleError('Failed to create instance, create fleet failed.', failedCount);
217+
}
218+
219+
logger.warn('Create fleet failed, error not recognized as scaling error.', { data: fleet.Errors });
220+
throw Error('Create fleet failed, no instance created.');
217221
}
218222

219223
function countScaleErrors(errors: string[], scaleErrors: string[]): number {

0 commit comments

Comments
 (0)