psdev-task-manager 1.4.6 → 1.7.1
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/.github/workflows/update-sites.yml +17 -8
- package/.prettierignore +7 -0
- package/.prettierrc.json +16 -0
- package/README.md +1 -0
- package/backend/tasks/index.js +0 -1
- package/backend/tasks/parentChildTasks/index.js +1 -1
- package/backend/tasks/taskManager.js +16 -8
- package/backend/tasks/tasks.js +26 -26
- package/backend/tasks/utils.js +28 -16
- package/eslint.config.js +113 -0
- package/index.js +1 -1
- package/package.json +19 -3
- package/public/consts.js +1 -1
|
@@ -1,21 +1,30 @@
|
|
|
1
1
|
name: Update Sites After Release Main
|
|
2
2
|
|
|
3
3
|
on:
|
|
4
|
+
push:
|
|
5
|
+
branches:
|
|
6
|
+
- main
|
|
4
7
|
workflow_dispatch:
|
|
5
|
-
|
|
8
|
+
|
|
6
9
|
permissions:
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
+
contents: write
|
|
11
|
+
packages: write
|
|
12
|
+
|
|
10
13
|
jobs:
|
|
11
14
|
update-sites:
|
|
12
|
-
uses: psdevteamenterprise/ci-workflows/.github/workflows/
|
|
15
|
+
uses: psdevteamenterprise/ci-workflows/.github/workflows/update-and-notify.yml@main
|
|
13
16
|
with:
|
|
14
|
-
|
|
15
|
-
|
|
17
|
+
npm_packages_to_update: "[{repo: 'Hisense-Wix/velo-npm'}]"
|
|
18
|
+
sites_to_update: "[{repo: 'psdevteamenterprise/external-template', secret: 'WIX_SR_API_KEY'},
|
|
19
|
+
{repo: 'psdevteamenterprise/internal', secret: 'WIX_SR_API_KEY'},
|
|
20
|
+
{repo: 'psdevteamenterprise/tests-site', secret: 'WIX_PS_API_KEY'},
|
|
21
|
+
{repo: 'psdevteamenterprise/hisense_mexico', secret: 'WIX_HM_API_KEY'},
|
|
22
|
+
]"
|
|
16
23
|
secrets:
|
|
17
24
|
GH_TOKEN: ${{ secrets.MY_GITHUB_TOKEN }}
|
|
18
25
|
NPM_TOKEN: ${{ secrets.NPM_TOKEN_PUBLISH }}
|
|
19
26
|
GH_APP_ID: ${{ secrets.GH_APP_ID }}
|
|
20
27
|
GH_APP_PRIVATE_KEY: ${{ secrets.GH_APP_PRIVATE_KEY }}
|
|
21
|
-
|
|
28
|
+
WIX_SR_API_KEY: ${{secrets.WIX_SR_API_KEY}}
|
|
29
|
+
WIX_PS_API_KEY: ${{secrets.WIX_PS_API_KEY}}
|
|
30
|
+
WIX_HM_API_KEY: ${{secrets.WIX_HM_API_KEY}}
|
package/.prettierignore
ADDED
package/.prettierrc.json
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{
|
|
2
|
+
"singleQuote": true,
|
|
3
|
+
"trailingComma": "es5",
|
|
4
|
+
"printWidth": 100,
|
|
5
|
+
"tabWidth": 2,
|
|
6
|
+
"semi": true,
|
|
7
|
+
"bracketSpacing": true,
|
|
8
|
+
"bracketSameLine": false,
|
|
9
|
+
"arrowParens": "avoid",
|
|
10
|
+
"endOfLine": "lf",
|
|
11
|
+
"quoteProps": "as-needed",
|
|
12
|
+
"jsxSingleQuote": false,
|
|
13
|
+
"requirePragma": false,
|
|
14
|
+
"insertPragma": false,
|
|
15
|
+
"proseWrap": "preserve"
|
|
16
|
+
}
|
package/README.md
CHANGED
package/backend/tasks/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
const { withDuration } = require('psdev-utils');
|
|
1
|
+
const { withDuration, withSuccessRateLogs } = require('psdev-utils');
|
|
2
2
|
|
|
3
|
-
const { TASK_STATUS, CRON_JOB_MAX_DURATION_SEC } = require('./consts');
|
|
3
|
+
const { TASK_STATUS, CRON_JOB_MAX_DURATION_SEC, TASK_MAX_TRIES } = require('./consts');
|
|
4
4
|
const { scheduleChildTasksAndUpdateParent } = require('./parentChildTasks/handler');
|
|
5
5
|
const {
|
|
6
6
|
saveTaskResultToAdditionalCollection,
|
|
@@ -17,7 +17,7 @@ const {
|
|
|
17
17
|
} = require('./utils');
|
|
18
18
|
|
|
19
19
|
function taskManager() {
|
|
20
|
-
const
|
|
20
|
+
const processTaskWithDuration = (task, tasksConfig) =>
|
|
21
21
|
withDuration(
|
|
22
22
|
'processTask',
|
|
23
23
|
async () => {
|
|
@@ -73,24 +73,33 @@ function taskManager() {
|
|
|
73
73
|
if (saveResults) {
|
|
74
74
|
await saveTaskResultToAdditionalCollection(task, TASK_STATUS.FAILED, { error });
|
|
75
75
|
}
|
|
76
|
-
|
|
76
|
+
const isFailedAfterAllRetries = amountOfRetries >= TASK_MAX_TRIES;
|
|
77
|
+
if (isFailedAfterAllRetries) {
|
|
78
|
+
|
|
79
|
+
//Only throw error if task is permanently failed, otherwise we have retry mechanism
|
|
80
|
+
throw new Error("task failed after all retries: " + errMsg);
|
|
81
|
+
}
|
|
77
82
|
}
|
|
78
83
|
},
|
|
79
84
|
console
|
|
80
85
|
);
|
|
86
|
+
const processTask = (...args) => {
|
|
87
|
+
const requestName = `processTask_${args[0].name}`; //To get success rate analysis per task
|
|
88
|
+
return withSuccessRateLogs(requestName, () => processTaskWithDuration(...args));
|
|
89
|
+
};
|
|
81
90
|
/**
|
|
82
91
|
* @description Processing tasks based on how many the cron job tick can handle and running them sequentially to be as safe as possible
|
|
83
92
|
* */
|
|
84
93
|
const processTasksBasedOnVeloLimit = async (scheduledTasks, tasksConfig) => {
|
|
85
94
|
console.log(
|
|
86
|
-
`processTasksBasedOnVeloLimit: ${
|
|
95
|
+
`processTasksBasedOnVeloLimit: scheduledTasks count: ${scheduledTasks.length} tasksConfig: ${JSON.stringify(tasksConfig)}`
|
|
87
96
|
);
|
|
88
97
|
const toProcessTasks = getTasksToProcess({
|
|
89
98
|
scheduledTasks,
|
|
90
99
|
tasksConfig,
|
|
91
100
|
maxDuration: CRON_JOB_MAX_DURATION_SEC,
|
|
92
101
|
});
|
|
93
|
-
console.log(`processTasksBasedOnVeloLimit: toProcessTasks: ${
|
|
102
|
+
console.log(`processTasksBasedOnVeloLimit: toProcessTasks count: ${toProcessTasks.length}`);
|
|
94
103
|
console.log(
|
|
95
104
|
`[processTasksBasedOnVeloLimit] started processing: ${toProcessTasks.length} tasks`
|
|
96
105
|
);
|
|
@@ -113,8 +122,7 @@ function taskManager() {
|
|
|
113
122
|
const runScheduledTasks = async tasksConfig => {
|
|
114
123
|
try {
|
|
115
124
|
const scheduledTasks = await getScheduledTasks();
|
|
116
|
-
console.log(`runScheduledTasks: scheduledTasks: ${
|
|
117
|
-
console.log(`runScheduledTasks: tasksConfig: ${JSON.stringify(tasksConfig)}`);
|
|
125
|
+
console.log(`runScheduledTasks: scheduledTasks count: ${scheduledTasks.length}`);
|
|
118
126
|
if (scheduledTasks.length) {
|
|
119
127
|
await processTasksBasedOnVeloLimit(scheduledTasks, tasksConfig);
|
|
120
128
|
} else {
|
package/backend/tasks/tasks.js
CHANGED
|
@@ -1,29 +1,29 @@
|
|
|
1
1
|
const TASKS = {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
},
|
|
16
|
-
shouldSkipCheck: (task) => task.data.shouldSkip,
|
|
17
|
-
estimatedDurationSec:2,
|
|
2
|
+
TEST_TASK: {
|
|
3
|
+
name: 'TestTask',
|
|
4
|
+
getIdentifier: task => task,
|
|
5
|
+
process: task => {
|
|
6
|
+
const data = task.data || {};
|
|
7
|
+
let error;
|
|
8
|
+
if (data.retries) {
|
|
9
|
+
error = task.error ? Number(task.error) - 1 : data.retries - 1;
|
|
10
|
+
}
|
|
11
|
+
if (data.shouldFail && (!error || error > 0)) {
|
|
12
|
+
throw new Error(error?.toString() || 'Test error');
|
|
13
|
+
}
|
|
14
|
+
return 'test';
|
|
18
15
|
},
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
16
|
+
shouldSkipCheck: task => task.data.shouldSkip,
|
|
17
|
+
estimatedDurationSec: 2,
|
|
18
|
+
},
|
|
19
|
+
BAD_TASK: {
|
|
20
|
+
name: 'BadTask',
|
|
21
|
+
getIdentifier: () => true,
|
|
22
|
+
process: () => 'test',
|
|
23
|
+
shouldSkipCheck: () => false,
|
|
24
|
+
},
|
|
25
|
+
};
|
|
26
26
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
27
|
+
module.exports = {
|
|
28
|
+
TASKS,
|
|
29
|
+
};
|
package/backend/tasks/utils.js
CHANGED
|
@@ -44,7 +44,7 @@ async function createCollectionIfMissing(
|
|
|
44
44
|
if (collectionType === 'singleItem') {
|
|
45
45
|
createDataCollectionOptions.plugins = [
|
|
46
46
|
{
|
|
47
|
-
type:
|
|
47
|
+
type: 'SINGLE_ITEM',
|
|
48
48
|
singleItemOptions: {},
|
|
49
49
|
},
|
|
50
50
|
];
|
|
@@ -168,19 +168,29 @@ const isParentTask = (task, taskConfig) => {
|
|
|
168
168
|
return true;
|
|
169
169
|
};
|
|
170
170
|
const filterScheduledTasksByStatus = (tasks, tasksConfig) => {
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
return isParentTask(task, tasksConfig[task.name]);
|
|
171
|
+
|
|
172
|
+
const shouldIncludeTask = (task, taskConfig) => {
|
|
173
|
+
console.log(`filterScheduledTasksByStatus: task: ${JSON.stringify(task)}`);
|
|
174
|
+
console.log(`filterScheduledTasksByStatus: taskConfig: ${JSON.stringify(taskConfig)}`);
|
|
175
|
+
const { status } = task;
|
|
176
|
+
if (status === TASK_STATUS.IN_PROGRESS) {
|
|
177
|
+
//Only include parent tasks that are in progress, to continue running next children
|
|
178
|
+
return isParentTask(task, taskConfig);
|
|
180
179
|
}
|
|
180
|
+
//TODO: need to rethink of this as some parent tasks we use only to schedule children,
|
|
181
|
+
// if (status === TASK_STATUS.FAILED) {
|
|
182
|
+
// // Exclude if it's a parent task, if parent task failed, we don't retry it anymore
|
|
183
|
+
// return !isParentTask(task, taskConfig);
|
|
184
|
+
// }
|
|
185
|
+
// // Include if status is PENDING
|
|
186
|
+
// return status === TASK_STATUS.PENDING;
|
|
181
187
|
return [TASK_STATUS.PENDING, TASK_STATUS.FAILED].includes(task.status);
|
|
188
|
+
};
|
|
189
|
+
const filtered = tasks.filter(task => {
|
|
190
|
+
const taskConfig = tasksConfig[task.name];
|
|
191
|
+
return shouldIncludeTask(task, taskConfig);
|
|
182
192
|
});
|
|
183
|
-
console.log(`filterScheduledTasksByStatus: filtered: ${
|
|
193
|
+
console.log(`filterScheduledTasksByStatus: filtered count: ${filtered.length}`);
|
|
184
194
|
return filtered;
|
|
185
195
|
};
|
|
186
196
|
const getScheduledTasks = async () => {
|
|
@@ -221,16 +231,18 @@ const getTaskScheduledChildren = async parentTaskId => {
|
|
|
221
231
|
};
|
|
222
232
|
|
|
223
233
|
const getTasksToProcess = ({ scheduledTasks, tasksConfig, maxDuration }) => {
|
|
224
|
-
console.log('getTasksToProcess:', {
|
|
234
|
+
console.log('getTasksToProcess:', {
|
|
235
|
+
scheduledTasksCount: scheduledTasks.length,
|
|
236
|
+
tasksConfig,
|
|
237
|
+
maxDuration,
|
|
238
|
+
});
|
|
225
239
|
const tasksToProcess = [];
|
|
226
240
|
let totalDuration = 0;
|
|
227
|
-
console.log(`tasksConfig is : ${JSON.stringify(tasksConfig)}`);
|
|
228
241
|
const filteredScheduledTasks = filterScheduledTasksByStatus(scheduledTasks, tasksConfig);
|
|
229
|
-
console.log(`filteredScheduledTasks
|
|
242
|
+
console.log(`filteredScheduledTasks count : ${filteredScheduledTasks.length}`);
|
|
230
243
|
for (const task of filteredScheduledTasks) {
|
|
231
244
|
console.log(`task is : ${JSON.stringify(task)}`);
|
|
232
245
|
const taskConfig = getTaskConfig(task.name, tasksConfig);
|
|
233
|
-
console.log(`taskConfig is : ${JSON.stringify(taskConfig)}`);
|
|
234
246
|
const estimated = taskConfig?.estimatedDurationSec;
|
|
235
247
|
if (!estimated) {
|
|
236
248
|
const errMsg = `[getTasksToProcess] estimatedDurationSec is not defined for task ${task.name}`;
|
|
@@ -243,7 +255,7 @@ const getTasksToProcess = ({ scheduledTasks, tasksConfig, maxDuration }) => {
|
|
|
243
255
|
totalDuration += buffered;
|
|
244
256
|
tasksToProcess.push(task);
|
|
245
257
|
}
|
|
246
|
-
console.log('getTasksToProcess: tasksToProcess:', tasksToProcess);
|
|
258
|
+
console.log('getTasksToProcess: tasksToProcess count:', tasksToProcess.length);
|
|
247
259
|
return tasksToProcess;
|
|
248
260
|
};
|
|
249
261
|
|
package/eslint.config.js
ADDED
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
const js = require('@eslint/js');
|
|
2
|
+
const prettierConfig = require('eslint-config-prettier');
|
|
3
|
+
const importPlugin = require('eslint-plugin-import');
|
|
4
|
+
const prettier = require('eslint-plugin-prettier');
|
|
5
|
+
const promisePlugin = require('eslint-plugin-promise');
|
|
6
|
+
const globals = require('globals');
|
|
7
|
+
|
|
8
|
+
module.exports = [
|
|
9
|
+
// Recommended base configurations
|
|
10
|
+
js.configs.recommended,
|
|
11
|
+
prettierConfig,
|
|
12
|
+
|
|
13
|
+
// Main configuration
|
|
14
|
+
{
|
|
15
|
+
files: ['**/*.js'],
|
|
16
|
+
languageOptions: {
|
|
17
|
+
ecmaVersion: 2021,
|
|
18
|
+
sourceType: 'commonjs',
|
|
19
|
+
globals: {
|
|
20
|
+
...globals.node,
|
|
21
|
+
...globals.es2021,
|
|
22
|
+
...globals.jest,
|
|
23
|
+
},
|
|
24
|
+
},
|
|
25
|
+
plugins: {
|
|
26
|
+
prettier,
|
|
27
|
+
import: importPlugin,
|
|
28
|
+
promise: promisePlugin,
|
|
29
|
+
},
|
|
30
|
+
rules: {
|
|
31
|
+
// Error prevention
|
|
32
|
+
'no-var': 'error',
|
|
33
|
+
'no-unused-vars': ['error', { argsIgnorePattern: '^_', varsIgnorePattern: '^_' }],
|
|
34
|
+
'no-console': ['warn', { allow: ['warn', 'error', 'log', 'info'] }],
|
|
35
|
+
'no-debugger': 'warn',
|
|
36
|
+
'no-duplicate-imports': 'error',
|
|
37
|
+
'no-unused-expressions': ['error', { allowShortCircuit: true, allowTernary: true }],
|
|
38
|
+
'no-use-before-define': ['error', { functions: false }],
|
|
39
|
+
|
|
40
|
+
// Best practices
|
|
41
|
+
'prefer-const': 'error',
|
|
42
|
+
'no-const-assign': 'error',
|
|
43
|
+
'prefer-arrow-callback': 'error',
|
|
44
|
+
'arrow-body-style': ['error', 'as-needed'],
|
|
45
|
+
'no-return-await': 'off',
|
|
46
|
+
'require-await': 'warn',
|
|
47
|
+
|
|
48
|
+
// Import rules
|
|
49
|
+
'import/order': [
|
|
50
|
+
'error',
|
|
51
|
+
{
|
|
52
|
+
groups: ['builtin', 'external', 'internal', 'parent', 'sibling', 'index'],
|
|
53
|
+
'newlines-between': 'always',
|
|
54
|
+
alphabetize: { order: 'asc', caseInsensitive: true },
|
|
55
|
+
},
|
|
56
|
+
],
|
|
57
|
+
'import/no-unresolved': 'error',
|
|
58
|
+
'import/no-duplicates': 'error',
|
|
59
|
+
'import/no-commonjs': 'off',
|
|
60
|
+
'import/no-dynamic-require': 'off',
|
|
61
|
+
|
|
62
|
+
// Promise rules
|
|
63
|
+
'promise/always-return': 'off',
|
|
64
|
+
'promise/no-return-wrap': 'error',
|
|
65
|
+
'promise/param-names': 'error',
|
|
66
|
+
'promise/catch-or-return': 'error',
|
|
67
|
+
'promise/no-native': 'off',
|
|
68
|
+
'promise/no-callback-in-promise': 'warn',
|
|
69
|
+
'promise/no-promise-in-callback': 'warn',
|
|
70
|
+
'promise/no-nesting': 'warn',
|
|
71
|
+
|
|
72
|
+
// Prettier rules
|
|
73
|
+
'prettier/prettier': [
|
|
74
|
+
'error',
|
|
75
|
+
{
|
|
76
|
+
singleQuote: true,
|
|
77
|
+
trailingComma: 'es5',
|
|
78
|
+
printWidth: 100,
|
|
79
|
+
tabWidth: 2,
|
|
80
|
+
semi: true,
|
|
81
|
+
bracketSpacing: true,
|
|
82
|
+
arrowParens: 'avoid',
|
|
83
|
+
endOfLine: 'lf',
|
|
84
|
+
},
|
|
85
|
+
],
|
|
86
|
+
},
|
|
87
|
+
settings: {
|
|
88
|
+
'import/resolver': {
|
|
89
|
+
node: {
|
|
90
|
+
extensions: ['.js', '.jsx', '.ts', '.tsx'],
|
|
91
|
+
},
|
|
92
|
+
},
|
|
93
|
+
},
|
|
94
|
+
},
|
|
95
|
+
|
|
96
|
+
// Test files override
|
|
97
|
+
{
|
|
98
|
+
files: ['**/*.test.js', '**/*.spec.js'],
|
|
99
|
+
languageOptions: {
|
|
100
|
+
globals: {
|
|
101
|
+
...globals.jest,
|
|
102
|
+
},
|
|
103
|
+
},
|
|
104
|
+
rules: {
|
|
105
|
+
'no-console': 'off',
|
|
106
|
+
},
|
|
107
|
+
},
|
|
108
|
+
|
|
109
|
+
// Ignore patterns
|
|
110
|
+
{
|
|
111
|
+
ignores: ['node_modules/**', 'dist/**', 'build/**', 'coverage/**', '*.min.js'],
|
|
112
|
+
},
|
|
113
|
+
];
|
package/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "psdev-task-manager",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.7.1",
|
|
4
4
|
"description": "Task manager library",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"task-manager"
|
|
@@ -18,11 +18,27 @@
|
|
|
18
18
|
"type": "commonjs",
|
|
19
19
|
"main": "index.js",
|
|
20
20
|
"scripts": {
|
|
21
|
-
"test": "jest"
|
|
21
|
+
"test": "jest",
|
|
22
|
+
"lint": "eslint .",
|
|
23
|
+
"lint:fix": "eslint . --fix",
|
|
24
|
+
"format": "prettier --write \"**/*.{js,json,md}\"",
|
|
25
|
+
"format:check": "prettier --check \"**/*.{js,json,md}\"",
|
|
26
|
+
"prepare": "husky"
|
|
22
27
|
},
|
|
23
28
|
"dependencies": {
|
|
24
29
|
"@wix/data": "^1.0.273",
|
|
25
30
|
"@wix/essentials": "^0.1.27",
|
|
26
|
-
"psdev-utils": "1.0
|
|
31
|
+
"psdev-utils": "1.1.0"
|
|
32
|
+
},
|
|
33
|
+
"devDependencies": {
|
|
34
|
+
"@eslint/js": "^9.12.0",
|
|
35
|
+
"eslint": "^9.12.0",
|
|
36
|
+
"eslint-config-prettier": "^9.1.0",
|
|
37
|
+
"eslint-plugin-import": "^2.30.0",
|
|
38
|
+
"eslint-plugin-prettier": "^5.2.1",
|
|
39
|
+
"eslint-plugin-promise": "^7.1.0",
|
|
40
|
+
"globals": "^15.10.0",
|
|
41
|
+
"husky": "^9.1.6",
|
|
42
|
+
"prettier": "^3.3.3"
|
|
27
43
|
}
|
|
28
44
|
}
|
package/public/consts.js
CHANGED