@guanghechen/task 1.0.0-alpha.2 → 1.0.0-alpha.20
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/CHANGELOG.md +184 -0
- package/lib/cjs/index.cjs +89 -100
- package/lib/esm/index.mjs +86 -99
- package/lib/types/index.d.ts +12 -89
- package/package.json +20 -19
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,190 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
# [1.0.0-alpha.20](https://github.com/guanghechen/sora/compare/@guanghechen/task@1.0.0-alpha.19...@guanghechen/task@1.0.0-alpha.20) (2023-11-18)
|
|
7
|
+
|
|
8
|
+
**Note:** Version bump only for package @guanghechen/task
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
# [1.0.0-alpha.19](https://github.com/guanghechen/sora/compare/@guanghechen/task@1.0.0-alpha.18...@guanghechen/task@1.0.0-alpha.19) (2023-11-18)
|
|
15
|
+
|
|
16
|
+
**Note:** Version bump only for package @guanghechen/task
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
# [1.0.0-alpha.18](https://github.com/guanghechen/sora/compare/@guanghechen/task@1.0.0-alpha.17...@guanghechen/task@1.0.0-alpha.18) (2023-11-18)
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
### Performance Improvements
|
|
26
|
+
|
|
27
|
+
* 🔧 upgrade engine version requirement from '>= 16.0.0' to '>= 18.0.0' ([ddb9521](https://github.com/guanghechen/sora/commit/ddb9521b529b2ca838554794339b9e27ac80b8aa))
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
# [1.0.0-alpha.17](https://github.com/guanghechen/sora/compare/@guanghechen/task@1.0.0-alpha.16...@guanghechen/task@1.0.0-alpha.17) (2023-11-07)
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
### Performance Improvements
|
|
37
|
+
|
|
38
|
+
* 🔧 make tsconfig.json tidy ([809f8cf](https://github.com/guanghechen/sora/commit/809f8cf6b18da2d8fbba1566a5f4a783b52683da))
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
# [1.0.0-alpha.16](https://github.com/guanghechen/sora/compare/@guanghechen/task@1.0.0-alpha.15...@guanghechen/task@1.0.0-alpha.16) (2023-10-26)
|
|
45
|
+
|
|
46
|
+
**Note:** Version bump only for package @guanghechen/task
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
# [1.0.0-alpha.15](https://github.com/guanghechen/sora/compare/@guanghechen/task@1.0.0-alpha.14...@guanghechen/task@1.0.0-alpha.15) (2023-10-25)
|
|
53
|
+
|
|
54
|
+
**Note:** Version bump only for package @guanghechen/task
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
# [1.0.0-alpha.14](https://github.com/guanghechen/sora/compare/@guanghechen/task@1.0.0-alpha.13...@guanghechen/task@1.0.0-alpha.14) (2023-10-22)
|
|
61
|
+
|
|
62
|
+
**Note:** Version bump only for package @guanghechen/task
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
# [1.0.0-alpha.13](https://github.com/guanghechen/sora/compare/@guanghechen/task@1.0.0-alpha.12...@guanghechen/task@1.0.0-alpha.13) (2023-10-16)
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
### Performance Improvements
|
|
72
|
+
|
|
73
|
+
* 🔧 remove unnecessary devDependencies ([944f3ae](https://github.com/guanghechen/sora/commit/944f3aee64e68ce52ca30237c7d0240a82c9c58f))
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
# [1.0.0-alpha.12](https://github.com/guanghechen/sora/compare/@guanghechen/task@1.0.0-alpha.11...@guanghechen/task@1.0.0-alpha.12) (2023-10-10)
|
|
80
|
+
|
|
81
|
+
**Note:** Version bump only for package @guanghechen/task
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
# [1.0.0-alpha.11](https://github.com/guanghechen/sora/compare/@guanghechen/task@1.0.0-alpha.10...@guanghechen/task@1.0.0-alpha.11) (2023-10-09)
|
|
88
|
+
|
|
89
|
+
**Note:** Version bump only for package @guanghechen/task
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
# [1.0.0-alpha.10](https://github.com/guanghechen/sora/compare/@guanghechen/task@1.0.0-alpha.9...@guanghechen/task@1.0.0-alpha.10) (2023-10-04)
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
### Features
|
|
99
|
+
|
|
100
|
+
* ✨ add @guanghechen/scheduler.types and @guanghechen/task.types ([81fa522](https://github.com/guanghechen/sora/commit/81fa52203ace549fc15da97218bd38a31eda4af9))
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
### Performance Improvements
|
|
104
|
+
|
|
105
|
+
* fix type error ([d06e855](https://github.com/guanghechen/sora/commit/d06e855ccc9d98768fcd4dd171e9288d7b645bd2))
|
|
106
|
+
* :truck: move @guanghechen/_shared to @guanghechen/internal ([73a08c9](https://github.com/guanghechen/sora/commit/73a08c918d5bf1eeb3c6daa69dc50169198b77bf))
|
|
107
|
+
* 🎨 reorganize files ([0aef7fc](https://github.com/guanghechen/sora/commit/0aef7fce0cca25b2f4c40ba5881a37cdd1bcb40f))
|
|
108
|
+
* ⬆️ the version of subpackage devDependencies is not matter ([3287c22](https://github.com/guanghechen/sora/commit/3287c22fb150af6620c1c9f6f4b186498aea815b))
|
|
109
|
+
* ⬆️ upgrade dependencies ([7fcee0d](https://github.com/guanghechen/sora/commit/7fcee0de7b515b1cc9e18758c2be1f38a7374cfb))
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
# [1.0.0-alpha.9](https://github.com/guanghechen/sora/compare/@guanghechen/task@1.0.0-alpha.8...@guanghechen/task@1.0.0-alpha.9) (2023-09-16)
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
### Performance Improvements
|
|
119
|
+
|
|
120
|
+
* 🎨 expand monitors into smaller properties ([28179bf](https://github.com/guanghechen/sora/commit/28179bf6ab0904c5b669e33fbadc9f13f12ccab7))
|
|
121
|
+
* ⬆️ upgrade dependencies ([a259feb](https://github.com/guanghechen/sora/commit/a259feba5933148a34e4f498c9b883a5f87b7b50))
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
# [1.0.0-alpha.8](https://github.com/guanghechen/sora/compare/@guanghechen/task@1.0.0-alpha.7...@guanghechen/task@1.0.0-alpha.8) (2023-09-14)
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
### Performance Improvements
|
|
131
|
+
|
|
132
|
+
* ⬆️ upgrade dependencies ([0af59d8](https://github.com/guanghechen/sora/commit/0af59d85d8c2c514f57e5289e87f0a3cbb6ab5ab))
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
# [1.0.0-alpha.7](https://github.com/guanghechen/sora/compare/@guanghechen/task@1.0.0-alpha.6...@guanghechen/task@1.0.0-alpha.7) (2023-09-07)
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
### Performance Improvements
|
|
142
|
+
|
|
143
|
+
* ⬆️ upgrade dev dependencies & fix rollup config ([593e19b](https://github.com/guanghechen/sora/commit/593e19bf68c159ec4f9f5d34a567c832997b5055))
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
# [1.0.0-alpha.6](https://github.com/guanghechen/sora/compare/@guanghechen/task@1.0.0-alpha.5...@guanghechen/task@1.0.0-alpha.6) (2023-09-06)
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
### Performance Improvements
|
|
153
|
+
|
|
154
|
+
* 🔧 update entries, support both esm and cjs ([b3f54dd](https://github.com/guanghechen/sora/commit/b3f54dde89d3b079c422e062cef795194482e165))
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
# [1.0.0-alpha.5](https://github.com/guanghechen/sora/compare/@guanghechen/task@1.0.0-alpha.4...@guanghechen/task@1.0.0-alpha.5) (2023-09-05)
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
### Performance Improvements
|
|
164
|
+
|
|
165
|
+
* 🎨 re-export types and constants ([7213062](https://github.com/guanghechen/sora/commit/721306218d253c3dad6549f145cf51c81e86d9ad))
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
# [1.0.0-alpha.4](https://github.com/guanghechen/sora/compare/@guanghechen/task@1.0.0-alpha.3...@guanghechen/task@1.0.0-alpha.4) (2023-09-02)
|
|
172
|
+
|
|
173
|
+
**Note:** Version bump only for package @guanghechen/task
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
# [1.0.0-alpha.3](https://github.com/guanghechen/sora/compare/@guanghechen/task@1.0.0-alpha.2...@guanghechen/task@1.0.0-alpha.3) (2023-08-30)
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
### Performance Improvements
|
|
183
|
+
|
|
184
|
+
* 🎨 reuse constants and types ([5efb70e](https://github.com/guanghechen/sora/commit/5efb70e6df130dc870ccb5add632291dcbd94809))
|
|
185
|
+
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
|
|
6
190
|
# [1.0.0-alpha.2](https://github.com/guanghechen/sora/compare/@guanghechen/task@1.0.0-alpha.1...@guanghechen/task@1.0.0-alpha.2) (2023-08-28)
|
|
7
191
|
|
|
8
192
|
|
package/lib/cjs/index.cjs
CHANGED
|
@@ -1,53 +1,39 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
var task_types = require('@guanghechen/task.types');
|
|
3
4
|
var error = require('@guanghechen/error');
|
|
5
|
+
require('node:fs');
|
|
6
|
+
require('node:fs/promises');
|
|
7
|
+
require('node:path');
|
|
4
8
|
var monitor = require('@guanghechen/monitor');
|
|
5
9
|
|
|
6
|
-
|
|
7
|
-
(function (TaskStatus) {
|
|
8
|
-
TaskStatus[TaskStatus["PENDING"] = 1] = "PENDING";
|
|
9
|
-
TaskStatus[TaskStatus["RUNNING"] = 2] = "RUNNING";
|
|
10
|
-
TaskStatus[TaskStatus["SUSPENDED"] = 4] = "SUSPENDED";
|
|
11
|
-
TaskStatus[TaskStatus["CANCELLED"] = 8] = "CANCELLED";
|
|
12
|
-
TaskStatus[TaskStatus["FAILED"] = 16] = "FAILED";
|
|
13
|
-
TaskStatus[TaskStatus["FINISHED"] = 32] = "FINISHED";
|
|
14
|
-
TaskStatus[TaskStatus["ATTEMPT_SUSPENDING"] = 64] = "ATTEMPT_SUSPENDING";
|
|
15
|
-
TaskStatus[TaskStatus["ATTEMPT_RESUMING"] = 128] = "ATTEMPT_RESUMING";
|
|
16
|
-
TaskStatus[TaskStatus["ATTEMPT_CANCELING"] = 256] = "ATTEMPT_CANCELING";
|
|
17
|
-
TaskStatus[TaskStatus["ATTEMPT_FINISHING"] = 512] = "ATTEMPT_FINISHING";
|
|
18
|
-
})(exports.TaskStatus || (exports.TaskStatus = {}));
|
|
19
|
-
exports.TaskStrategy = void 0;
|
|
20
|
-
(function (TaskStrategy) {
|
|
21
|
-
TaskStrategy[TaskStrategy["ABORT_ON_ERROR"] = 1] = "ABORT_ON_ERROR";
|
|
22
|
-
TaskStrategy[TaskStrategy["CONTINUE_ON_ERROR"] = 2] = "CONTINUE_ON_ERROR";
|
|
23
|
-
})(exports.TaskStrategy || (exports.TaskStrategy = {}));
|
|
24
|
-
const active = exports.TaskStatus.RUNNING |
|
|
25
|
-
exports.TaskStatus.ATTEMPT_SUSPENDING |
|
|
26
|
-
exports.TaskStatus.ATTEMPT_RESUMING;
|
|
27
|
-
const alive = exports.TaskStatus.PENDING |
|
|
28
|
-
exports.TaskStatus.RUNNING |
|
|
29
|
-
exports.TaskStatus.SUSPENDED |
|
|
30
|
-
exports.TaskStatus.ATTEMPT_SUSPENDING |
|
|
31
|
-
exports.TaskStatus.ATTEMPT_RESUMING;
|
|
32
|
-
const terminated = exports.TaskStatus.CANCELLED |
|
|
33
|
-
exports.TaskStatus.FAILED |
|
|
34
|
-
exports.TaskStatus.FINISHED;
|
|
10
|
+
process.env.NODE_ENV === 'production';
|
|
35
11
|
|
|
36
12
|
function noop(..._args) { }
|
|
37
13
|
|
|
14
|
+
const active = task_types.TaskStatusEnum.RUNNING |
|
|
15
|
+
task_types.TaskStatusEnum.ATTEMPT_SUSPENDING |
|
|
16
|
+
task_types.TaskStatusEnum.ATTEMPT_RESUMING;
|
|
17
|
+
const alive = task_types.TaskStatusEnum.PENDING |
|
|
18
|
+
task_types.TaskStatusEnum.RUNNING |
|
|
19
|
+
task_types.TaskStatusEnum.SUSPENDED |
|
|
20
|
+
task_types.TaskStatusEnum.ATTEMPT_SUSPENDING |
|
|
21
|
+
task_types.TaskStatusEnum.ATTEMPT_RESUMING;
|
|
22
|
+
const terminated = task_types.TaskStatusEnum.CANCELLED |
|
|
23
|
+
task_types.TaskStatusEnum.FAILED |
|
|
24
|
+
task_types.TaskStatusEnum.FINISHED;
|
|
38
25
|
class TaskState {
|
|
39
26
|
name;
|
|
40
27
|
_errorCollector;
|
|
41
|
-
|
|
28
|
+
_monitorAddError;
|
|
29
|
+
_monitorStatusChange;
|
|
42
30
|
_status;
|
|
43
31
|
constructor(name) {
|
|
44
32
|
this.name = name;
|
|
45
33
|
this._errorCollector = new error.SoraErrorCollector(name);
|
|
46
|
-
this.
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
};
|
|
50
|
-
this._status = exports.TaskStatus.PENDING;
|
|
34
|
+
this._monitorAddError = new monitor.Monitor('onAddError');
|
|
35
|
+
this._monitorStatusChange = new monitor.Monitor('onStatusChange');
|
|
36
|
+
this._status = task_types.TaskStatusEnum.PENDING;
|
|
51
37
|
}
|
|
52
38
|
get status() {
|
|
53
39
|
return this._status;
|
|
@@ -75,7 +61,7 @@ class TaskState {
|
|
|
75
61
|
const accepted = this.check(status);
|
|
76
62
|
if (accepted) {
|
|
77
63
|
this._status = status;
|
|
78
|
-
this.
|
|
64
|
+
this._monitorStatusChange.notify(status, curStatus);
|
|
79
65
|
}
|
|
80
66
|
else {
|
|
81
67
|
throw new TypeError(`[transit] unexpected status: task(${this.name}) cur(${curStatus}) next(${status})`);
|
|
@@ -86,8 +72,8 @@ class TaskState {
|
|
|
86
72
|
if (this.terminated)
|
|
87
73
|
return noop;
|
|
88
74
|
const { onAddError, onStatusChange } = monitor;
|
|
89
|
-
const unsubscribeOnAddError = this.
|
|
90
|
-
const unsubscribeOnStatusChange = this.
|
|
75
|
+
const unsubscribeOnAddError = this._monitorAddError.subscribe(onAddError);
|
|
76
|
+
const unsubscribeOnStatusChange = this._monitorStatusChange.subscribe(onStatusChange);
|
|
91
77
|
return () => {
|
|
92
78
|
unsubscribeOnAddError();
|
|
93
79
|
unsubscribeOnStatusChange();
|
|
@@ -96,30 +82,30 @@ class TaskState {
|
|
|
96
82
|
check(nextStatus) {
|
|
97
83
|
const status = this._status;
|
|
98
84
|
switch (nextStatus) {
|
|
99
|
-
case
|
|
85
|
+
case task_types.TaskStatusEnum.PENDING:
|
|
100
86
|
return false;
|
|
101
|
-
case
|
|
102
|
-
return status ===
|
|
103
|
-
case
|
|
104
|
-
return status ===
|
|
105
|
-
case
|
|
106
|
-
return status ===
|
|
107
|
-
case
|
|
108
|
-
return (status !==
|
|
109
|
-
status !==
|
|
87
|
+
case task_types.TaskStatusEnum.RUNNING:
|
|
88
|
+
return status === task_types.TaskStatusEnum.PENDING || status === task_types.TaskStatusEnum.ATTEMPT_RESUMING;
|
|
89
|
+
case task_types.TaskStatusEnum.SUSPENDED:
|
|
90
|
+
return status === task_types.TaskStatusEnum.ATTEMPT_SUSPENDING;
|
|
91
|
+
case task_types.TaskStatusEnum.CANCELLED:
|
|
92
|
+
return status === task_types.TaskStatusEnum.ATTEMPT_CANCELING;
|
|
93
|
+
case task_types.TaskStatusEnum.FAILED:
|
|
94
|
+
return (status !== task_types.TaskStatusEnum.PENDING &&
|
|
95
|
+
status !== task_types.TaskStatusEnum.SUSPENDED &&
|
|
110
96
|
(status & terminated) === 0);
|
|
111
|
-
case
|
|
112
|
-
return (status !==
|
|
113
|
-
status !==
|
|
97
|
+
case task_types.TaskStatusEnum.FINISHED:
|
|
98
|
+
return (status !== task_types.TaskStatusEnum.PENDING &&
|
|
99
|
+
status !== task_types.TaskStatusEnum.SUSPENDED &&
|
|
114
100
|
(status & terminated) === 0);
|
|
115
|
-
case
|
|
116
|
-
return status ===
|
|
117
|
-
case
|
|
118
|
-
return status ===
|
|
119
|
-
case
|
|
101
|
+
case task_types.TaskStatusEnum.ATTEMPT_SUSPENDING:
|
|
102
|
+
return status === task_types.TaskStatusEnum.RUNNING;
|
|
103
|
+
case task_types.TaskStatusEnum.ATTEMPT_RESUMING:
|
|
104
|
+
return status === task_types.TaskStatusEnum.SUSPENDED;
|
|
105
|
+
case task_types.TaskStatusEnum.ATTEMPT_CANCELING:
|
|
120
106
|
return (status & alive) > 0;
|
|
121
|
-
case
|
|
122
|
-
return status !==
|
|
107
|
+
case task_types.TaskStatusEnum.ATTEMPT_FINISHING:
|
|
108
|
+
return status !== task_types.TaskStatusEnum.PENDING && (status & alive) > 0;
|
|
123
109
|
default:
|
|
124
110
|
return false;
|
|
125
111
|
}
|
|
@@ -128,12 +114,12 @@ class TaskState {
|
|
|
128
114
|
if (!this.terminated)
|
|
129
115
|
throw new Error(`[cleanup] task(${this.name}) is not terminated`);
|
|
130
116
|
this._errorCollector.cleanup();
|
|
131
|
-
this.
|
|
132
|
-
this.
|
|
117
|
+
this._monitorStatusChange.destroy();
|
|
118
|
+
this._monitorAddError.destroy();
|
|
133
119
|
}
|
|
134
|
-
_addError(type, error$1, level = error.
|
|
120
|
+
_addError(type, error$1, level = error.ErrorLevelEnum.ERROR) {
|
|
135
121
|
this._errorCollector.add(type, error$1, level);
|
|
136
|
-
this.
|
|
122
|
+
this._monitorAddError.notify(type, error$1, level);
|
|
137
123
|
}
|
|
138
124
|
}
|
|
139
125
|
|
|
@@ -144,15 +130,15 @@ class AtomicTask extends TaskState {
|
|
|
144
130
|
this._promise = undefined;
|
|
145
131
|
}
|
|
146
132
|
async start() {
|
|
147
|
-
if (this.status ===
|
|
148
|
-
this.status =
|
|
133
|
+
if (this.status === task_types.TaskStatusEnum.PENDING) {
|
|
134
|
+
this.status = task_types.TaskStatusEnum.RUNNING;
|
|
149
135
|
this._promise = this.run()
|
|
150
136
|
.then(() => {
|
|
151
|
-
this.status =
|
|
137
|
+
this.status = task_types.TaskStatusEnum.FINISHED;
|
|
152
138
|
})
|
|
153
139
|
.catch(error => {
|
|
154
|
-
this.status = exports.TaskStatus.FAILED;
|
|
155
140
|
this._addError('AtomicTaskError', error);
|
|
141
|
+
this.status = task_types.TaskStatusEnum.FAILED;
|
|
156
142
|
});
|
|
157
143
|
}
|
|
158
144
|
return this._promise;
|
|
@@ -164,20 +150,20 @@ class AtomicTask extends TaskState {
|
|
|
164
150
|
await this._promise;
|
|
165
151
|
}
|
|
166
152
|
async cancel() {
|
|
167
|
-
if (this.status ===
|
|
168
|
-
this.status =
|
|
169
|
-
this.status =
|
|
153
|
+
if (this.status === task_types.TaskStatusEnum.PENDING) {
|
|
154
|
+
this.status = task_types.TaskStatusEnum.ATTEMPT_CANCELING;
|
|
155
|
+
this.status = task_types.TaskStatusEnum.CANCELLED;
|
|
170
156
|
return;
|
|
171
157
|
}
|
|
172
158
|
if (this.alive)
|
|
173
|
-
this.status =
|
|
159
|
+
this.status = task_types.TaskStatusEnum.ATTEMPT_CANCELING;
|
|
174
160
|
await this._promise;
|
|
175
161
|
}
|
|
176
162
|
async finish() {
|
|
177
|
-
if (this.status ===
|
|
163
|
+
if (this.status === task_types.TaskStatusEnum.PENDING)
|
|
178
164
|
await this.start();
|
|
179
165
|
if (this.alive)
|
|
180
|
-
this.status =
|
|
166
|
+
this.status = task_types.TaskStatusEnum.ATTEMPT_FINISHING;
|
|
181
167
|
await this._promise;
|
|
182
168
|
}
|
|
183
169
|
}
|
|
@@ -195,63 +181,63 @@ class ResumableTask extends TaskState {
|
|
|
195
181
|
this._step = undefined;
|
|
196
182
|
}
|
|
197
183
|
async start() {
|
|
198
|
-
if (this.status ===
|
|
199
|
-
this.status =
|
|
184
|
+
if (this.status === task_types.TaskStatusEnum.PENDING) {
|
|
185
|
+
this.status = task_types.TaskStatusEnum.RUNNING;
|
|
200
186
|
this._execution = this.run();
|
|
201
187
|
this.launchStep();
|
|
202
188
|
await this._step;
|
|
203
189
|
}
|
|
204
190
|
}
|
|
205
191
|
async pause() {
|
|
206
|
-
if (this.status ===
|
|
207
|
-
this.status =
|
|
192
|
+
if (this.status === task_types.TaskStatusEnum.RUNNING) {
|
|
193
|
+
this.status = task_types.TaskStatusEnum.ATTEMPT_SUSPENDING;
|
|
208
194
|
await this._step;
|
|
209
|
-
if (this.status ===
|
|
210
|
-
this.status =
|
|
195
|
+
if (this.status === task_types.TaskStatusEnum.ATTEMPT_SUSPENDING) {
|
|
196
|
+
this.status = task_types.TaskStatusEnum.SUSPENDED;
|
|
211
197
|
}
|
|
212
198
|
}
|
|
213
199
|
}
|
|
214
200
|
async resume() {
|
|
215
|
-
if (this.status ===
|
|
216
|
-
this.status =
|
|
201
|
+
if (this.status === task_types.TaskStatusEnum.SUSPENDED) {
|
|
202
|
+
this.status = task_types.TaskStatusEnum.ATTEMPT_RESUMING;
|
|
217
203
|
await this._step;
|
|
218
|
-
if (this.status ===
|
|
219
|
-
this.status =
|
|
204
|
+
if (this.status === task_types.TaskStatusEnum.ATTEMPT_RESUMING) {
|
|
205
|
+
this.status = task_types.TaskStatusEnum.RUNNING;
|
|
220
206
|
this.queueStep();
|
|
221
207
|
}
|
|
222
208
|
}
|
|
223
209
|
}
|
|
224
210
|
async cancel() {
|
|
225
211
|
if (this.alive) {
|
|
226
|
-
this.status =
|
|
212
|
+
this.status = task_types.TaskStatusEnum.ATTEMPT_CANCELING;
|
|
227
213
|
await this._step;
|
|
228
|
-
if (this.status ===
|
|
229
|
-
this.status =
|
|
214
|
+
if (this.status === task_types.TaskStatusEnum.ATTEMPT_CANCELING) {
|
|
215
|
+
this.status = task_types.TaskStatusEnum.CANCELLED;
|
|
230
216
|
}
|
|
231
217
|
}
|
|
232
218
|
}
|
|
233
219
|
async finish() {
|
|
234
|
-
if (this.status ===
|
|
220
|
+
if (this.status === task_types.TaskStatusEnum.PENDING)
|
|
235
221
|
await this.start();
|
|
236
222
|
if (this.alive) {
|
|
237
|
-
this.status =
|
|
223
|
+
this.status = task_types.TaskStatusEnum.ATTEMPT_FINISHING;
|
|
238
224
|
await this._step;
|
|
239
225
|
const execution = this._execution;
|
|
240
226
|
if (execution) {
|
|
241
|
-
while (this.status ===
|
|
227
|
+
while (this.status === task_types.TaskStatusEnum.ATTEMPT_FINISHING) {
|
|
242
228
|
const step = execution.next();
|
|
243
229
|
if (step.done) {
|
|
244
|
-
this.status = this.hasError ?
|
|
230
|
+
this.status = this.hasError ? task_types.TaskStatusEnum.FAILED : task_types.TaskStatusEnum.FINISHED;
|
|
245
231
|
break;
|
|
246
232
|
}
|
|
247
233
|
await step.value.catch(error => {
|
|
248
234
|
this._addError('ResumableTaskError', error);
|
|
249
235
|
switch (this.strategy) {
|
|
250
|
-
case
|
|
236
|
+
case task_types.TaskStrategyEnum.ABORT_ON_ERROR:
|
|
251
237
|
if (!this.terminated)
|
|
252
|
-
this.status =
|
|
238
|
+
this.status = task_types.TaskStatusEnum.FAILED;
|
|
253
239
|
break;
|
|
254
|
-
case
|
|
240
|
+
case task_types.TaskStrategyEnum.CONTINUE_ON_ERROR:
|
|
255
241
|
break;
|
|
256
242
|
}
|
|
257
243
|
});
|
|
@@ -260,10 +246,10 @@ class ResumableTask extends TaskState {
|
|
|
260
246
|
}
|
|
261
247
|
}
|
|
262
248
|
launchStep() {
|
|
263
|
-
if (this.status ===
|
|
249
|
+
if (this.status === task_types.TaskStatusEnum.RUNNING && this._step === undefined && this._execution) {
|
|
264
250
|
const step = this._execution.next();
|
|
265
251
|
if (step.done) {
|
|
266
|
-
this.status = this.hasError ?
|
|
252
|
+
this.status = this.hasError ? task_types.TaskStatusEnum.FAILED : task_types.TaskStatusEnum.FINISHED;
|
|
267
253
|
return;
|
|
268
254
|
}
|
|
269
255
|
this._step = step.value
|
|
@@ -275,11 +261,11 @@ class ResumableTask extends TaskState {
|
|
|
275
261
|
this._step = undefined;
|
|
276
262
|
this._addError('ResumableTaskError', error);
|
|
277
263
|
switch (this.strategy) {
|
|
278
|
-
case
|
|
264
|
+
case task_types.TaskStrategyEnum.ABORT_ON_ERROR:
|
|
279
265
|
if (!this.terminated)
|
|
280
|
-
this.status =
|
|
266
|
+
this.status = task_types.TaskStatusEnum.FAILED;
|
|
281
267
|
break;
|
|
282
|
-
case
|
|
268
|
+
case task_types.TaskStrategyEnum.CONTINUE_ON_ERROR:
|
|
283
269
|
this.queueStep();
|
|
284
270
|
break;
|
|
285
271
|
}
|
|
@@ -294,6 +280,9 @@ class ResumableTask extends TaskState {
|
|
|
294
280
|
exports.AtomicTask = AtomicTask;
|
|
295
281
|
exports.ResumableTask = ResumableTask;
|
|
296
282
|
exports.TaskState = TaskState;
|
|
297
|
-
|
|
298
|
-
exports.
|
|
299
|
-
|
|
283
|
+
Object.keys(task_types).forEach(function (k) {
|
|
284
|
+
if (k !== 'default' && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {
|
|
285
|
+
enumerable: true,
|
|
286
|
+
get: function () { return task_types[k]; }
|
|
287
|
+
});
|
|
288
|
+
});
|
package/lib/esm/index.mjs
CHANGED
|
@@ -1,51 +1,38 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { TaskStatusEnum, TaskStrategyEnum } from '@guanghechen/task.types';
|
|
2
|
+
export * from '@guanghechen/task.types';
|
|
3
|
+
import { SoraErrorCollector, ErrorLevelEnum } from '@guanghechen/error';
|
|
4
|
+
import 'node:fs';
|
|
5
|
+
import 'node:fs/promises';
|
|
6
|
+
import 'node:path';
|
|
2
7
|
import { Monitor } from '@guanghechen/monitor';
|
|
3
8
|
|
|
4
|
-
|
|
5
|
-
(function (TaskStatus) {
|
|
6
|
-
TaskStatus[TaskStatus["PENDING"] = 1] = "PENDING";
|
|
7
|
-
TaskStatus[TaskStatus["RUNNING"] = 2] = "RUNNING";
|
|
8
|
-
TaskStatus[TaskStatus["SUSPENDED"] = 4] = "SUSPENDED";
|
|
9
|
-
TaskStatus[TaskStatus["CANCELLED"] = 8] = "CANCELLED";
|
|
10
|
-
TaskStatus[TaskStatus["FAILED"] = 16] = "FAILED";
|
|
11
|
-
TaskStatus[TaskStatus["FINISHED"] = 32] = "FINISHED";
|
|
12
|
-
TaskStatus[TaskStatus["ATTEMPT_SUSPENDING"] = 64] = "ATTEMPT_SUSPENDING";
|
|
13
|
-
TaskStatus[TaskStatus["ATTEMPT_RESUMING"] = 128] = "ATTEMPT_RESUMING";
|
|
14
|
-
TaskStatus[TaskStatus["ATTEMPT_CANCELING"] = 256] = "ATTEMPT_CANCELING";
|
|
15
|
-
TaskStatus[TaskStatus["ATTEMPT_FINISHING"] = 512] = "ATTEMPT_FINISHING";
|
|
16
|
-
})(TaskStatus || (TaskStatus = {}));
|
|
17
|
-
var TaskStrategy;
|
|
18
|
-
(function (TaskStrategy) {
|
|
19
|
-
TaskStrategy[TaskStrategy["ABORT_ON_ERROR"] = 1] = "ABORT_ON_ERROR";
|
|
20
|
-
TaskStrategy[TaskStrategy["CONTINUE_ON_ERROR"] = 2] = "CONTINUE_ON_ERROR";
|
|
21
|
-
})(TaskStrategy || (TaskStrategy = {}));
|
|
22
|
-
const active = TaskStatus.RUNNING |
|
|
23
|
-
TaskStatus.ATTEMPT_SUSPENDING |
|
|
24
|
-
TaskStatus.ATTEMPT_RESUMING;
|
|
25
|
-
const alive = TaskStatus.PENDING |
|
|
26
|
-
TaskStatus.RUNNING |
|
|
27
|
-
TaskStatus.SUSPENDED |
|
|
28
|
-
TaskStatus.ATTEMPT_SUSPENDING |
|
|
29
|
-
TaskStatus.ATTEMPT_RESUMING;
|
|
30
|
-
const terminated = TaskStatus.CANCELLED |
|
|
31
|
-
TaskStatus.FAILED |
|
|
32
|
-
TaskStatus.FINISHED;
|
|
9
|
+
process.env.NODE_ENV === 'production';
|
|
33
10
|
|
|
34
11
|
function noop(..._args) { }
|
|
35
12
|
|
|
13
|
+
const active = TaskStatusEnum.RUNNING |
|
|
14
|
+
TaskStatusEnum.ATTEMPT_SUSPENDING |
|
|
15
|
+
TaskStatusEnum.ATTEMPT_RESUMING;
|
|
16
|
+
const alive = TaskStatusEnum.PENDING |
|
|
17
|
+
TaskStatusEnum.RUNNING |
|
|
18
|
+
TaskStatusEnum.SUSPENDED |
|
|
19
|
+
TaskStatusEnum.ATTEMPT_SUSPENDING |
|
|
20
|
+
TaskStatusEnum.ATTEMPT_RESUMING;
|
|
21
|
+
const terminated = TaskStatusEnum.CANCELLED |
|
|
22
|
+
TaskStatusEnum.FAILED |
|
|
23
|
+
TaskStatusEnum.FINISHED;
|
|
36
24
|
class TaskState {
|
|
37
25
|
name;
|
|
38
26
|
_errorCollector;
|
|
39
|
-
|
|
27
|
+
_monitorAddError;
|
|
28
|
+
_monitorStatusChange;
|
|
40
29
|
_status;
|
|
41
30
|
constructor(name) {
|
|
42
31
|
this.name = name;
|
|
43
32
|
this._errorCollector = new SoraErrorCollector(name);
|
|
44
|
-
this.
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
};
|
|
48
|
-
this._status = TaskStatus.PENDING;
|
|
33
|
+
this._monitorAddError = new Monitor('onAddError');
|
|
34
|
+
this._monitorStatusChange = new Monitor('onStatusChange');
|
|
35
|
+
this._status = TaskStatusEnum.PENDING;
|
|
49
36
|
}
|
|
50
37
|
get status() {
|
|
51
38
|
return this._status;
|
|
@@ -73,7 +60,7 @@ class TaskState {
|
|
|
73
60
|
const accepted = this.check(status);
|
|
74
61
|
if (accepted) {
|
|
75
62
|
this._status = status;
|
|
76
|
-
this.
|
|
63
|
+
this._monitorStatusChange.notify(status, curStatus);
|
|
77
64
|
}
|
|
78
65
|
else {
|
|
79
66
|
throw new TypeError(`[transit] unexpected status: task(${this.name}) cur(${curStatus}) next(${status})`);
|
|
@@ -84,8 +71,8 @@ class TaskState {
|
|
|
84
71
|
if (this.terminated)
|
|
85
72
|
return noop;
|
|
86
73
|
const { onAddError, onStatusChange } = monitor;
|
|
87
|
-
const unsubscribeOnAddError = this.
|
|
88
|
-
const unsubscribeOnStatusChange = this.
|
|
74
|
+
const unsubscribeOnAddError = this._monitorAddError.subscribe(onAddError);
|
|
75
|
+
const unsubscribeOnStatusChange = this._monitorStatusChange.subscribe(onStatusChange);
|
|
89
76
|
return () => {
|
|
90
77
|
unsubscribeOnAddError();
|
|
91
78
|
unsubscribeOnStatusChange();
|
|
@@ -94,30 +81,30 @@ class TaskState {
|
|
|
94
81
|
check(nextStatus) {
|
|
95
82
|
const status = this._status;
|
|
96
83
|
switch (nextStatus) {
|
|
97
|
-
case
|
|
84
|
+
case TaskStatusEnum.PENDING:
|
|
98
85
|
return false;
|
|
99
|
-
case
|
|
100
|
-
return status ===
|
|
101
|
-
case
|
|
102
|
-
return status ===
|
|
103
|
-
case
|
|
104
|
-
return status ===
|
|
105
|
-
case
|
|
106
|
-
return (status !==
|
|
107
|
-
status !==
|
|
86
|
+
case TaskStatusEnum.RUNNING:
|
|
87
|
+
return status === TaskStatusEnum.PENDING || status === TaskStatusEnum.ATTEMPT_RESUMING;
|
|
88
|
+
case TaskStatusEnum.SUSPENDED:
|
|
89
|
+
return status === TaskStatusEnum.ATTEMPT_SUSPENDING;
|
|
90
|
+
case TaskStatusEnum.CANCELLED:
|
|
91
|
+
return status === TaskStatusEnum.ATTEMPT_CANCELING;
|
|
92
|
+
case TaskStatusEnum.FAILED:
|
|
93
|
+
return (status !== TaskStatusEnum.PENDING &&
|
|
94
|
+
status !== TaskStatusEnum.SUSPENDED &&
|
|
108
95
|
(status & terminated) === 0);
|
|
109
|
-
case
|
|
110
|
-
return (status !==
|
|
111
|
-
status !==
|
|
96
|
+
case TaskStatusEnum.FINISHED:
|
|
97
|
+
return (status !== TaskStatusEnum.PENDING &&
|
|
98
|
+
status !== TaskStatusEnum.SUSPENDED &&
|
|
112
99
|
(status & terminated) === 0);
|
|
113
|
-
case
|
|
114
|
-
return status ===
|
|
115
|
-
case
|
|
116
|
-
return status ===
|
|
117
|
-
case
|
|
100
|
+
case TaskStatusEnum.ATTEMPT_SUSPENDING:
|
|
101
|
+
return status === TaskStatusEnum.RUNNING;
|
|
102
|
+
case TaskStatusEnum.ATTEMPT_RESUMING:
|
|
103
|
+
return status === TaskStatusEnum.SUSPENDED;
|
|
104
|
+
case TaskStatusEnum.ATTEMPT_CANCELING:
|
|
118
105
|
return (status & alive) > 0;
|
|
119
|
-
case
|
|
120
|
-
return status !==
|
|
106
|
+
case TaskStatusEnum.ATTEMPT_FINISHING:
|
|
107
|
+
return status !== TaskStatusEnum.PENDING && (status & alive) > 0;
|
|
121
108
|
default:
|
|
122
109
|
return false;
|
|
123
110
|
}
|
|
@@ -126,12 +113,12 @@ class TaskState {
|
|
|
126
113
|
if (!this.terminated)
|
|
127
114
|
throw new Error(`[cleanup] task(${this.name}) is not terminated`);
|
|
128
115
|
this._errorCollector.cleanup();
|
|
129
|
-
this.
|
|
130
|
-
this.
|
|
116
|
+
this._monitorStatusChange.destroy();
|
|
117
|
+
this._monitorAddError.destroy();
|
|
131
118
|
}
|
|
132
|
-
_addError(type, error, level =
|
|
119
|
+
_addError(type, error, level = ErrorLevelEnum.ERROR) {
|
|
133
120
|
this._errorCollector.add(type, error, level);
|
|
134
|
-
this.
|
|
121
|
+
this._monitorAddError.notify(type, error, level);
|
|
135
122
|
}
|
|
136
123
|
}
|
|
137
124
|
|
|
@@ -142,15 +129,15 @@ class AtomicTask extends TaskState {
|
|
|
142
129
|
this._promise = undefined;
|
|
143
130
|
}
|
|
144
131
|
async start() {
|
|
145
|
-
if (this.status ===
|
|
146
|
-
this.status =
|
|
132
|
+
if (this.status === TaskStatusEnum.PENDING) {
|
|
133
|
+
this.status = TaskStatusEnum.RUNNING;
|
|
147
134
|
this._promise = this.run()
|
|
148
135
|
.then(() => {
|
|
149
|
-
this.status =
|
|
136
|
+
this.status = TaskStatusEnum.FINISHED;
|
|
150
137
|
})
|
|
151
138
|
.catch(error => {
|
|
152
|
-
this.status = TaskStatus.FAILED;
|
|
153
139
|
this._addError('AtomicTaskError', error);
|
|
140
|
+
this.status = TaskStatusEnum.FAILED;
|
|
154
141
|
});
|
|
155
142
|
}
|
|
156
143
|
return this._promise;
|
|
@@ -162,20 +149,20 @@ class AtomicTask extends TaskState {
|
|
|
162
149
|
await this._promise;
|
|
163
150
|
}
|
|
164
151
|
async cancel() {
|
|
165
|
-
if (this.status ===
|
|
166
|
-
this.status =
|
|
167
|
-
this.status =
|
|
152
|
+
if (this.status === TaskStatusEnum.PENDING) {
|
|
153
|
+
this.status = TaskStatusEnum.ATTEMPT_CANCELING;
|
|
154
|
+
this.status = TaskStatusEnum.CANCELLED;
|
|
168
155
|
return;
|
|
169
156
|
}
|
|
170
157
|
if (this.alive)
|
|
171
|
-
this.status =
|
|
158
|
+
this.status = TaskStatusEnum.ATTEMPT_CANCELING;
|
|
172
159
|
await this._promise;
|
|
173
160
|
}
|
|
174
161
|
async finish() {
|
|
175
|
-
if (this.status ===
|
|
162
|
+
if (this.status === TaskStatusEnum.PENDING)
|
|
176
163
|
await this.start();
|
|
177
164
|
if (this.alive)
|
|
178
|
-
this.status =
|
|
165
|
+
this.status = TaskStatusEnum.ATTEMPT_FINISHING;
|
|
179
166
|
await this._promise;
|
|
180
167
|
}
|
|
181
168
|
}
|
|
@@ -193,63 +180,63 @@ class ResumableTask extends TaskState {
|
|
|
193
180
|
this._step = undefined;
|
|
194
181
|
}
|
|
195
182
|
async start() {
|
|
196
|
-
if (this.status ===
|
|
197
|
-
this.status =
|
|
183
|
+
if (this.status === TaskStatusEnum.PENDING) {
|
|
184
|
+
this.status = TaskStatusEnum.RUNNING;
|
|
198
185
|
this._execution = this.run();
|
|
199
186
|
this.launchStep();
|
|
200
187
|
await this._step;
|
|
201
188
|
}
|
|
202
189
|
}
|
|
203
190
|
async pause() {
|
|
204
|
-
if (this.status ===
|
|
205
|
-
this.status =
|
|
191
|
+
if (this.status === TaskStatusEnum.RUNNING) {
|
|
192
|
+
this.status = TaskStatusEnum.ATTEMPT_SUSPENDING;
|
|
206
193
|
await this._step;
|
|
207
|
-
if (this.status ===
|
|
208
|
-
this.status =
|
|
194
|
+
if (this.status === TaskStatusEnum.ATTEMPT_SUSPENDING) {
|
|
195
|
+
this.status = TaskStatusEnum.SUSPENDED;
|
|
209
196
|
}
|
|
210
197
|
}
|
|
211
198
|
}
|
|
212
199
|
async resume() {
|
|
213
|
-
if (this.status ===
|
|
214
|
-
this.status =
|
|
200
|
+
if (this.status === TaskStatusEnum.SUSPENDED) {
|
|
201
|
+
this.status = TaskStatusEnum.ATTEMPT_RESUMING;
|
|
215
202
|
await this._step;
|
|
216
|
-
if (this.status ===
|
|
217
|
-
this.status =
|
|
203
|
+
if (this.status === TaskStatusEnum.ATTEMPT_RESUMING) {
|
|
204
|
+
this.status = TaskStatusEnum.RUNNING;
|
|
218
205
|
this.queueStep();
|
|
219
206
|
}
|
|
220
207
|
}
|
|
221
208
|
}
|
|
222
209
|
async cancel() {
|
|
223
210
|
if (this.alive) {
|
|
224
|
-
this.status =
|
|
211
|
+
this.status = TaskStatusEnum.ATTEMPT_CANCELING;
|
|
225
212
|
await this._step;
|
|
226
|
-
if (this.status ===
|
|
227
|
-
this.status =
|
|
213
|
+
if (this.status === TaskStatusEnum.ATTEMPT_CANCELING) {
|
|
214
|
+
this.status = TaskStatusEnum.CANCELLED;
|
|
228
215
|
}
|
|
229
216
|
}
|
|
230
217
|
}
|
|
231
218
|
async finish() {
|
|
232
|
-
if (this.status ===
|
|
219
|
+
if (this.status === TaskStatusEnum.PENDING)
|
|
233
220
|
await this.start();
|
|
234
221
|
if (this.alive) {
|
|
235
|
-
this.status =
|
|
222
|
+
this.status = TaskStatusEnum.ATTEMPT_FINISHING;
|
|
236
223
|
await this._step;
|
|
237
224
|
const execution = this._execution;
|
|
238
225
|
if (execution) {
|
|
239
|
-
while (this.status ===
|
|
226
|
+
while (this.status === TaskStatusEnum.ATTEMPT_FINISHING) {
|
|
240
227
|
const step = execution.next();
|
|
241
228
|
if (step.done) {
|
|
242
|
-
this.status = this.hasError ?
|
|
229
|
+
this.status = this.hasError ? TaskStatusEnum.FAILED : TaskStatusEnum.FINISHED;
|
|
243
230
|
break;
|
|
244
231
|
}
|
|
245
232
|
await step.value.catch(error => {
|
|
246
233
|
this._addError('ResumableTaskError', error);
|
|
247
234
|
switch (this.strategy) {
|
|
248
|
-
case
|
|
235
|
+
case TaskStrategyEnum.ABORT_ON_ERROR:
|
|
249
236
|
if (!this.terminated)
|
|
250
|
-
this.status =
|
|
237
|
+
this.status = TaskStatusEnum.FAILED;
|
|
251
238
|
break;
|
|
252
|
-
case
|
|
239
|
+
case TaskStrategyEnum.CONTINUE_ON_ERROR:
|
|
253
240
|
break;
|
|
254
241
|
}
|
|
255
242
|
});
|
|
@@ -258,10 +245,10 @@ class ResumableTask extends TaskState {
|
|
|
258
245
|
}
|
|
259
246
|
}
|
|
260
247
|
launchStep() {
|
|
261
|
-
if (this.status ===
|
|
248
|
+
if (this.status === TaskStatusEnum.RUNNING && this._step === undefined && this._execution) {
|
|
262
249
|
const step = this._execution.next();
|
|
263
250
|
if (step.done) {
|
|
264
|
-
this.status = this.hasError ?
|
|
251
|
+
this.status = this.hasError ? TaskStatusEnum.FAILED : TaskStatusEnum.FINISHED;
|
|
265
252
|
return;
|
|
266
253
|
}
|
|
267
254
|
this._step = step.value
|
|
@@ -273,11 +260,11 @@ class ResumableTask extends TaskState {
|
|
|
273
260
|
this._step = undefined;
|
|
274
261
|
this._addError('ResumableTaskError', error);
|
|
275
262
|
switch (this.strategy) {
|
|
276
|
-
case
|
|
263
|
+
case TaskStrategyEnum.ABORT_ON_ERROR:
|
|
277
264
|
if (!this.terminated)
|
|
278
|
-
this.status =
|
|
265
|
+
this.status = TaskStatusEnum.FAILED;
|
|
279
266
|
break;
|
|
280
|
-
case
|
|
267
|
+
case TaskStrategyEnum.CONTINUE_ON_ERROR:
|
|
281
268
|
this.queueStep();
|
|
282
269
|
break;
|
|
283
270
|
}
|
|
@@ -289,4 +276,4 @@ class ResumableTask extends TaskState {
|
|
|
289
276
|
}
|
|
290
277
|
}
|
|
291
278
|
|
|
292
|
-
export { AtomicTask, ResumableTask, TaskState
|
|
279
|
+
export { AtomicTask, ResumableTask, TaskState };
|
package/lib/types/index.d.ts
CHANGED
|
@@ -1,102 +1,25 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
PENDING = 1,
|
|
5
|
-
RUNNING = 2,
|
|
6
|
-
SUSPENDED = 4,
|
|
7
|
-
CANCELLED = 8,
|
|
8
|
-
FAILED = 16,
|
|
9
|
-
FINISHED = 32,
|
|
10
|
-
ATTEMPT_SUSPENDING = 64,
|
|
11
|
-
ATTEMPT_RESUMING = 128,
|
|
12
|
-
ATTEMPT_CANCELING = 256,
|
|
13
|
-
ATTEMPT_FINISHING = 512
|
|
14
|
-
}
|
|
15
|
-
declare enum TaskStrategy {
|
|
16
|
-
ABORT_ON_ERROR = 1,
|
|
17
|
-
CONTINUE_ON_ERROR = 2
|
|
18
|
-
}
|
|
19
|
-
declare const active: number;
|
|
20
|
-
declare const alive: number;
|
|
21
|
-
declare const terminated: number;
|
|
22
|
-
|
|
23
|
-
interface ITaskError {
|
|
24
|
-
from: string;
|
|
25
|
-
details: ISoraError[];
|
|
26
|
-
}
|
|
27
|
-
interface ITaskMonitor {
|
|
28
|
-
onAddError(type: string, error: unknown, level: SoraErrorLevel | undefined): void;
|
|
29
|
-
onStatusChange(status: TaskStatus, prevStatus: TaskStatus): void;
|
|
30
|
-
}
|
|
31
|
-
type IUnMonitorTask = () => void;
|
|
32
|
-
interface ITaskState {
|
|
33
|
-
readonly status: TaskStatus;
|
|
34
|
-
readonly active: boolean;
|
|
35
|
-
readonly alive: boolean;
|
|
36
|
-
readonly terminated: boolean;
|
|
37
|
-
}
|
|
38
|
-
interface ITask extends ITaskState {
|
|
39
|
-
/**
|
|
40
|
-
* Task name.
|
|
41
|
-
*/
|
|
42
|
-
readonly name: string;
|
|
43
|
-
/**
|
|
44
|
-
* Task error.
|
|
45
|
-
*/
|
|
46
|
-
readonly error: ITaskError | undefined;
|
|
47
|
-
/**
|
|
48
|
-
* Indicate if the task has error.
|
|
49
|
-
*/
|
|
50
|
-
readonly hasError: boolean;
|
|
51
|
-
/**
|
|
52
|
-
* Start the task.
|
|
53
|
-
*/
|
|
54
|
-
start(): Promise<void>;
|
|
55
|
-
/**
|
|
56
|
-
* Pause the task.
|
|
57
|
-
*/
|
|
58
|
-
pause(): Promise<void>;
|
|
59
|
-
/**
|
|
60
|
-
* Resume the task.
|
|
61
|
-
*/
|
|
62
|
-
resume(): Promise<void>;
|
|
63
|
-
/**
|
|
64
|
-
* Cancel the task.
|
|
65
|
-
*/
|
|
66
|
-
cancel(): Promise<void>;
|
|
67
|
-
/**
|
|
68
|
-
* finish the task: run to completed no matter if the task started or not.
|
|
69
|
-
*/
|
|
70
|
-
finish(): Promise<void>;
|
|
71
|
-
/**
|
|
72
|
-
* Perform a clean up.
|
|
73
|
-
* Will thrown an error if the task is not terminated.
|
|
74
|
-
*/
|
|
75
|
-
cleanup(): void;
|
|
76
|
-
/**
|
|
77
|
-
* Register a monitor to subscribe the task changes.
|
|
78
|
-
* @param monitor
|
|
79
|
-
*/
|
|
80
|
-
monitor(monitor: Partial<ITaskMonitor>): IUnMonitorTask;
|
|
81
|
-
}
|
|
1
|
+
import { ITaskState, TaskStatusEnum, ITaskError, ITaskMonitor, IUnMonitorTask, ITask, TaskStrategyEnum } from '@guanghechen/task.types';
|
|
2
|
+
export * from '@guanghechen/task.types';
|
|
3
|
+
import { ISoraErrorCollector, ErrorLevelEnum } from '@guanghechen/error';
|
|
82
4
|
|
|
83
5
|
declare class TaskState implements ITaskState {
|
|
84
6
|
readonly name: string;
|
|
85
7
|
protected readonly _errorCollector: ISoraErrorCollector;
|
|
86
|
-
private readonly
|
|
8
|
+
private readonly _monitorAddError;
|
|
9
|
+
private readonly _monitorStatusChange;
|
|
87
10
|
private _status;
|
|
88
11
|
constructor(name: string);
|
|
89
|
-
get status():
|
|
12
|
+
get status(): TaskStatusEnum;
|
|
90
13
|
get active(): boolean;
|
|
91
14
|
get alive(): boolean;
|
|
92
15
|
get terminated(): boolean;
|
|
93
16
|
get hasError(): boolean;
|
|
94
17
|
get error(): ITaskError | undefined;
|
|
95
|
-
set status(status:
|
|
18
|
+
set status(status: TaskStatusEnum);
|
|
96
19
|
monitor(monitor: Partial<ITaskMonitor>): IUnMonitorTask;
|
|
97
|
-
check(nextStatus:
|
|
20
|
+
check(nextStatus: TaskStatusEnum): boolean;
|
|
98
21
|
cleanup(): void;
|
|
99
|
-
protected _addError(type: string, error: unknown, level?:
|
|
22
|
+
protected _addError(type: string, error: unknown, level?: ErrorLevelEnum): void;
|
|
100
23
|
}
|
|
101
24
|
|
|
102
25
|
declare abstract class AtomicTask extends TaskState implements ITask {
|
|
@@ -112,11 +35,11 @@ declare abstract class AtomicTask extends TaskState implements ITask {
|
|
|
112
35
|
|
|
113
36
|
interface IResumableTaskProps {
|
|
114
37
|
name: string;
|
|
115
|
-
strategy:
|
|
38
|
+
strategy: TaskStrategyEnum;
|
|
116
39
|
pollInterval: number;
|
|
117
40
|
}
|
|
118
41
|
declare abstract class ResumableTask extends TaskState implements ITask {
|
|
119
|
-
readonly strategy:
|
|
42
|
+
readonly strategy: TaskStrategyEnum;
|
|
120
43
|
private readonly _pollInterval;
|
|
121
44
|
private _execution;
|
|
122
45
|
private _step;
|
|
@@ -131,4 +54,4 @@ declare abstract class ResumableTask extends TaskState implements ITask {
|
|
|
131
54
|
private queueStep;
|
|
132
55
|
}
|
|
133
56
|
|
|
134
|
-
export { AtomicTask,
|
|
57
|
+
export { AtomicTask, ResumableTask, TaskState };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@guanghechen/task",
|
|
3
|
-
"version": "1.0.0-alpha.
|
|
3
|
+
"version": "1.0.0-alpha.20",
|
|
4
4
|
"description": "Atomic and resumable tasks",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "guanghechen",
|
|
@@ -8,22 +8,26 @@
|
|
|
8
8
|
},
|
|
9
9
|
"repository": {
|
|
10
10
|
"type": "git",
|
|
11
|
-
"url": "https://github.com/guanghechen/sora/tree/@guanghechen/task@1.0.0-alpha.
|
|
11
|
+
"url": "https://github.com/guanghechen/sora/tree/@guanghechen/task@1.0.0-alpha.19",
|
|
12
12
|
"directory": "packages/task"
|
|
13
13
|
},
|
|
14
|
-
"homepage": "https://github.com/guanghechen/sora/tree/@guanghechen/task@1.0.0-alpha.
|
|
14
|
+
"homepage": "https://github.com/guanghechen/sora/tree/@guanghechen/task@1.0.0-alpha.19/packages/task#readme",
|
|
15
15
|
"type": "module",
|
|
16
|
-
"main": "./lib/cjs/index.cjs",
|
|
17
|
-
"module": "./lib/esm/index.mjs",
|
|
18
16
|
"exports": {
|
|
19
|
-
"
|
|
20
|
-
|
|
17
|
+
".": {
|
|
18
|
+
"source": "./src/index.ts",
|
|
19
|
+
"import": "./lib/esm/index.mjs",
|
|
20
|
+
"require": "./lib/cjs/index.cjs",
|
|
21
|
+
"types": "./lib/types/index.d.ts"
|
|
22
|
+
}
|
|
21
23
|
},
|
|
22
|
-
"
|
|
23
|
-
"
|
|
24
|
+
"source": "./src/index.ts",
|
|
25
|
+
"main": "./lib/cjs/index.cjs",
|
|
26
|
+
"module": "./lib/esm/index.mjs",
|
|
27
|
+
"types": "./lib/types/index.d.ts",
|
|
24
28
|
"license": "MIT",
|
|
25
29
|
"engines": {
|
|
26
|
-
"node": ">=
|
|
30
|
+
"node": ">= 18.0.0"
|
|
27
31
|
},
|
|
28
32
|
"files": [
|
|
29
33
|
"lib/",
|
|
@@ -34,20 +38,17 @@
|
|
|
34
38
|
"README.md"
|
|
35
39
|
],
|
|
36
40
|
"scripts": {
|
|
37
|
-
"build": "rimraf lib/ && cross-env NODE_ENV=production rollup -c ../../rollup.config.mjs",
|
|
41
|
+
"build": "../../node_modules/.bin/rimraf lib/ && ../../node_modules/.bin/cross-env NODE_ENV=production ../../node_modules/.bin/rollup -c ../../rollup.config.mjs",
|
|
38
42
|
"prepublishOnly": "yarn build",
|
|
39
43
|
"test": "node --experimental-vm-modules ../../node_modules/.bin/jest --config ../../jest.config.mjs --rootDir ."
|
|
40
44
|
},
|
|
41
45
|
"dependencies": {
|
|
42
|
-
"@guanghechen/error": "^1.0.0-alpha.
|
|
43
|
-
"@guanghechen/monitor": "^1.0.0-alpha.
|
|
46
|
+
"@guanghechen/error": "^1.0.0-alpha.16",
|
|
47
|
+
"@guanghechen/monitor": "^1.0.0-alpha.20",
|
|
48
|
+
"@guanghechen/task.types": "^1.0.0-alpha.7"
|
|
44
49
|
},
|
|
45
50
|
"devDependencies": {
|
|
46
|
-
"@guanghechen/
|
|
47
|
-
"cross-env": "^7.0.3",
|
|
48
|
-
"jest": "^29.6.4",
|
|
49
|
-
"rimraf": "^5.0.1",
|
|
50
|
-
"rollup": "^3.28.1"
|
|
51
|
+
"@guanghechen/internal": "^1.0.0-alpha.0"
|
|
51
52
|
},
|
|
52
|
-
"gitHead": "
|
|
53
|
+
"gitHead": "98df8d39d3f8b67758e298e3c3a0b46bfc76bec1"
|
|
53
54
|
}
|