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