@lage-run/scheduler 0.5.9 → 0.5.11
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.json +61 -1
- package/CHANGELOG.md +23 -2
- package/lib/SimpleScheduler.d.ts +0 -1
- package/lib/SimpleScheduler.js +95 -115
- package/lib/WrappedTarget.js +117 -80
- package/lib/bufferTransform.d.ts +0 -1
- package/lib/bufferTransform.js +13 -10
- package/lib/categorizeTargetRuns.js +10 -7
- package/lib/formatBytes.js +7 -4
- package/lib/getLageOutputCacheLocation.js +15 -10
- package/lib/index.js +19 -11
- package/lib/runners/NoOpRunner.js +11 -7
- package/lib/runners/NpmScriptRunner.js +70 -69
- package/lib/runners/TargetRunnerPicker.js +28 -46
- package/lib/runners/WorkerRunner.js +24 -70
- package/lib/workers/targetWorker.js +12 -11
- package/package.json +4 -4
- package/lib/SimpleScheduler.js.map +0 -1
- package/lib/WrappedTarget.js.map +0 -1
- package/lib/bufferTransform.js.map +0 -1
- package/lib/categorizeTargetRuns.js.map +0 -1
- package/lib/formatBytes.js.map +0 -1
- package/lib/getLageOutputCacheLocation.js.map +0 -1
- package/lib/index.js.map +0 -1
- package/lib/runners/NoOpRunner.js.map +0 -1
- package/lib/runners/NpmScriptRunner.js.map +0 -1
- package/lib/runners/TargetRunnerPicker.js.map +0 -1
- package/lib/runners/WorkerRunner.js.map +0 -1
- package/lib/workers/targetWorker.js.map +0 -1
package/CHANGELOG.json
CHANGED
|
@@ -2,7 +2,67 @@
|
|
|
2
2
|
"name": "@lage-run/scheduler",
|
|
3
3
|
"entries": [
|
|
4
4
|
{
|
|
5
|
-
"date": "
|
|
5
|
+
"date": "Thu, 10 Nov 2022 20:20:28 GMT",
|
|
6
|
+
"tag": "@lage-run/scheduler_v0.5.11",
|
|
7
|
+
"version": "0.5.11",
|
|
8
|
+
"comments": {
|
|
9
|
+
"patch": [
|
|
10
|
+
{
|
|
11
|
+
"author": "kchau@microsoft.com",
|
|
12
|
+
"package": "@lage-run/scheduler",
|
|
13
|
+
"commit": "b1a42cb963a5fc680e4c59b1e705acbc964f0804",
|
|
14
|
+
"comment": "update api from targetgraphbuilder"
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
"author": "ken@gizzar.com",
|
|
18
|
+
"package": "@lage-run/scheduler",
|
|
19
|
+
"commit": "b1a42cb963a5fc680e4c59b1e705acbc964f0804",
|
|
20
|
+
"comment": "making swc the transpiler of choice"
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
"author": "kchau@microsoft.com",
|
|
24
|
+
"package": "@lage-run/scheduler",
|
|
25
|
+
"commit": "b1a42cb963a5fc680e4c59b1e705acbc964f0804",
|
|
26
|
+
"comment": "fixing real imports with rollup as well as getting rid of getPackageAndTask implementation details"
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
"author": "beachball",
|
|
30
|
+
"package": "@lage-run/scheduler",
|
|
31
|
+
"comment": "Bump @lage-run/target-graph to v0.6.0",
|
|
32
|
+
"commit": "b1a42cb963a5fc680e4c59b1e705acbc964f0804"
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
"author": "beachball",
|
|
36
|
+
"package": "@lage-run/scheduler",
|
|
37
|
+
"comment": "Bump @lage-run/cache to v0.2.1",
|
|
38
|
+
"commit": "b1a42cb963a5fc680e4c59b1e705acbc964f0804"
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
"author": "beachball",
|
|
42
|
+
"package": "@lage-run/scheduler",
|
|
43
|
+
"comment": "Bump @lage-run/scheduler-types to v0.2.7",
|
|
44
|
+
"commit": "b1a42cb963a5fc680e4c59b1e705acbc964f0804"
|
|
45
|
+
}
|
|
46
|
+
]
|
|
47
|
+
}
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
"date": "Fri, 04 Nov 2022 21:14:01 GMT",
|
|
51
|
+
"tag": "@lage-run/scheduler_v0.5.10",
|
|
52
|
+
"version": "0.5.10",
|
|
53
|
+
"comments": {
|
|
54
|
+
"patch": [
|
|
55
|
+
{
|
|
56
|
+
"author": "kchau@microsoft.com",
|
|
57
|
+
"package": "@lage-run/scheduler",
|
|
58
|
+
"commit": "6dba6df4c699c92ca201e91301dfa4aac6344902",
|
|
59
|
+
"comment": "fixed the tsconfig.lage2.json to output node16 moduleRes"
|
|
60
|
+
}
|
|
61
|
+
]
|
|
62
|
+
}
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
"date": "Wed, 02 Nov 2022 20:45:00 GMT",
|
|
6
66
|
"tag": "@lage-run/scheduler_v0.5.9",
|
|
7
67
|
"version": "0.5.9",
|
|
8
68
|
"comments": {
|
package/CHANGELOG.md
CHANGED
|
@@ -1,12 +1,33 @@
|
|
|
1
1
|
# Change Log - @lage-run/scheduler
|
|
2
2
|
|
|
3
|
-
This log was last generated on
|
|
3
|
+
This log was last generated on Thu, 10 Nov 2022 20:20:28 GMT and should not be manually modified.
|
|
4
4
|
|
|
5
5
|
<!-- Start content -->
|
|
6
6
|
|
|
7
|
+
## 0.5.11
|
|
8
|
+
|
|
9
|
+
Thu, 10 Nov 2022 20:20:28 GMT
|
|
10
|
+
|
|
11
|
+
### Patches
|
|
12
|
+
|
|
13
|
+
- update api from targetgraphbuilder (kchau@microsoft.com)
|
|
14
|
+
- making swc the transpiler of choice (ken@gizzar.com)
|
|
15
|
+
- fixing real imports with rollup as well as getting rid of getPackageAndTask implementation details (kchau@microsoft.com)
|
|
16
|
+
- Bump @lage-run/target-graph to v0.6.0
|
|
17
|
+
- Bump @lage-run/cache to v0.2.1
|
|
18
|
+
- Bump @lage-run/scheduler-types to v0.2.7
|
|
19
|
+
|
|
20
|
+
## 0.5.10
|
|
21
|
+
|
|
22
|
+
Fri, 04 Nov 2022 21:14:01 GMT
|
|
23
|
+
|
|
24
|
+
### Patches
|
|
25
|
+
|
|
26
|
+
- fixed the tsconfig.lage2.json to output node16 moduleRes (kchau@microsoft.com)
|
|
27
|
+
|
|
7
28
|
## 0.5.9
|
|
8
29
|
|
|
9
|
-
Wed, 02 Nov 2022 20:
|
|
30
|
+
Wed, 02 Nov 2022 20:45:00 GMT
|
|
10
31
|
|
|
11
32
|
### Patches
|
|
12
33
|
|
package/lib/SimpleScheduler.d.ts
CHANGED
|
@@ -38,7 +38,6 @@ export declare class SimpleScheduler implements TargetScheduler {
|
|
|
38
38
|
targetsByPriority: Target[];
|
|
39
39
|
abortController: AbortController;
|
|
40
40
|
abortSignal: AbortSignal;
|
|
41
|
-
dependencies: [string, string][];
|
|
42
41
|
pool: Pool;
|
|
43
42
|
runPromise: Promise<any>;
|
|
44
43
|
constructor(options: SimpleSchedulerOptions);
|
package/lib/SimpleScheduler.js
CHANGED
|
@@ -1,69 +1,36 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
* 2. Takes a TargetRunner, a CacheProvider, a TargetHasher and a Logger as constructor parameters (dependency injection).
|
|
15
|
-
* 3. Directly constructs new WrappedTarget, which provides the call to caching and logging.
|
|
16
|
-
*
|
|
17
|
-
* Roadmap / future enhancements:
|
|
18
|
-
* 1. Allow for multiple kinds of runner (currently only ONE is supported, and it is applied to all targets)
|
|
19
|
-
*
|
|
20
|
-
*/
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
Object.defineProperty(exports, "SimpleScheduler", {
|
|
6
|
+
enumerable: true,
|
|
7
|
+
get: ()=>SimpleScheduler
|
|
8
|
+
});
|
|
9
|
+
const _categorizeTargetRunsJs = require("./categorizeTargetRuns.js");
|
|
10
|
+
const _targetGraph = require("@lage-run/target-graph");
|
|
11
|
+
const _wrappedTargetJs = require("./WrappedTarget.js");
|
|
12
|
+
const _workerThreadsPool = require("@lage-run/worker-threads-pool");
|
|
13
|
+
const _formatBytesJs = require("./formatBytes.js");
|
|
21
14
|
class SimpleScheduler {
|
|
22
|
-
constructor(options) {
|
|
23
|
-
var _a;
|
|
24
|
-
this.options = options;
|
|
25
|
-
this.targetRuns = new Map();
|
|
26
|
-
this.targetsByPriority = [];
|
|
27
|
-
this.abortController = new AbortController();
|
|
28
|
-
this.abortSignal = this.abortController.signal;
|
|
29
|
-
this.dependencies = [];
|
|
30
|
-
this.runPromise = Promise.resolve();
|
|
31
|
-
this.pool =
|
|
32
|
-
(_a = options.pool) !== null && _a !== void 0 ? _a : new worker_threads_pool_1.AggregatedPool({
|
|
33
|
-
logger: options.logger,
|
|
34
|
-
maxWorkersByGroup: options.maxWorkersPerTask,
|
|
35
|
-
groupBy: ({ target }) => target.task,
|
|
36
|
-
maxWorkers: options.concurrency,
|
|
37
|
-
script: require.resolve("./workers/targetWorker"),
|
|
38
|
-
workerOptions: {
|
|
39
|
-
stdout: true,
|
|
40
|
-
stderr: true,
|
|
41
|
-
workerData: {
|
|
42
|
-
runners: options.runners,
|
|
43
|
-
},
|
|
44
|
-
},
|
|
45
|
-
workerIdleMemoryLimit: options.workerIdleMemoryLimit, // in bytes
|
|
46
|
-
});
|
|
47
|
-
}
|
|
48
15
|
/**
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
async run(root, targetGraph) {
|
|
16
|
+
* The job of the run method is to:
|
|
17
|
+
* 1. Convert the target graph into a promise graph.
|
|
18
|
+
* 2. Create a promise graph of all targets
|
|
19
|
+
* 3. Pass the continueOnError option to the promise graph runner.
|
|
20
|
+
*
|
|
21
|
+
* @param root
|
|
22
|
+
* @param targetGraph
|
|
23
|
+
* @returns
|
|
24
|
+
*/ async run(root, targetGraph) {
|
|
59
25
|
const startTime = process.hrtime();
|
|
60
|
-
const { continueOnError, logger, cacheProvider, shouldCache, shouldResetCache, hasher
|
|
61
|
-
const { pool, abortController
|
|
62
|
-
const {
|
|
63
|
-
this.
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
26
|
+
const { continueOnError , logger , cacheProvider , shouldCache , shouldResetCache , hasher } = this.options;
|
|
27
|
+
const { pool , abortController } = this;
|
|
28
|
+
const { targets } = targetGraph;
|
|
29
|
+
this.targetsByPriority = (0, _targetGraph.sortTargetsByPriority)([
|
|
30
|
+
...targets.values()
|
|
31
|
+
]);
|
|
32
|
+
for (const target of targets.values()){
|
|
33
|
+
const targetRun = new _wrappedTargetJs.WrappedTarget({
|
|
67
34
|
target,
|
|
68
35
|
root,
|
|
69
36
|
logger,
|
|
@@ -73,31 +40,30 @@ class SimpleScheduler {
|
|
|
73
40
|
shouldResetCache,
|
|
74
41
|
continueOnError,
|
|
75
42
|
abortController,
|
|
76
|
-
pool
|
|
43
|
+
pool
|
|
77
44
|
});
|
|
78
|
-
if (target.id === (0,
|
|
45
|
+
if (target.id === (0, _targetGraph.getStartTargetId)()) {
|
|
79
46
|
targetRun.status = "success";
|
|
80
47
|
}
|
|
81
48
|
this.targetRuns.set(target.id, targetRun);
|
|
82
49
|
}
|
|
83
50
|
let results = "failed";
|
|
84
51
|
let error;
|
|
85
|
-
let duration = [
|
|
52
|
+
let duration = [
|
|
53
|
+
0,
|
|
54
|
+
0
|
|
55
|
+
];
|
|
86
56
|
let targetRunByStatus;
|
|
87
57
|
try {
|
|
88
58
|
await this.scheduleReadyTargets();
|
|
89
|
-
}
|
|
90
|
-
catch (e) {
|
|
59
|
+
} catch (e) {
|
|
91
60
|
error = e instanceof Error ? e.message : String(e);
|
|
92
|
-
}
|
|
93
|
-
finally {
|
|
61
|
+
} finally{
|
|
94
62
|
duration = process.hrtime(startTime);
|
|
95
|
-
targetRunByStatus = (0,
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
targetRunByStatus.running.length ===
|
|
100
|
-
0) {
|
|
63
|
+
targetRunByStatus = (0, _categorizeTargetRunsJs.categorizeTargetRuns)([
|
|
64
|
+
...this.targetRuns.values()
|
|
65
|
+
]);
|
|
66
|
+
if (targetRunByStatus.failed.length + targetRunByStatus.aborted.length + targetRunByStatus.pending.length + targetRunByStatus.running.length === 0) {
|
|
101
67
|
results = "success";
|
|
102
68
|
}
|
|
103
69
|
}
|
|
@@ -110,65 +76,64 @@ class SimpleScheduler {
|
|
|
110
76
|
results,
|
|
111
77
|
error,
|
|
112
78
|
workerRestarts: poolStats.workerRestarts,
|
|
113
|
-
maxWorkerMemoryUsage: poolStats.maxWorkerMemoryUsage
|
|
79
|
+
maxWorkerMemoryUsage: poolStats.maxWorkerMemoryUsage
|
|
114
80
|
};
|
|
115
81
|
}
|
|
116
82
|
/**
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
async onTargetChange(targetId) {
|
|
83
|
+
* Used by consumers of the scheduler to notify that the inputs to the target has changed
|
|
84
|
+
* @param targetId
|
|
85
|
+
*/ async onTargetChange(targetId) {
|
|
121
86
|
this.abortController.abort();
|
|
122
87
|
await this.runPromise;
|
|
123
|
-
const queue = [
|
|
124
|
-
|
|
88
|
+
const queue = [
|
|
89
|
+
targetId
|
|
90
|
+
];
|
|
91
|
+
while(queue.length > 0){
|
|
125
92
|
const current = queue.shift();
|
|
126
93
|
const targetRun = this.targetRuns.get(current);
|
|
127
94
|
if (targetRun.status !== "pending") {
|
|
128
95
|
targetRun.status = "pending";
|
|
129
96
|
const dependents = targetRun.target.dependents;
|
|
130
|
-
for (const dependent of dependents)
|
|
97
|
+
for (const dependent of dependents){
|
|
131
98
|
queue.push(dependent);
|
|
132
99
|
}
|
|
133
100
|
}
|
|
134
101
|
}
|
|
135
102
|
this.abortController = new AbortController();
|
|
136
103
|
this.abortSignal = this.abortController.signal;
|
|
137
|
-
for (const
|
|
138
|
-
|
|
104
|
+
for (const targetRun1 of this.targetRuns.values()){
|
|
105
|
+
targetRun1.abortController = this.abortController;
|
|
139
106
|
}
|
|
140
107
|
this.runPromise = this.scheduleReadyTargets();
|
|
141
108
|
}
|
|
142
109
|
getReadyTargets() {
|
|
143
|
-
var _a;
|
|
144
110
|
const readyTargets = [];
|
|
145
|
-
const runningTargets = this.targetsByPriority.filter((target)
|
|
111
|
+
const runningTargets = this.targetsByPriority.filter((target)=>this.targetRuns.get(target.id).status === "running");
|
|
146
112
|
const runningTargetsCountByTask = {};
|
|
147
|
-
for (const target of runningTargets)
|
|
148
|
-
runningTargetsCountByTask[target.task] =
|
|
149
|
-
typeof runningTargetsCountByTask[target.task] !== "number" ? 1 : runningTargetsCountByTask[target.task]++;
|
|
113
|
+
for (const target of runningTargets){
|
|
114
|
+
runningTargetsCountByTask[target.task] = typeof runningTargetsCountByTask[target.task] !== "number" ? 1 : runningTargetsCountByTask[target.task]++;
|
|
150
115
|
}
|
|
151
|
-
for (const
|
|
152
|
-
if (
|
|
116
|
+
for (const target1 of this.targetsByPriority){
|
|
117
|
+
if (target1.id === (0, _targetGraph.getStartTargetId)()) {
|
|
153
118
|
continue;
|
|
154
119
|
}
|
|
155
|
-
const targetRun = this.targetRuns.get(
|
|
120
|
+
const targetRun = this.targetRuns.get(target1.id);
|
|
156
121
|
const targetDeps = targetRun.target.dependencies;
|
|
157
122
|
// filter all dependencies for those that are "ready"
|
|
158
|
-
const ready = targetDeps.every((dep)
|
|
123
|
+
const ready = targetDeps.every((dep)=>{
|
|
159
124
|
const fromTarget = this.targetRuns.get(dep);
|
|
160
|
-
return fromTarget.status === "success" || fromTarget.status === "skipped" || dep === (0,
|
|
125
|
+
return fromTarget.status === "success" || fromTarget.status === "skipped" || dep === (0, _targetGraph.getStartTargetId)();
|
|
161
126
|
});
|
|
162
127
|
if (ready && targetRun.status === "pending") {
|
|
163
128
|
readyTargets.push(targetRun);
|
|
164
|
-
runningTargetsCountByTask[
|
|
129
|
+
runningTargetsCountByTask[target1.task] = (runningTargetsCountByTask[target1.task] ?? 0) + 1;
|
|
165
130
|
}
|
|
166
131
|
}
|
|
167
132
|
return readyTargets;
|
|
168
133
|
}
|
|
169
134
|
isAllDone() {
|
|
170
|
-
for (const t of this.targetRuns.values())
|
|
171
|
-
if (t.status !== "skipped" && t.status !== "success" && t.target.id !== (0,
|
|
135
|
+
for (const t of this.targetRuns.values()){
|
|
136
|
+
if (t.status !== "skipped" && t.status !== "success" && t.target.id !== (0, _targetGraph.getStartTargetId)()) {
|
|
172
137
|
return false;
|
|
173
138
|
}
|
|
174
139
|
}
|
|
@@ -178,22 +143,17 @@ class SimpleScheduler {
|
|
|
178
143
|
if (this.isAllDone() || this.abortSignal.aborted) {
|
|
179
144
|
return Promise.resolve();
|
|
180
145
|
}
|
|
181
|
-
this.options.logger.silly(`Max Worker Memory Usage: ${(0,
|
|
146
|
+
this.options.logger.silly(`Max Worker Memory Usage: ${(0, _formatBytesJs.formatBytes)(this.pool.stats().maxWorkerMemoryUsage)}`);
|
|
182
147
|
const promises = [];
|
|
183
|
-
for (const nextTarget of this.getReadyTargets())
|
|
184
|
-
promises.push(nextTarget
|
|
185
|
-
.run()
|
|
186
|
-
.then(() => {
|
|
148
|
+
for (const nextTarget of this.getReadyTargets()){
|
|
149
|
+
promises.push(nextTarget.run().then(()=>{
|
|
187
150
|
return this.scheduleReadyTargets();
|
|
188
|
-
})
|
|
189
|
-
.catch((e) => {
|
|
190
|
-
var _a;
|
|
151
|
+
}).catch((e)=>{
|
|
191
152
|
// if a continue option is set, this merely records what errors have been encountered
|
|
192
153
|
// it'll continue down the execution until all the tasks that still works
|
|
193
|
-
if (
|
|
154
|
+
if (this.options?.continueOnError) {
|
|
194
155
|
return this.scheduleReadyTargets();
|
|
195
|
-
}
|
|
196
|
-
else {
|
|
156
|
+
} else {
|
|
197
157
|
// immediately reject, if not using "continue" option
|
|
198
158
|
throw e;
|
|
199
159
|
}
|
|
@@ -203,16 +163,36 @@ class SimpleScheduler {
|
|
|
203
163
|
return this.runPromise;
|
|
204
164
|
}
|
|
205
165
|
async cleanup() {
|
|
206
|
-
this.options.logger.silly(`Max Worker Memory Usage: ${(0,
|
|
166
|
+
this.options.logger.silly(`Max Worker Memory Usage: ${(0, _formatBytesJs.formatBytes)(this.pool.stats().maxWorkerMemoryUsage)}`);
|
|
207
167
|
await this.pool.close();
|
|
208
168
|
}
|
|
209
169
|
/**
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
abort() {
|
|
170
|
+
* Abort the scheduler using the abort controller.
|
|
171
|
+
*/ abort() {
|
|
213
172
|
this.abortController.abort();
|
|
214
173
|
}
|
|
174
|
+
constructor(options){
|
|
175
|
+
this.options = options;
|
|
176
|
+
this.targetRuns = new Map();
|
|
177
|
+
this.targetsByPriority = [];
|
|
178
|
+
this.abortController = new AbortController();
|
|
179
|
+
this.abortSignal = this.abortController.signal;
|
|
180
|
+
this.runPromise = Promise.resolve();
|
|
181
|
+
this.pool = options.pool ?? new _workerThreadsPool.AggregatedPool({
|
|
182
|
+
logger: options.logger,
|
|
183
|
+
maxWorkersByGroup: options.maxWorkersPerTask,
|
|
184
|
+
groupBy: ({ target })=>target.task,
|
|
185
|
+
maxWorkers: options.concurrency,
|
|
186
|
+
script: require.resolve("./workers/targetWorker"),
|
|
187
|
+
workerOptions: {
|
|
188
|
+
stdout: true,
|
|
189
|
+
stderr: true,
|
|
190
|
+
workerData: {
|
|
191
|
+
runners: options.runners
|
|
192
|
+
}
|
|
193
|
+
},
|
|
194
|
+
workerIdleMemoryLimit: options.workerIdleMemoryLimit
|
|
195
|
+
});
|
|
196
|
+
}
|
|
215
197
|
}
|
|
216
|
-
exports.SimpleScheduler = SimpleScheduler;
|
|
217
198
|
encodeURI;
|
|
218
|
-
//# sourceMappingURL=SimpleScheduler.js.map
|