Skip to content
This repository was archived by the owner on Aug 6, 2025. It is now read-only.

Commit 5a6396b

Browse files
caesarbellCaesar Bell
andauthored
* ⚡ DOP-3598 passing test with benchmark mods * 🔇 DOP-3598 removes console log * ⚡ DOP-3598 properly use await to wait until each step is done * 🎉 DOP-3598 successfully passes all test and collects timestamp * 🎨 DOP-3598 cleans up the Dockerfile and deploy-stage-ecs * ✅ DOP-3598 writes success test * ✅ DOP-3598 writes success test * 👌 DOP-3598 makes changes based on feedback * 💡 DOP-3598 adds comment for clairty * 👌 DOP-3598 adds feedmore from the team * 🏷️ DOP-3598 typescript error fix * 🐛 DOP-3598 updates broken test * 👷 DOP-3598 puts back the docker and deploy configs to original state for cleanup * 👌 DOP-3598 additonal improvements based on teams feedback * ⏪ DOP-3598 revert configs for cleanup * 👌 DOP-3598 provides better non-blocking erroring * 🐛 DOP-3598 handles error and doesn't await for update but logs error if found * 🔧 DOP-3598 configuration for testing changes with working job queue * 🔧 DOP-3598 reverts config files to keep things clean * 👌 DOP-3598 sets findOneAndUpdateExecutionTime to be a promise while not propagated the error upward * 🔧 DOP-3598 testing against meta base branch * 🔧 DOP-3598 reverts config to original state --------- Co-authored-by: Caesar Bell <[email protected]>
1 parent 8f12a32 commit 5a6396b

File tree

12 files changed

+143
-17
lines changed

12 files changed

+143
-17
lines changed

api/controllers/v1/github.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,14 @@ async function prepGithubPushPayload(githubEvent: any, branchRepository: BranchR
3434
priority: 1,
3535
error: {},
3636
result: null,
37+
buildDepsExeStartTime: 0,
38+
buildDepsExeEndTime: 0,
39+
parseExeStartTime: 0,
40+
parseExeEndTime: 0,
41+
htmlExeStartTime: 0,
42+
htmlExeEndTime: 0,
43+
oasPageBuildExeStartTime: 0,
44+
oasPageBuildExeEndTime: 0,
3745
payload: {
3846
jobType: 'githubPush',
3947
source: 'github',

api/controllers/v1/slack.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,14 @@ function createJob(payload: any, jobTitle: string, jobUserName: string, jobUserE
264264
startTime: null,
265265
endTime: null,
266266
priority: 1,
267+
buildDepsExeStartTime: 0,
268+
buildDepsExeEndTime: 0,
269+
parseExeStartTime: 0,
270+
parseExeEndTime: 0,
271+
htmlExeStartTime: 0,
272+
htmlExeEndTime: 0,
273+
oasPageBuildExeStartTime: 0,
274+
oasPageBuildExeEndTime: 0,
267275
error: {},
268276
result: null,
269277
payload: payload,

src/entities/job.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ export type Payload = {
4848

4949
export type Job = {
5050
_id: string;
51+
useWithBenchmark?: boolean;
5152
payload: Payload;
5253
createdTime: Date;
5354
endTime: Date | null | undefined;

src/job/jobHandler.ts

Lines changed: 77 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -234,21 +234,88 @@ export abstract class JobHandler {
234234
}
235235
}
236236

237+
private async logBuildDetails(resp: CommandExecutorResponse): Promise<void> {
238+
await this._logger.save(
239+
this.currJob._id,
240+
`${'(BUILD)'.padEnd(15)}worker.sh run details:\n\n${resp.output}\n---\n${resp.error}`
241+
);
242+
if (resp.status != 'success') {
243+
const error = new AutoBuilderError(resp.error, 'BuildError');
244+
await this.logError(error);
245+
throw error;
246+
}
247+
}
248+
249+
// call this method when we want benchmarks and uses cwd option to call command outside of a one liner.
250+
private async callWithBenchmark(command: string, stage: string): Promise<CommandExecutorResponse> {
251+
const start = performance.now();
252+
const resp = await this._commandExecutor.execute([command], `repos/${this.currJob.payload.repoName}`);
253+
await this._logger.save(
254+
this.currJob._id,
255+
`${'(COMMAND)'.padEnd(15)} ${command} run details in ${this.currJob.payload.repoName}`
256+
);
257+
const end = performance.now();
258+
const update = {
259+
[`${stage}StartTime`]: start,
260+
[`${stage}EndTime`]: end,
261+
};
262+
263+
this._jobRepository.findOneAndUpdateExecutionTime(this.currJob._id, update);
264+
return resp;
265+
}
266+
267+
private async exeBuildModified(): Promise<void> {
268+
const stages = {
269+
['get-build-dependencies']: 'buildDepsExe',
270+
['next-gen-parse']: 'parseExe',
271+
['next-gen-html']: 'htmlExe',
272+
['oas-page-build']: 'oasPageBuildExe',
273+
};
274+
275+
// get the prerequisite commands which should be all commands up to `rm -f makefile`
276+
const endOfPrerequisiteCommands = this.currJob.buildCommands.indexOf('rm -f makefile');
277+
const index = endOfPrerequisiteCommands + 1;
278+
const prerequisiteCommands = this.currJob.buildCommands.slice(0, index);
279+
await this._logger.save(
280+
this.currJob._id,
281+
`${'(PREREQUISITE COMMANDS)'.padEnd(15)} ${prerequisiteCommands.join(' && ')}`
282+
);
283+
284+
const makeCommands = this.currJob.buildCommands.slice(index);
285+
await this._logger.save(this.currJob._id, `${'(MAKE COMMANDS)'.padEnd(15)} ${makeCommands.join(' && ')}`);
286+
287+
// call prerequisite commands
288+
await this._commandExecutor.execute(prerequisiteCommands);
289+
290+
for (const command of makeCommands) {
291+
// works for any make command with the following signature make <make-rule>
292+
const key = command.split(' ')[1].trim();
293+
if (stages[key]) {
294+
const makeCommandsWithBenchmarksResponse = await this.callWithBenchmark(command, stages[key]);
295+
await this.logBuildDetails(makeCommandsWithBenchmarksResponse);
296+
} else {
297+
const makeCommandsResp = await this._commandExecutor.execute([command]);
298+
await this.logBuildDetails(makeCommandsResp);
299+
}
300+
}
301+
await this._logger.save(this.currJob._id, `${'(BUILD)'.padEnd(15)}Finished Build`);
302+
}
303+
304+
private async exeBuild(): Promise<void> {
305+
const resp = await this._commandExecutor.execute(this.currJob.buildCommands);
306+
this.logBuildDetails(resp);
307+
await this._logger.save(this.currJob._id, `${'(BUILD)'.padEnd(15)}Finished Build`);
308+
}
309+
237310
@throwIfJobInterupted()
238311
private async executeBuild(): Promise<boolean> {
239312
if (this.currJob.buildCommands && this.currJob.buildCommands.length > 0) {
240313
await this._logger.save(this.currJob._id, `${'(BUILD)'.padEnd(15)}Running Build`);
241314
await this._logger.save(this.currJob._id, `${'(BUILD)'.padEnd(15)}running worker.sh`);
242-
const resp = await this._commandExecutor.execute(this.currJob.buildCommands);
243-
await this._logger.save(this.currJob._id, `${'(BUILD)'.padEnd(15)}Finished Build`);
244-
await this._logger.save(
245-
this.currJob._id,
246-
`${'(BUILD)'.padEnd(15)}worker.sh run details:\n\n${resp.output}\n---\n${resp.error}`
247-
);
248-
if (resp.status != 'success') {
249-
const error = new AutoBuilderError(resp.error, 'BuildError');
250-
await this.logError(error);
251-
throw error;
315+
if (this.currJob.useWithBenchmark) {
316+
await this.exeBuildModified();
317+
} else {
318+
await this.exeBuild();
252319
}
253320
} else {
254321
const error = new AutoBuilderError('No commands to execute', 'BuildError');

src/job/jobManager.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,8 @@ export class JobManager {
116116
try {
117117
this._jobHandler = null;
118118
if (job?.payload) {
119+
// Can easily rollback with commenting out this flag.
120+
job.useWithBenchmark = true;
119121
await this.createHandlerAndExecute(job);
120122
} else {
121123
this._logger.info('JobManager', `No Jobs Found: ${new Date()}`);

src/job/productionJobHandler.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ export class ProductionJobHandler extends JobHandler {
6565
prepStageSpecificNextGenCommands(): void {
6666
if (this.currJob?.buildCommands) {
6767
this.currJob.buildCommands[this.currJob.buildCommands.length - 1] = 'make get-build-dependencies';
68+
this.currJob.buildCommands.push('make next-gen-parse');
6869
this.currJob.buildCommands.push('make next-gen-html');
6970
this.currJob.buildCommands.push(`make oas-page-build MUT_PREFIX=${this.currJob.payload.mutPrefix}`);
7071
}

src/job/stagingJobHandler.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,8 @@ export class StagingJobHandler extends JobHandler {
5454

5555
prepStageSpecificNextGenCommands(): void {
5656
if (this.currJob.buildCommands) {
57-
this.currJob.buildCommands[this.currJob.buildCommands.length - 1] = 'make next-gen-html';
57+
this.currJob.buildCommands[this.currJob.buildCommands.length - 1] = 'make next-gen-parse';
58+
this.currJob.buildCommands.push('make next-gen-html');
5859
const project = this.currJob.payload.project === 'cloud-docs' ? this.currJob.payload.project : '';
5960
const branchName = /^[a-zA-Z0-9_\-\./]+$/.test(this.currJob.payload.branchName)
6061
? this.currJob.payload.branchName

src/repositories/jobRepository.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,19 @@ export class JobRepository extends BaseRepository {
9393
await this._queueConnector.sendMessage(new JobQueueMessage(jobId, status, 0, taskId), url, delay);
9494
}
9595

96+
async findOneAndUpdateExecutionTime(id: string, setValues: { [key: string]: number }): Promise<void> {
97+
const query = {
98+
_id: new objectId(id),
99+
};
100+
const update = { $set: setValues };
101+
const options = { sort: { priority: -1, createdTime: 1 }, returnNewDocument: true };
102+
this.findOneAndUpdate(query, update, options, `Mongo Timeout Error: Timed out while retrieving job`).catch(
103+
(err) => {
104+
this._logger.error('findOneAndUpdateExecutionTime', `Error at findOneAndUpdate: ${err}`);
105+
}
106+
);
107+
}
108+
96109
async findOneAndUpdateJob(query): Promise<Job | null> {
97110
const update = { $set: { startTime: new Date(), status: 'inProgress' } };
98111
const options = { sort: { priority: -1, createdTime: 1 }, returnNewDocument: true };

src/services/commandExecutor.ts

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ export class CommandExecutorResponse {
2121
}
2222

2323
export interface ICommandExecutor {
24-
execute(commands: Array<string>): Promise<CommandExecutorResponse>;
24+
execute(commands: Array<string>, cwd?: string): Promise<CommandExecutorResponse>;
2525
}
2626

2727
export interface IJobCommandExecutor extends ICommandExecutor {
@@ -43,11 +43,17 @@ export interface IGithubCommandExecutor {
4343
}
4444

4545
export class ShellCommandExecutor implements ICommandExecutor {
46-
async execute(commands: string[]): Promise<CommandExecutorResponse> {
46+
async execute(commands: string[], cwd?: string): Promise<CommandExecutorResponse> {
4747
const exec = promisify(cp.exec);
4848
const resp = new CommandExecutorResponse();
4949
try {
50-
const { stdout, stderr } = await exec(commands.join(' && '), { maxBuffer: c.get('MAX_STDOUT_BUFFER_SIZE') });
50+
const options: { maxBuffer: number; cwd?: string } = {
51+
maxBuffer: c.get('MAX_STDOUT_BUFFER_SIZE'),
52+
};
53+
if (cwd) {
54+
options.cwd = cwd;
55+
}
56+
const { stdout, stderr } = await exec(commands.join(' && '), options);
5157

5258
resp.output = stdout.trim();
5359
resp.error = stderr;

tests/data/data.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,7 @@ export class TestDataProvider {
144144
const genericCommands = TestDataProvider.getCommonBuildCommands(job);
145145
return Array<string>().concat(genericCommands.slice(0, genericCommands.length - 1), [
146146
'make get-build-dependencies',
147+
'make next-gen-parse',
147148
'make next-gen-html',
148149
`make oas-page-build MUT_PREFIX=${job.payload.mutPrefix}`,
149150
]);
@@ -160,6 +161,7 @@ export class TestDataProvider {
160161
static getExpectedStagingBuildNextGenCommands(job: Job): Array<string> {
161162
const genericCommands = TestDataProvider.getCommonBuildCommands(job);
162163
const commands = Array<string>().concat(genericCommands.slice(0, genericCommands.length - 1), [
164+
'make next-gen-parse',
163165
'make next-gen-html',
164166
]);
165167
const project = job.payload.project === 'cloud-docs' ? job.payload.project : '';

0 commit comments

Comments
 (0)