psdev-task-manager 2.0.4 → 2.0.6
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 +15 -16
- 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 +15 -7
- package/backend/tasks/tasks.js +26 -26
- package/backend/tasks/utils.js +28 -12
- package/eslint.config.js +113 -0
- package/index.js +1 -1
- package/package.json +19 -3
- package/public/consts.js +1 -1
|
@@ -3,10 +3,7 @@ name: Update Sites After Release Main
|
|
|
3
3
|
on:
|
|
4
4
|
push:
|
|
5
5
|
branches:
|
|
6
|
-
|
|
7
|
-
pull_request:
|
|
8
|
-
branches:
|
|
9
|
-
- main
|
|
6
|
+
- main
|
|
10
7
|
workflow_dispatch:
|
|
11
8
|
|
|
12
9
|
permissions:
|
|
@@ -14,15 +11,17 @@ permissions:
|
|
|
14
11
|
packages: write
|
|
15
12
|
|
|
16
13
|
jobs:
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
14
|
+
update-sites:
|
|
15
|
+
uses: psdevteamenterprise/ci-workflows/.github/workflows/update-and-notify.yml@main
|
|
16
|
+
with:
|
|
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
|
+
secrets:
|
|
22
|
+
GH_TOKEN: ${{ secrets.MY_GITHUB_TOKEN }}
|
|
23
|
+
NPM_TOKEN: ${{ secrets.NPM_TOKEN_PUBLISH }}
|
|
24
|
+
GH_APP_ID: ${{ secrets.GH_APP_ID }}
|
|
25
|
+
GH_APP_PRIVATE_KEY: ${{ secrets.GH_APP_PRIVATE_KEY }}
|
|
26
|
+
WIX_SR_API_KEY: ${{secrets.WIX_SR_API_KEY}}
|
|
27
|
+
WIX_PS_API_KEY: ${{secrets.WIX_PS_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,32 @@ 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
|
+
//Only throw error if task is permanently failed, otherwise we have retry mechanism
|
|
79
|
+
throw new Error(errMsg);
|
|
80
|
+
}
|
|
77
81
|
}
|
|
78
82
|
},
|
|
79
83
|
console
|
|
80
84
|
);
|
|
85
|
+
const processTask = (...args) => {
|
|
86
|
+
const requestName = `processTask_${args[0].name}`; //To get success rate analysis per task
|
|
87
|
+
return withSuccessRateLogs(requestName, () => processTaskWithDuration(...args));
|
|
88
|
+
};
|
|
81
89
|
/**
|
|
82
90
|
* @description Processing tasks based on how many the cron job tick can handle and running them sequentially to be as safe as possible
|
|
83
91
|
* */
|
|
84
92
|
const processTasksBasedOnVeloLimit = async (scheduledTasks, tasksConfig) => {
|
|
85
93
|
console.log(
|
|
86
|
-
`processTasksBasedOnVeloLimit: ${
|
|
94
|
+
`processTasksBasedOnVeloLimit: scheduledTasks count: ${scheduledTasks.length} tasksConfig: ${JSON.stringify(tasksConfig)}`
|
|
87
95
|
);
|
|
88
96
|
const toProcessTasks = getTasksToProcess({
|
|
89
97
|
scheduledTasks,
|
|
90
98
|
tasksConfig,
|
|
91
99
|
maxDuration: CRON_JOB_MAX_DURATION_SEC,
|
|
92
100
|
});
|
|
93
|
-
console.log(`processTasksBasedOnVeloLimit: toProcessTasks: ${
|
|
101
|
+
console.log(`processTasksBasedOnVeloLimit: toProcessTasks count: ${toProcessTasks.length}`);
|
|
94
102
|
console.log(
|
|
95
103
|
`[processTasksBasedOnVeloLimit] started processing: ${toProcessTasks.length} tasks`
|
|
96
104
|
);
|
|
@@ -113,7 +121,7 @@ function taskManager() {
|
|
|
113
121
|
const runScheduledTasks = async tasksConfig => {
|
|
114
122
|
try {
|
|
115
123
|
const scheduledTasks = await getScheduledTasks();
|
|
116
|
-
console.log(`runScheduledTasks: scheduledTasks: ${
|
|
124
|
+
console.log(`runScheduledTasks: scheduledTasks count: ${scheduledTasks.length}`);
|
|
117
125
|
console.log(`runScheduledTasks: tasksConfig: ${JSON.stringify(tasksConfig)}`);
|
|
118
126
|
if (scheduledTasks.length) {
|
|
119
127
|
await processTasksBasedOnVeloLimit(scheduledTasks, tasksConfig);
|
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
|
];
|
|
@@ -169,18 +169,30 @@ const isParentTask = (task, taskConfig) => {
|
|
|
169
169
|
};
|
|
170
170
|
const filterScheduledTasksByStatus = (tasks, tasksConfig) => {
|
|
171
171
|
console.log(
|
|
172
|
-
`filterScheduledTasksByStatus: ${
|
|
172
|
+
`filterScheduledTasksByStatus: tasks count: ${tasks.length} tasksConfig: ${JSON.stringify(tasksConfig)}`
|
|
173
173
|
);
|
|
174
|
-
const
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
174
|
+
const shouldIncludeTask = (task, taskConfig) => {
|
|
175
|
+
console.log(`filterScheduledTasksByStatus: task: ${JSON.stringify(task)}`);
|
|
176
|
+
console.log(`filterScheduledTasksByStatus: taskConfig: ${JSON.stringify(taskConfig)}`);
|
|
177
|
+
const { status } = task;
|
|
178
|
+
if (status === TASK_STATUS.IN_PROGRESS) {
|
|
179
|
+
//Only include parent tasks that are in progress, to continue running next children
|
|
180
|
+
return isParentTask(task, taskConfig);
|
|
180
181
|
}
|
|
182
|
+
//TODO: need to rethink of this as some parent tasks we use only to schedule children,
|
|
183
|
+
// if (status === TASK_STATUS.FAILED) {
|
|
184
|
+
// // Exclude if it's a parent task, if parent task failed, we don't retry it anymore
|
|
185
|
+
// return !isParentTask(task, taskConfig);
|
|
186
|
+
// }
|
|
187
|
+
// // Include if status is PENDING
|
|
188
|
+
// return status === TASK_STATUS.PENDING;
|
|
181
189
|
return [TASK_STATUS.PENDING, TASK_STATUS.FAILED].includes(task.status);
|
|
190
|
+
};
|
|
191
|
+
const filtered = tasks.filter(task => {
|
|
192
|
+
const taskConfig = tasksConfig[task.name];
|
|
193
|
+
return shouldIncludeTask(task, taskConfig);
|
|
182
194
|
});
|
|
183
|
-
console.log(`filterScheduledTasksByStatus: filtered: ${
|
|
195
|
+
console.log(`filterScheduledTasksByStatus: filtered count: ${filtered.length}`);
|
|
184
196
|
return filtered;
|
|
185
197
|
};
|
|
186
198
|
const getScheduledTasks = async () => {
|
|
@@ -221,12 +233,16 @@ const getTaskScheduledChildren = async parentTaskId => {
|
|
|
221
233
|
};
|
|
222
234
|
|
|
223
235
|
const getTasksToProcess = ({ scheduledTasks, tasksConfig, maxDuration }) => {
|
|
224
|
-
console.log('getTasksToProcess:', {
|
|
236
|
+
console.log('getTasksToProcess:', {
|
|
237
|
+
scheduledTasksCount: scheduledTasks.length,
|
|
238
|
+
tasksConfig,
|
|
239
|
+
maxDuration,
|
|
240
|
+
});
|
|
225
241
|
const tasksToProcess = [];
|
|
226
242
|
let totalDuration = 0;
|
|
227
243
|
console.log(`tasksConfig is : ${JSON.stringify(tasksConfig)}`);
|
|
228
244
|
const filteredScheduledTasks = filterScheduledTasksByStatus(scheduledTasks, tasksConfig);
|
|
229
|
-
console.log(`filteredScheduledTasks
|
|
245
|
+
console.log(`filteredScheduledTasks count : ${filteredScheduledTasks.length}`);
|
|
230
246
|
for (const task of filteredScheduledTasks) {
|
|
231
247
|
console.log(`task is : ${JSON.stringify(task)}`);
|
|
232
248
|
const taskConfig = getTaskConfig(task.name, tasksConfig);
|
|
@@ -243,7 +259,7 @@ const getTasksToProcess = ({ scheduledTasks, tasksConfig, maxDuration }) => {
|
|
|
243
259
|
totalDuration += buffered;
|
|
244
260
|
tasksToProcess.push(task);
|
|
245
261
|
}
|
|
246
|
-
console.log('getTasksToProcess: tasksToProcess:', tasksToProcess);
|
|
262
|
+
console.log('getTasksToProcess: tasksToProcess count:', tasksToProcess.length);
|
|
247
263
|
return tasksToProcess;
|
|
248
264
|
};
|
|
249
265
|
|
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": "2.0.
|
|
3
|
+
"version": "2.0.6",
|
|
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