screwdriver-queue-service 2.0.36 → 2.0.39
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +2 -2
- package/plugins/helper.js +24 -0
- package/plugins/queue/scheduler.js +42 -17
- package/plugins/worker/worker.js +7 -3
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "screwdriver-queue-service",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.39",
|
|
4
4
|
"description": "Screwdriver Queue Service API",
|
|
5
5
|
"main": "app.js",
|
|
6
6
|
"directories": {
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
"screwdriver-logger": "^1.0.2",
|
|
39
39
|
"screwdriver-request": "^1.0.2",
|
|
40
40
|
"string-hash": "^1.1.3",
|
|
41
|
-
"uuid": "^
|
|
41
|
+
"uuid": "^8.0.0"
|
|
42
42
|
},
|
|
43
43
|
"devDependencies": {
|
|
44
44
|
"chai": "^4.3.4",
|
package/plugins/helper.js
CHANGED
|
@@ -247,6 +247,29 @@ async function updateBuild(updateConfig, retryStrategyFn) {
|
|
|
247
247
|
);
|
|
248
248
|
}
|
|
249
249
|
|
|
250
|
+
/**
|
|
251
|
+
* Notify user with job status
|
|
252
|
+
* @param {Number} jobId
|
|
253
|
+
* @param {String} token
|
|
254
|
+
* @param {Object} payload
|
|
255
|
+
* @param {String} apiUri
|
|
256
|
+
* @param {Object} retryStrategyFn
|
|
257
|
+
*/
|
|
258
|
+
async function notifyJob(notifyConfig, retryStrategyFn) {
|
|
259
|
+
const { token, apiUri, jobId, payload } = notifyConfig;
|
|
260
|
+
|
|
261
|
+
return request(formatOptions('POST', `${apiUri}/v4/jobs/${jobId}/notify`, token, payload, retryStrategyFn)).then(
|
|
262
|
+
res => {
|
|
263
|
+
logger.info(`POST /v4/jobs/${jobId}/notify completed with attempts, ${res.statusCode}, ${res.attempts}`);
|
|
264
|
+
if ([200, 201, 204].includes(res.statusCode)) {
|
|
265
|
+
return res.body;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
throw new Error(`Could not notify job ${jobId} with ${res.statusCode}code and ${JSON.stringify(res.body)}`);
|
|
269
|
+
}
|
|
270
|
+
);
|
|
271
|
+
}
|
|
272
|
+
|
|
250
273
|
/**
|
|
251
274
|
* Post the webhooks process
|
|
252
275
|
* @method processHooks
|
|
@@ -306,5 +329,6 @@ module.exports = {
|
|
|
306
329
|
createBuildEvent,
|
|
307
330
|
getPipelineAdmin,
|
|
308
331
|
updateBuild,
|
|
332
|
+
notifyJob,
|
|
309
333
|
processHooks
|
|
310
334
|
};
|
|
@@ -29,12 +29,13 @@ const BLOCKED_BY_SAME_JOB_WAIT_TIME = 5;
|
|
|
29
29
|
async function postBuildEvent(executor, eventConfig) {
|
|
30
30
|
const { pipeline, job, apiUri, eventId, causeMessage, buildId } = eventConfig;
|
|
31
31
|
const pipelineId = pipeline.id;
|
|
32
|
+
const jobId = job.id;
|
|
32
33
|
|
|
33
34
|
try {
|
|
34
35
|
const token = executor.tokenGen({
|
|
35
36
|
pipelineId,
|
|
36
37
|
service: 'queue',
|
|
37
|
-
jobId
|
|
38
|
+
jobId,
|
|
38
39
|
scmContext: pipeline.scmContext,
|
|
39
40
|
scope: ['user']
|
|
40
41
|
});
|
|
@@ -71,6 +72,26 @@ async function postBuildEvent(executor, eventConfig) {
|
|
|
71
72
|
`POST event for pipeline failed as no admin found: ${pipelineId}:${job.name}:${job.id}:${buildId}`
|
|
72
73
|
);
|
|
73
74
|
|
|
75
|
+
const pipelineToken = executor.tokenGen({
|
|
76
|
+
pipelineId,
|
|
77
|
+
service: 'queue',
|
|
78
|
+
scmContext: pipeline.scmContext,
|
|
79
|
+
scope: ['pipeline']
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
const status = 'FAILURE';
|
|
83
|
+
const message = `Pipeline ${pipelineId} does not have admin, unable to start job ${job.name}.`;
|
|
84
|
+
|
|
85
|
+
await helper.notifyJob(
|
|
86
|
+
{
|
|
87
|
+
token: pipelineToken,
|
|
88
|
+
apiUri,
|
|
89
|
+
jobId,
|
|
90
|
+
payload: { status, message }
|
|
91
|
+
},
|
|
92
|
+
helper.requestRetryStrategyPostEvent
|
|
93
|
+
);
|
|
94
|
+
|
|
74
95
|
throw new Error(`Pipeline admin not found, cannot process build ${buildId}`);
|
|
75
96
|
}
|
|
76
97
|
} catch (err) {
|
|
@@ -166,15 +187,6 @@ async function startPeriodic(executor, config) {
|
|
|
166
187
|
|
|
167
188
|
if (triggerBuild) {
|
|
168
189
|
config.causeMessage = 'Started by periodic build scheduler';
|
|
169
|
-
|
|
170
|
-
// Even if post event failed for this event after retry, we should still enqueue the next event
|
|
171
|
-
try {
|
|
172
|
-
await postBuildEvent(executor, config);
|
|
173
|
-
} catch (err) {
|
|
174
|
-
logger.error(
|
|
175
|
-
`periodic builds: failed to post build event for job ${job.id} in pipeline ${pipeline.id}: ${err}`
|
|
176
|
-
);
|
|
177
|
-
}
|
|
178
190
|
}
|
|
179
191
|
|
|
180
192
|
if (buildCron && job.state === 'ENABLED' && !job.archived) {
|
|
@@ -214,18 +226,28 @@ async function startPeriodic(executor, config) {
|
|
|
214
226
|
logger.error(`failed to enqueue for job ${job.id}: ${err}`);
|
|
215
227
|
}
|
|
216
228
|
}
|
|
217
|
-
if (!shouldRetry) {
|
|
218
|
-
logger.info(`successfully added to queue for job ${job.id}`);
|
|
219
229
|
|
|
220
|
-
|
|
230
|
+
if (shouldRetry) {
|
|
231
|
+
try {
|
|
232
|
+
await executor.queue.enqueueAt(next, executor.periodicBuildQueue, 'startDelayed', [{ jobId: job.id }]);
|
|
233
|
+
} catch (err) {
|
|
234
|
+
logger.error(`failed to add to delayed queue for job ${job.id}: ${err}`);
|
|
235
|
+
}
|
|
236
|
+
} else {
|
|
237
|
+
logger.info(`successfully added to queue for job ${job.id}`);
|
|
221
238
|
}
|
|
239
|
+
}
|
|
240
|
+
logger.info(`added to delayed queue for job ${job.id}`);
|
|
241
|
+
|
|
242
|
+
if (triggerBuild) {
|
|
222
243
|
try {
|
|
223
|
-
await
|
|
244
|
+
await postBuildEvent(executor, config);
|
|
224
245
|
} catch (err) {
|
|
225
|
-
logger.error(
|
|
246
|
+
logger.error(
|
|
247
|
+
`periodic builds: failed to post build event for job ${job.id} in pipeline ${pipeline.id}: ${err}`
|
|
248
|
+
);
|
|
226
249
|
}
|
|
227
250
|
}
|
|
228
|
-
logger.info(`added to delayed queue for job ${job.id}`);
|
|
229
251
|
|
|
230
252
|
return Promise.resolve();
|
|
231
253
|
}
|
|
@@ -536,8 +558,11 @@ async function init(executor) {
|
|
|
536
558
|
executor.scheduler.on('master', state => logger.info(`scheduler became master ${state}`));
|
|
537
559
|
executor.scheduler.on('error', error => logger.info(`scheduler error >> ${error}`));
|
|
538
560
|
executor.scheduler.on('workingTimestamp', timestamp => logger.info(`scheduler working timestamp ${timestamp}`));
|
|
561
|
+
executor.scheduler.on('cleanStuckWorker', (workerName, errorPayload, delta) =>
|
|
562
|
+
logger.info(`scheduler failing ${workerName} (stuck for ${delta}s) and failing job ${errorPayload}`)
|
|
563
|
+
);
|
|
539
564
|
executor.scheduler.on('transferredJob', (timestamp, job) =>
|
|
540
|
-
logger.info(`scheduler enqueuing job timestamp >> ${JSON.stringify(job)}`)
|
|
565
|
+
logger.info(`scheduler enqueuing job ${timestamp} >> ${JSON.stringify(job)}`)
|
|
541
566
|
);
|
|
542
567
|
|
|
543
568
|
await executor.multiWorker.start();
|
package/plugins/worker/worker.js
CHANGED
|
@@ -123,13 +123,17 @@ async function invoke() {
|
|
|
123
123
|
scheduler.on('poll', () => logger.info('queueWorker->scheduler polling'));
|
|
124
124
|
scheduler.on('master', state => logger.info(`queueWorker->scheduler became master ${state}`));
|
|
125
125
|
scheduler.on('error', error => logger.info(`queueWorker->scheduler error >> ${error}`));
|
|
126
|
-
scheduler.on('
|
|
126
|
+
scheduler.on('workingTimestamp', timestamp =>
|
|
127
127
|
logger.info(`queueWorker->scheduler working timestamp ${timestamp}`)
|
|
128
128
|
);
|
|
129
|
-
scheduler.on('
|
|
129
|
+
scheduler.on('transferredJob', (timestamp, job) =>
|
|
130
130
|
logger.info(`queueWorker->scheduler enqueuing job timestamp >> ${timestamp} ${JSON.stringify(job)}`)
|
|
131
131
|
);
|
|
132
|
-
|
|
132
|
+
scheduler.on('cleanStuckWorker', (workerName, errorPayload, delta) =>
|
|
133
|
+
logger.info(
|
|
134
|
+
`queueWorker->scheduler failing ${workerName} (stuck for ${delta}s) and failing job ${errorPayload}`
|
|
135
|
+
)
|
|
136
|
+
);
|
|
133
137
|
multiWorker.start();
|
|
134
138
|
|
|
135
139
|
await scheduler.connect();
|