-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathhandler.js
93 lines (73 loc) · 2.52 KB
/
handler.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
const { log } = require('./helpers/log');
const { getObjectSafely } = require('./helpers/object');
const job = (func, options) => {
return { func, options };
};
/**
* Run all functions passed into the jobs array as a set
* of asyc promisses to run as parallel as possible.
*
* @param {Function[]} jobs List of function calls
* @returns
*/
const run = async (event, hasuraEvent, jobs) => {
if (!Array.isArray(jobs)) return;
if (!jobs.length === 0) return;
let safeJobs = [];
for (const key in jobs) {
const job = jobs[key];
let { func, options = {} } = job;
if (!func) continue;
if (!options) options = {};
safeJobs.push(safeJobWrapper(func, event, hasuraEvent, options));
}
log(`${event}.runJobs`, `Running ${safeJobs.length} jobs...`);
const responses = await Promise.allSettled(safeJobs);
log(`${event}.runJobs`, `Completed ${safeJobs.length} jobs`);
return preparedResponse(event, jobs, responses);
};
const safeJobWrapper = async (func, event, hasuraEvent, options) => {
// Use the urnary (+) to get starting time as milliseconds
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Unary_plus
let start = +new Date();
let output = {
event,
name: func?.name,
duration: 0,
result: null,
};
try {
if (!func) throw Error('Job func not defined');
if (typeof func !== 'function') throw Error('Job func not a function');
// Call the job function
const funcRes = await func(event, hasuraEvent, options);
output.duration = +new Date() - start;
output.result = funcRes;
return output;
} catch (error) {
output.result = error.message;
output.duration = +new Date() - start;
log(event, `Job func crashed: ${error.message}`);
let newError = new Error(`Job func crashed: ${error.message}`);
newError.stack = output;
throw newError;
}
};
const preparedResponse = (event, jobs, responses) => {
let jobsOutput = [];
for (const responseIndex in responses) {
const jobResponse = responses[responseIndex];
const jobResponseDetails = jobResponse?.value || jobResponse?.reason;
const job = jobs[responseIndex];
const jobOutput = jobResponse?.status === 'fulfilled' ? jobResponse?.value : jobResponseDetails?.stack;
jobsOutput.push({
name: jobOutput?.name,
options: getObjectSafely(job?.options),
completed: jobResponse?.status === 'fulfilled',
duration: jobOutput?.duration,
result: jobOutput?.result,
});
}
return jobsOutput;
};
module.exports = { job, run };