@lage-run/scheduler 1.5.15 → 1.5.16
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 +24 -1
- package/CHANGELOG.md +10 -2
- package/lib/SimpleScheduler.d.ts +3 -5
- package/lib/SimpleScheduler.js +0 -1
- package/lib/SimpleScheduler.js.map +1 -1
- package/lib/WrappedTarget.d.ts +0 -2
- package/lib/WrappedTarget.js.map +1 -1
- package/lib/bufferTransform.js.map +1 -1
- package/lib/cache/createCacheProvider.js.map +1 -1
- package/lib/cache/isRunningFromCI.js.map +1 -1
- package/lib/formatBytes.js.map +1 -1
- package/lib/getLageOutputCacheLocation.js.map +1 -1
- package/package.json +9 -9
package/CHANGELOG.json
CHANGED
|
@@ -2,7 +2,30 @@
|
|
|
2
2
|
"name": "@lage-run/scheduler",
|
|
3
3
|
"entries": [
|
|
4
4
|
{
|
|
5
|
-
"date": "
|
|
5
|
+
"date": "Sat, 24 Jan 2026 09:00:58 GMT",
|
|
6
|
+
"version": "1.5.16",
|
|
7
|
+
"tag": "@lage-run/scheduler_v1.5.16",
|
|
8
|
+
"comments": {
|
|
9
|
+
"patch": [
|
|
10
|
+
{
|
|
11
|
+
"author": "elcraig@microsoft.com",
|
|
12
|
+
"package": "@lage-run/scheduler",
|
|
13
|
+
"commit": "092607a7d55561a9342ab3265ccab0142dd59b9b",
|
|
14
|
+
"comment": "Add explicit module boundary types and update typescript version"
|
|
15
|
+
}
|
|
16
|
+
],
|
|
17
|
+
"none": [
|
|
18
|
+
{
|
|
19
|
+
"author": "elcraig@microsoft.com",
|
|
20
|
+
"package": "@lage-run/scheduler",
|
|
21
|
+
"commit": "092607a7d55561a9342ab3265ccab0142dd59b9b",
|
|
22
|
+
"comment": "Update internal types and docs"
|
|
23
|
+
}
|
|
24
|
+
]
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
"date": "Thu, 15 Jan 2026 23:24:00 GMT",
|
|
6
29
|
"version": "1.5.15",
|
|
7
30
|
"tag": "@lage-run/scheduler_v1.5.15",
|
|
8
31
|
"comments": {
|
package/CHANGELOG.md
CHANGED
|
@@ -1,12 +1,20 @@
|
|
|
1
1
|
# Change Log - @lage-run/scheduler
|
|
2
2
|
|
|
3
|
-
<!-- This log was last generated on
|
|
3
|
+
<!-- This log was last generated on Sat, 24 Jan 2026 09:00:58 GMT and should not be manually modified. -->
|
|
4
4
|
|
|
5
5
|
<!-- Start content -->
|
|
6
6
|
|
|
7
|
+
## 1.5.16
|
|
8
|
+
|
|
9
|
+
Sat, 24 Jan 2026 09:00:58 GMT
|
|
10
|
+
|
|
11
|
+
### Patches
|
|
12
|
+
|
|
13
|
+
- Add explicit module boundary types and update typescript version (elcraig@microsoft.com)
|
|
14
|
+
|
|
7
15
|
## 1.5.15
|
|
8
16
|
|
|
9
|
-
Thu, 15 Jan 2026 23:
|
|
17
|
+
Thu, 15 Jan 2026 23:24:00 GMT
|
|
10
18
|
|
|
11
19
|
### Patches
|
|
12
20
|
|
package/lib/SimpleScheduler.d.ts
CHANGED
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
/// <reference types="node" />
|
|
3
|
-
/// <reference types="global" />
|
|
1
|
+
import { type Target } from "@lage-run/target-graph";
|
|
4
2
|
import { WrappedTarget } from "./WrappedTarget.js";
|
|
5
3
|
import { TargetRunnerPicker } from "@lage-run/runners";
|
|
6
4
|
import type { WorkerResult } from "./WrappedTarget.js";
|
|
@@ -54,7 +52,7 @@ export declare class SimpleScheduler implements TargetScheduler<WorkerResult> {
|
|
|
54
52
|
runnerPicker: TargetRunnerPicker;
|
|
55
53
|
runPromise: Promise<any>;
|
|
56
54
|
constructor(options: SimpleSchedulerOptions);
|
|
57
|
-
getTargetsByPriority():
|
|
55
|
+
getTargetsByPriority(): Target[];
|
|
58
56
|
/**
|
|
59
57
|
* The job of the run method is to:
|
|
60
58
|
* 1. Convert the target graph into a promise graph.
|
|
@@ -70,7 +68,7 @@ export declare class SimpleScheduler implements TargetScheduler<WorkerResult> {
|
|
|
70
68
|
* Used by consumers of the scheduler to notify that the inputs to the target has changed
|
|
71
69
|
* @param targetId
|
|
72
70
|
*/
|
|
73
|
-
markTargetAndDependentsPending(targetId:
|
|
71
|
+
markTargetAndDependentsPending(targetId: string): void;
|
|
74
72
|
getReadyTargets(): WrappedTarget[];
|
|
75
73
|
isAllDone(): boolean;
|
|
76
74
|
scheduleReadyTargets(): Promise<void>;
|
package/lib/SimpleScheduler.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/SimpleScheduler.ts"],"sourcesContent":["import { AggregatedPool } from \"@lage-run/worker-threads-pool\";\nimport { formatBytes } from \"./formatBytes.js\";\nimport { categorizeTargetRuns } from \"./categorizeTargetRuns.js\";\nimport { getStartTargetId, sortTargetsByPriority } from \"@lage-run/target-graph\";\nimport { WrappedTarget } from \"./WrappedTarget.js\";\nimport { TargetRunnerPicker } from \"@lage-run/runners\";\n\nimport type { WorkerResult } from \"./WrappedTarget.js\";\nimport type { Logger } from \"@lage-run/logger\";\nimport type { TargetGraph } from \"@lage-run/target-graph\";\nimport type { TargetScheduler, SchedulerRunResults, SchedulerRunSummary, TargetRunSummary } from \"@lage-run/scheduler-types\";\nimport type { Pool } from \"@lage-run/worker-threads-pool\";\nimport type { TargetRunnerPickerOptions } from \"@lage-run/runners\";\nimport type { TargetHasher } from \"@lage-run/hasher\";\nimport type { CacheOptions } from \"@lage-run/cache\";\nimport type { MessagePort } from \"worker_threads\";\n\nexport interface SimpleSchedulerOptions {\n logger: Logger;\n concurrency: number;\n continueOnError: boolean;\n shouldCache: boolean;\n shouldResetCache: boolean;\n workerData: {\n runners: TargetRunnerPickerOptions;\n root: string;\n taskArgs: string[];\n skipLocalCache?: boolean;\n cacheOptions?: CacheOptions;\n };\n maxWorkersPerTask: Map<string, number>;\n pool?: Pool; // for testing\n workerIdleMemoryLimit: number; // in bytes\n hasher: TargetHasher;\n onMessage?: (message: any, postMessage: MessagePort[\"postMessage\"]) => void;\n}\n\n/**\n * Simple scheduler that runs all targets in a promise graph using p-graph library.\n *\n * Some characteristics:\n * 1. Can cache results of target runs via the cache provider.\n * 2. Takes a TargetRunner, a CacheProvider, a TargetHasher and a Logger as constructor parameters (dependency injection).\n * 3. Directly constructs new WrappedTarget, which provides the call to caching and logging.\n *\n * Roadmap / future enhancements:\n * 1. Allow for multiple kinds of runner (currently only ONE is supported, and it is applied to all targets)\n *\n */\nexport class SimpleScheduler implements TargetScheduler<WorkerResult> {\n targetRuns: Map<string, WrappedTarget> = new Map();\n rerunTargets: Set<string> = new Set();\n abortController: AbortController = new AbortController();\n abortSignal: AbortSignal = this.abortController.signal;\n pool: Pool;\n runnerPicker: TargetRunnerPicker;\n\n runPromise = Promise.resolve() as Promise<any>;\n\n constructor(private options: SimpleSchedulerOptions) {\n this.pool =\n options.pool ??\n new AggregatedPool({\n logger: options.logger,\n maxWorkersByGroup: options.maxWorkersPerTask,\n groupBy: ({ target }) => target.task,\n maxWorkers: options.concurrency,\n script: require.resolve(\"./workers/targetWorker\"),\n workerOptions: {\n stdout: true,\n stderr: true,\n workerData: { ...options.workerData, shouldCache: options.shouldCache, shouldResetCache: options.shouldResetCache },\n },\n workerIdleMemoryLimit: options.workerIdleMemoryLimit, // in bytes\n });\n\n this.runnerPicker = new TargetRunnerPicker(options.workerData.runners);\n }\n\n getTargetsByPriority() {\n return sortTargetsByPriority([...this.targetRuns.values()].map((run) => run.target));\n }\n\n /**\n * The job of the run method is to:\n * 1. Convert the target graph into a promise graph.\n * 2. Create a promise graph of all targets\n * 3. Pass the continueOnError option to the promise graph runner.\n *\n * @param root\n * @param targetGraph\n * @returns\n */\n async run(root: string, targetGraph: TargetGraph, shouldRerun = false): Promise<SchedulerRunSummary<WorkerResult>> {\n const startTime: [number, number] = process.hrtime();\n\n const { continueOnError, logger, shouldCache } = this.options;\n\n logger.verbose(\"\", {\n schedulerRun: {\n startTime,\n },\n });\n\n const { pool, abortController } = this;\n\n const { targets } = targetGraph;\n\n for (const target of targets.values()) {\n let targetRun: WrappedTarget;\n\n const prevTargetRun = this.targetRuns.get(target.id);\n if (prevTargetRun) {\n targetRun = prevTargetRun;\n\n // If previous run has been successful, then we may want to rerun\n if (prevTargetRun.successful && shouldRerun) {\n this.markTargetAndDependentsPending(target.id);\n } else if (prevTargetRun.waiting && shouldRerun) {\n this.rerunTargets.add(targetRun.target.id);\n } else if (!prevTargetRun.successful) {\n // If previous run has failed, we should rerun\n this.markTargetAndDependentsPending(target.id);\n }\n } else {\n targetRun = new WrappedTarget({\n target,\n root,\n logger,\n shouldCache,\n continueOnError,\n abortController,\n pool,\n hasher: this.options.hasher,\n onMessage: this.options.onMessage,\n });\n }\n\n this.targetRuns.set(target.id, targetRun);\n }\n\n let results: SchedulerRunResults = \"failed\";\n let error: string | undefined;\n let duration: [number, number] = [0, 0];\n let targetRunByStatus: TargetRunSummary;\n\n try {\n await this.scheduleReadyTargets();\n } catch (e) {\n error = e instanceof Error ? e.message : String(e);\n } finally {\n duration = process.hrtime(startTime);\n targetRunByStatus = categorizeTargetRuns(this.targetRuns.values());\n\n if (\n targetRunByStatus.failed.length +\n targetRunByStatus.aborted.length +\n targetRunByStatus.pending.length +\n targetRunByStatus.running.length ===\n 0\n ) {\n results = \"success\";\n }\n }\n\n const poolStats = pool.stats();\n\n await this.options.hasher.cleanup();\n\n return {\n targetRunByStatus,\n targetRuns: this.targetRuns,\n duration,\n startTime,\n results,\n error,\n workerRestarts: poolStats.workerRestarts, // number of times a worker was restarted due to memory usage\n maxWorkerMemoryUsage: poolStats.maxWorkerMemoryUsage, // max memory usage of a worker in bytes\n };\n }\n\n /**\n * Used by consumers of the scheduler to notify that the inputs to the target has changed\n * @param targetId\n */\n markTargetAndDependentsPending(targetId) {\n const queue = [targetId];\n while (queue.length > 0) {\n const current = queue.shift()!;\n\n if (this.targetRuns.has(current)) {\n const targetRun = this.targetRuns.get(current)!;\n\n if (targetRun.status !== \"pending\") {\n targetRun.reset();\n this.rerunTargets.add(targetRun.target.id);\n const dependents = targetRun.target.dependents;\n for (const dependent of dependents) {\n queue.push(dependent);\n }\n }\n }\n }\n }\n\n getReadyTargets() {\n const readyTargets: Set<WrappedTarget> = new Set();\n\n for (const target of this.getTargetsByPriority()) {\n // Skip the start target\n if (target.id === getStartTargetId()) {\n continue;\n }\n\n const targetRun = this.targetRuns.get(target.id)!;\n\n // If the target is already running, then we can't run it again\n if (targetRun.status === \"pending\") {\n const targetDeps = targetRun.target.dependencies;\n\n // Target is only ready when all its deps are \"successful\" or that it is a root target\n const ready = targetDeps.every((dep) => {\n const fromTarget = this.targetRuns.get(dep)!;\n return fromTarget.successful || dep === getStartTargetId();\n });\n\n if (ready) {\n readyTargets.add(targetRun);\n }\n }\n }\n\n return [...readyTargets];\n }\n\n isAllDone() {\n for (const t of this.targetRuns.values()) {\n if (t.status !== \"skipped\" && t.status !== \"success\" && t.target.id !== getStartTargetId()) {\n return false;\n }\n }\n\n return true;\n }\n\n async scheduleReadyTargets() {\n if (this.isAllDone() || this.abortSignal.aborted) {\n return Promise.resolve();\n }\n\n this.options.logger.silly(`Max Worker Memory Usage: ${formatBytes(this.pool.stats().maxWorkerMemoryUsage)}`);\n\n const promises: Promise<any>[] = [];\n\n for (const nextTarget of this.getReadyTargets()) {\n const runPromise = this.#generateTargetRunPromise(nextTarget);\n promises.push(runPromise);\n }\n\n await Promise.all(promises);\n }\n\n logProgress() {\n const targetRunByStatus = categorizeTargetRuns(this.targetRuns.values());\n const total = [...this.targetRuns.values()].filter((t) => !t.target.hidden).length;\n\n this.options.logger.verbose(\"\", {\n poolStats: this.pool.stats(),\n progress: {\n waiting: targetRunByStatus.pending.length + targetRunByStatus.queued.length,\n completed:\n targetRunByStatus.aborted.length +\n targetRunByStatus.failed.length +\n targetRunByStatus.skipped.length +\n targetRunByStatus.success.length,\n total,\n },\n });\n }\n\n async #generateTargetRunPromise(target: WrappedTarget) {\n let runError: unknown | undefined;\n\n if (!target.successful || this.rerunTargets.has(target.target.id)) {\n // This do-while loop only runs again if something causes this target to rerun (asynchronously triggering a re-run)\n do {\n this.rerunTargets.delete(target.target.id);\n target.onQueued();\n\n try {\n let shouldRun = true;\n\n try {\n const runner = await this.runnerPicker.pick(target.target);\n shouldRun = await runner.shouldRun(target.target);\n } catch (e) {\n // pass - default to run anyway\n }\n\n if (shouldRun) {\n await target.run();\n } else {\n target.onSkipped();\n }\n } catch (e) {\n runError = e;\n }\n } while (this.rerunTargets.has(target.target.id));\n\n // if a continue option is set, this merely records what errors have been encountered\n // it'll continue down the execution until all the tasks that still works\n if (runError && !this.options?.continueOnError) {\n if (!this.options?.continueOnError) {\n // immediately reject, if not using \"continue\" option\n throw runError;\n }\n }\n }\n\n this.logProgress();\n\n // finally do another round of scheduling to run next round of targets\n await this.scheduleReadyTargets();\n }\n\n async cleanup() {\n this.options.logger.silly(`Max Worker Memory Usage: ${formatBytes(this.pool.stats().maxWorkerMemoryUsage)}`);\n await this.pool.close();\n }\n\n /**\n * Abort the scheduler using the abort controller.\n */\n abort() {\n this.abortController.abort();\n }\n}\nencodeURI;\n"],"names":["SimpleScheduler","getTargetsByPriority","sortTargetsByPriority","targetRuns","values","map","run","target","root","targetGraph","shouldRerun","startTime","process","hrtime","continueOnError","logger","shouldCache","options","verbose","schedulerRun","pool","abortController","targets","targetRun","prevTargetRun","get","id","successful","markTargetAndDependentsPending","waiting","rerunTargets","add","WrappedTarget","hasher","onMessage","set","results","error","duration","targetRunByStatus","scheduleReadyTargets","e","Error","message","String","categorizeTargetRuns","failed","length","aborted","pending","running","poolStats","stats","cleanup","workerRestarts","maxWorkerMemoryUsage","targetId","queue","current","shift","has","status","reset","dependents","dependent","push","getReadyTargets","readyTargets","Set","getStartTargetId","targetDeps","dependencies","ready","every","dep","fromTarget","isAllDone","t","abortSignal","Promise","resolve","silly","formatBytes","promises","nextTarget","runPromise","all","logProgress","total","filter","hidden","progress","queued","completed","skipped","success","close","abort","runnerPicker","Map","AbortController","signal","AggregatedPool","maxWorkersByGroup","maxWorkersPerTask","groupBy","task","maxWorkers","concurrency","script","require","workerOptions","stdout","stderr","workerData","shouldResetCache","workerIdleMemoryLimit","TargetRunnerPicker","runners","runError","delete","onQueued","shouldRun","runner","pick","onSkipped","encodeURI"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../src/SimpleScheduler.ts"],"sourcesContent":["import { AggregatedPool } from \"@lage-run/worker-threads-pool\";\nimport { formatBytes } from \"./formatBytes.js\";\nimport { categorizeTargetRuns } from \"./categorizeTargetRuns.js\";\nimport { type Target, getStartTargetId, sortTargetsByPriority } from \"@lage-run/target-graph\";\nimport { WrappedTarget } from \"./WrappedTarget.js\";\nimport { TargetRunnerPicker } from \"@lage-run/runners\";\n\nimport type { WorkerResult } from \"./WrappedTarget.js\";\nimport type { Logger } from \"@lage-run/logger\";\nimport type { TargetGraph } from \"@lage-run/target-graph\";\nimport type { TargetScheduler, SchedulerRunResults, SchedulerRunSummary, TargetRunSummary } from \"@lage-run/scheduler-types\";\nimport type { Pool } from \"@lage-run/worker-threads-pool\";\nimport type { TargetRunnerPickerOptions } from \"@lage-run/runners\";\nimport type { TargetHasher } from \"@lage-run/hasher\";\nimport type { CacheOptions } from \"@lage-run/cache\";\nimport type { MessagePort } from \"worker_threads\";\n\nexport interface SimpleSchedulerOptions {\n logger: Logger;\n concurrency: number;\n continueOnError: boolean;\n shouldCache: boolean;\n shouldResetCache: boolean;\n workerData: {\n runners: TargetRunnerPickerOptions;\n root: string;\n taskArgs: string[];\n skipLocalCache?: boolean;\n cacheOptions?: CacheOptions;\n };\n maxWorkersPerTask: Map<string, number>;\n pool?: Pool; // for testing\n workerIdleMemoryLimit: number; // in bytes\n hasher: TargetHasher;\n onMessage?: (message: any, postMessage: MessagePort[\"postMessage\"]) => void;\n}\n\n/**\n * Simple scheduler that runs all targets in a promise graph using p-graph library.\n *\n * Some characteristics:\n * 1. Can cache results of target runs via the cache provider.\n * 2. Takes a TargetRunner, a CacheProvider, a TargetHasher and a Logger as constructor parameters (dependency injection).\n * 3. Directly constructs new WrappedTarget, which provides the call to caching and logging.\n *\n * Roadmap / future enhancements:\n * 1. Allow for multiple kinds of runner (currently only ONE is supported, and it is applied to all targets)\n *\n */\nexport class SimpleScheduler implements TargetScheduler<WorkerResult> {\n targetRuns: Map<string, WrappedTarget> = new Map();\n rerunTargets: Set<string> = new Set();\n abortController: AbortController = new AbortController();\n abortSignal: AbortSignal = this.abortController.signal;\n pool: Pool;\n runnerPicker: TargetRunnerPicker;\n\n runPromise = Promise.resolve() as Promise<any>;\n\n constructor(private options: SimpleSchedulerOptions) {\n this.pool =\n options.pool ??\n new AggregatedPool({\n logger: options.logger,\n maxWorkersByGroup: options.maxWorkersPerTask,\n groupBy: ({ target }) => target.task,\n maxWorkers: options.concurrency,\n script: require.resolve(\"./workers/targetWorker\"),\n workerOptions: {\n stdout: true,\n stderr: true,\n workerData: { ...options.workerData, shouldCache: options.shouldCache, shouldResetCache: options.shouldResetCache },\n },\n workerIdleMemoryLimit: options.workerIdleMemoryLimit, // in bytes\n });\n\n this.runnerPicker = new TargetRunnerPicker(options.workerData.runners);\n }\n\n getTargetsByPriority(): Target[] {\n return sortTargetsByPriority([...this.targetRuns.values()].map((run) => run.target));\n }\n\n /**\n * The job of the run method is to:\n * 1. Convert the target graph into a promise graph.\n * 2. Create a promise graph of all targets\n * 3. Pass the continueOnError option to the promise graph runner.\n *\n * @param root\n * @param targetGraph\n * @returns\n */\n async run(root: string, targetGraph: TargetGraph, shouldRerun = false): Promise<SchedulerRunSummary<WorkerResult>> {\n const startTime: [number, number] = process.hrtime();\n\n const { continueOnError, logger, shouldCache } = this.options;\n\n logger.verbose(\"\", {\n schedulerRun: {\n startTime,\n },\n });\n\n const { pool, abortController } = this;\n\n const { targets } = targetGraph;\n\n for (const target of targets.values()) {\n let targetRun: WrappedTarget;\n\n const prevTargetRun = this.targetRuns.get(target.id);\n if (prevTargetRun) {\n targetRun = prevTargetRun;\n\n // If previous run has been successful, then we may want to rerun\n if (prevTargetRun.successful && shouldRerun) {\n this.markTargetAndDependentsPending(target.id);\n } else if (prevTargetRun.waiting && shouldRerun) {\n this.rerunTargets.add(targetRun.target.id);\n } else if (!prevTargetRun.successful) {\n // If previous run has failed, we should rerun\n this.markTargetAndDependentsPending(target.id);\n }\n } else {\n targetRun = new WrappedTarget({\n target,\n root,\n logger,\n shouldCache,\n continueOnError,\n abortController,\n pool,\n hasher: this.options.hasher,\n onMessage: this.options.onMessage,\n });\n }\n\n this.targetRuns.set(target.id, targetRun);\n }\n\n let results: SchedulerRunResults = \"failed\";\n let error: string | undefined;\n let duration: [number, number] = [0, 0];\n let targetRunByStatus: TargetRunSummary;\n\n try {\n await this.scheduleReadyTargets();\n } catch (e) {\n error = e instanceof Error ? e.message : String(e);\n } finally {\n duration = process.hrtime(startTime);\n targetRunByStatus = categorizeTargetRuns(this.targetRuns.values());\n\n if (\n targetRunByStatus.failed.length +\n targetRunByStatus.aborted.length +\n targetRunByStatus.pending.length +\n targetRunByStatus.running.length ===\n 0\n ) {\n results = \"success\";\n }\n }\n\n const poolStats = pool.stats();\n\n await this.options.hasher.cleanup();\n\n return {\n targetRunByStatus,\n targetRuns: this.targetRuns,\n duration,\n startTime,\n results,\n error,\n workerRestarts: poolStats.workerRestarts, // number of times a worker was restarted due to memory usage\n maxWorkerMemoryUsage: poolStats.maxWorkerMemoryUsage, // max memory usage of a worker in bytes\n };\n }\n\n /**\n * Used by consumers of the scheduler to notify that the inputs to the target has changed\n * @param targetId\n */\n markTargetAndDependentsPending(targetId: string): void {\n const queue = [targetId];\n while (queue.length > 0) {\n const current = queue.shift()!;\n\n if (this.targetRuns.has(current)) {\n const targetRun = this.targetRuns.get(current)!;\n\n if (targetRun.status !== \"pending\") {\n targetRun.reset();\n this.rerunTargets.add(targetRun.target.id);\n const dependents = targetRun.target.dependents;\n for (const dependent of dependents) {\n queue.push(dependent);\n }\n }\n }\n }\n }\n\n getReadyTargets(): WrappedTarget[] {\n const readyTargets: Set<WrappedTarget> = new Set();\n\n for (const target of this.getTargetsByPriority()) {\n // Skip the start target\n if (target.id === getStartTargetId()) {\n continue;\n }\n\n const targetRun = this.targetRuns.get(target.id)!;\n\n // If the target is already running, then we can't run it again\n if (targetRun.status === \"pending\") {\n const targetDeps = targetRun.target.dependencies;\n\n // Target is only ready when all its deps are \"successful\" or that it is a root target\n const ready = targetDeps.every((dep) => {\n const fromTarget = this.targetRuns.get(dep)!;\n return fromTarget.successful || dep === getStartTargetId();\n });\n\n if (ready) {\n readyTargets.add(targetRun);\n }\n }\n }\n\n return [...readyTargets];\n }\n\n isAllDone(): boolean {\n for (const t of this.targetRuns.values()) {\n if (t.status !== \"skipped\" && t.status !== \"success\" && t.target.id !== getStartTargetId()) {\n return false;\n }\n }\n\n return true;\n }\n\n async scheduleReadyTargets(): Promise<void> {\n if (this.isAllDone() || this.abortSignal.aborted) {\n return Promise.resolve();\n }\n\n this.options.logger.silly(`Max Worker Memory Usage: ${formatBytes(this.pool.stats().maxWorkerMemoryUsage)}`);\n\n const promises: Promise<any>[] = [];\n\n for (const nextTarget of this.getReadyTargets()) {\n const runPromise = this.#generateTargetRunPromise(nextTarget);\n promises.push(runPromise);\n }\n\n await Promise.all(promises);\n }\n\n logProgress(): void {\n const targetRunByStatus = categorizeTargetRuns(this.targetRuns.values());\n const total = [...this.targetRuns.values()].filter((t) => !t.target.hidden).length;\n\n this.options.logger.verbose(\"\", {\n poolStats: this.pool.stats(),\n progress: {\n waiting: targetRunByStatus.pending.length + targetRunByStatus.queued.length,\n completed:\n targetRunByStatus.aborted.length +\n targetRunByStatus.failed.length +\n targetRunByStatus.skipped.length +\n targetRunByStatus.success.length,\n total,\n },\n });\n }\n\n async #generateTargetRunPromise(target: WrappedTarget) {\n let runError: unknown | undefined;\n\n if (!target.successful || this.rerunTargets.has(target.target.id)) {\n // This do-while loop only runs again if something causes this target to rerun (asynchronously triggering a re-run)\n do {\n this.rerunTargets.delete(target.target.id);\n target.onQueued();\n\n try {\n let shouldRun = true;\n\n try {\n const runner = await this.runnerPicker.pick(target.target);\n shouldRun = await runner.shouldRun(target.target);\n } catch (e) {\n // pass - default to run anyway\n }\n\n if (shouldRun) {\n await target.run();\n } else {\n target.onSkipped();\n }\n } catch (e) {\n runError = e;\n }\n } while (this.rerunTargets.has(target.target.id));\n\n // if a continue option is set, this merely records what errors have been encountered\n // it'll continue down the execution until all the tasks that still works\n if (runError && !this.options?.continueOnError) {\n if (!this.options?.continueOnError) {\n // immediately reject, if not using \"continue\" option\n throw runError;\n }\n }\n }\n\n this.logProgress();\n\n // finally do another round of scheduling to run next round of targets\n await this.scheduleReadyTargets();\n }\n\n async cleanup(): Promise<void> {\n this.options.logger.silly(`Max Worker Memory Usage: ${formatBytes(this.pool.stats().maxWorkerMemoryUsage)}`);\n await this.pool.close();\n }\n\n /**\n * Abort the scheduler using the abort controller.\n */\n abort(): void {\n this.abortController.abort();\n }\n}\n"],"names":["SimpleScheduler","getTargetsByPriority","sortTargetsByPriority","targetRuns","values","map","run","target","root","targetGraph","shouldRerun","startTime","process","hrtime","continueOnError","logger","shouldCache","options","verbose","schedulerRun","pool","abortController","targets","targetRun","prevTargetRun","get","id","successful","markTargetAndDependentsPending","waiting","rerunTargets","add","WrappedTarget","hasher","onMessage","set","results","error","duration","targetRunByStatus","scheduleReadyTargets","e","Error","message","String","categorizeTargetRuns","failed","length","aborted","pending","running","poolStats","stats","cleanup","workerRestarts","maxWorkerMemoryUsage","targetId","queue","current","shift","has","status","reset","dependents","dependent","push","getReadyTargets","readyTargets","Set","getStartTargetId","targetDeps","dependencies","ready","every","dep","fromTarget","isAllDone","t","abortSignal","Promise","resolve","silly","formatBytes","promises","nextTarget","runPromise","all","logProgress","total","filter","hidden","progress","queued","completed","skipped","success","close","abort","runnerPicker","Map","AbortController","signal","AggregatedPool","maxWorkersByGroup","maxWorkersPerTask","groupBy","task","maxWorkers","concurrency","script","require","workerOptions","stdout","stderr","workerData","shouldResetCache","workerIdleMemoryLimit","TargetRunnerPicker","runners","runError","delete","onQueued","shouldRun","runner","pick","onSkipped"],"mappings":"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"}
|
package/lib/WrappedTarget.d.ts
CHANGED
package/lib/WrappedTarget.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/WrappedTarget.ts"],"sourcesContent":["import { bufferTransform } from \"./bufferTransform.js\";\nimport { getLageOutputCacheLocation } from \"./getLageOutputCacheLocation.js\";\nimport { type LogEntry, LogLevel } from \"@lage-run/logger\";\n\nimport fs from \"fs\";\nimport path from \"path\";\nimport { mkdir, writeFile } from \"fs/promises\";\n\nimport type { Pool } from \"@lage-run/worker-threads-pool\";\nimport type { TargetRun, TargetStatus } from \"@lage-run/scheduler-types\";\nimport { getStartTargetId, type Target } from \"@lage-run/target-graph\";\nimport type { Logger } from \"@lage-run/logger\";\nimport type { TargetHasher } from \"@lage-run/hasher\";\nimport type { MessagePort } from \"worker_threads\";\n\nexport interface WrappedTargetOptions {\n root: string;\n target: Target;\n logger: Logger;\n shouldCache: boolean;\n continueOnError: boolean;\n abortController: AbortController;\n pool: Pool;\n hasher: TargetHasher;\n onMessage?: (message: any, postMessage: MessagePort[\"postMessage\"]) => void;\n}\n\nexport interface WorkerResult {\n stdoutBuffer: string;\n stderrBuffer: string;\n skipped: boolean;\n hash: string;\n value: unknown;\n id: string;\n}\n\n/**\n * Wraps a target with additional functionality:\n * 1. Caching\n * 2. Logging\n * 3. Abort signal\n * 4. Continue on error\n */\nexport class WrappedTarget implements TargetRun<WorkerResult> {\n #status: TargetStatus = \"pending\";\n #result: WorkerResult | undefined;\n queueTime: [number, number] = [0, 0];\n startTime: [number, number] = [0, 0];\n duration: [number, number] = [0, 0];\n target: Target;\n threadId = 0;\n\n get result() {\n return this.#result;\n }\n\n get status() {\n return this.#status;\n }\n\n get abortController() {\n return this.options.abortController;\n }\n\n set abortController(abortController: AbortController) {\n this.options.abortController = abortController;\n }\n\n get successful() {\n return this.#status === \"skipped\" || this.#status === \"success\";\n }\n\n get waiting() {\n return this.#status === \"pending\" || this.#status === \"queued\";\n }\n\n constructor(public options: WrappedTargetOptions) {\n this.target = options.target;\n\n if (this.target.id === getStartTargetId()) {\n this.#status = \"success\";\n }\n\n this.options.logger.info(\"\", { target: this.target, status: this.status });\n }\n\n onQueued() {\n this.#status = \"queued\";\n this.queueTime = process.hrtime();\n this.options.logger.info(\"\", { target: this.target, status: \"queued\" });\n }\n\n onAbort() {\n this.#status = \"aborted\";\n this.options.logger.info(\"\", { target: this.target, status: \"aborted\", threadId: this.threadId });\n }\n\n onStart(threadId: number) {\n if (this.status !== \"running\") {\n this.threadId = threadId;\n this.#status = \"running\";\n this.startTime = process.hrtime();\n this.options.logger.info(\"\", { target: this.target, status: \"running\", threadId });\n }\n }\n\n onComplete() {\n this.#status = \"success\";\n this.options.logger.info(\"\", {\n target: this.target,\n status: \"success\",\n duration: this.duration,\n threadId: this.threadId,\n });\n }\n\n onFail() {\n this.#status = \"failed\";\n this.options.logger.info(\"\", {\n target: this.target,\n status: \"failed\",\n duration: this.duration,\n threadId: this.threadId,\n });\n\n if (!this.options.continueOnError && this.options.abortController) {\n this.options.abortController.abort();\n }\n }\n\n onSkipped(hash?: string | undefined) {\n this.#status = \"skipped\";\n\n if (hash) {\n this.options.logger.info(\"\", {\n target: this.target,\n status: \"skipped\",\n duration: this.duration,\n hash,\n threadId: this.threadId,\n });\n }\n }\n\n async run() {\n const { target, logger, shouldCache, abortController, root } = this.options;\n\n const abortSignal = abortController.signal;\n\n if (abortSignal.aborted) {\n this.onStart(0);\n this.onAbort();\n return;\n }\n\n try {\n this.#result = await this.runInPool();\n\n const cacheEnabled = target.cache && shouldCache && this.#result.hash;\n // Save output if cache is enabled & cache is hit\n if (!this.#result.skipped && cacheEnabled) {\n const outputLocation = getLageOutputCacheLocation(root, this.#result.hash);\n const outputPath = path.dirname(outputLocation);\n await mkdir(outputPath, { recursive: true });\n\n const output = `${this.#result.stdoutBuffer}\\n${this.#result.stderrBuffer}`;\n\n await writeFile(outputLocation, output);\n\n logger.verbose(`>> Saved cache - ${this.#result.hash}`, { target });\n }\n\n if (this.#result.skipped) {\n const { hash } = this.#result;\n\n const cachedOutputFile = getLageOutputCacheLocation(root, hash ?? \"\");\n\n const shouldShowCachedOutput = fs.existsSync(cachedOutputFile);\n if (shouldShowCachedOutput) {\n const cachedOutput = fs.readFileSync(cachedOutputFile, \"utf8\");\n logger.verbose(\">> Replaying cached output\", { target });\n logger.verbose(cachedOutput.trim(), { target });\n }\n\n this.onSkipped(hash);\n } else {\n this.onComplete();\n }\n\n return this.#result;\n } catch (e) {\n if (e instanceof Error) {\n logger.error(String(e), { target });\n }\n\n if (abortSignal.aborted) {\n this.onAbort();\n } else {\n this.onFail();\n }\n\n throw e;\n }\n }\n\n private async runInPool(): Promise<WorkerResult> {\n const { target, logger, abortController, pool } = this.options;\n const abortSignal = abortController.signal;\n\n let releaseStdout: any;\n let releaseStderr: any;\n\n const bufferStdout = bufferTransform();\n const bufferStderr = bufferTransform();\n\n let msgHandler: (data: LogEntry<any> & { type: string }) => void;\n\n const result = await (pool.exec(\n { target },\n target.weight ?? 1,\n (worker, stdout, stderr) => {\n const postMessage = worker.postMessage.bind(worker);\n\n msgHandler = (data) => {\n if (data.type === \"log\") {\n logger.log(data.level, data.msg, { target, threadId: worker.threadId });\n } else if (data.type === \"hash\") {\n void this.options.hasher.hash(target).then((hash) => {\n worker.postMessage({ type: \"hash\", hash });\n });\n } else if (this.options.onMessage) {\n this.options.onMessage(data, postMessage);\n }\n };\n\n worker.on(\"message\", msgHandler);\n\n const threadId = worker.threadId;\n\n this.onStart(threadId);\n\n stdout.pipe(bufferStdout.transform);\n stderr.pipe(bufferStderr.transform);\n\n const releaseStdoutStream = logger.stream(LogLevel.verbose, stdout, { target, threadId });\n\n releaseStdout = () => {\n releaseStdoutStream();\n stdout.unpipe(bufferStdout.transform);\n };\n\n const releaseStderrStream = logger.stream(LogLevel.verbose, stderr, { target, threadId });\n\n releaseStderr = () => {\n releaseStderrStream();\n stderr.unpipe(bufferStderr.transform);\n };\n },\n (worker) => {\n worker.off(\"message\", msgHandler);\n this.duration = process.hrtime(this.startTime);\n releaseStdout();\n releaseStderr();\n },\n abortSignal,\n target.priority\n ) as Promise<{ value?: unknown; skipped: boolean; hash: string; id: string }>);\n\n return {\n stdoutBuffer: bufferStdout.buffer,\n stderrBuffer: bufferStderr.buffer,\n skipped: result?.skipped,\n hash: result?.hash,\n value: result?.value,\n id: result?.id,\n };\n }\n\n /**\n * A JSON representation of this wrapped target, suitable for serialization in tests.\n *\n * Skips the unpredictable properties of the wrapped target like the startTime and duration.\n *\n * @returns\n */\n toJSON() {\n return {\n target: this.target.id,\n status: this.status,\n };\n }\n\n /**\n * Reset the state of this wrapped target.\n */\n reset() {\n this.#result = undefined;\n this.#status = \"pending\";\n }\n}\n"],"names":["WrappedTarget","result","status","abortController","options","successful","waiting","onQueued","queueTime","process","hrtime","logger","info","target","onAbort","threadId","onStart","startTime","onComplete","duration","onFail","continueOnError","abort","onSkipped","hash","run","shouldCache","root","abortSignal","signal","aborted","runInPool","cacheEnabled","cache","skipped","outputLocation","getLageOutputCacheLocation","outputPath","path","dirname","mkdir","recursive","output","stdoutBuffer","stderrBuffer","writeFile","verbose","cachedOutputFile","shouldShowCachedOutput","fs","existsSync","cachedOutput","readFileSync","trim","e","Error","error","String","pool","releaseStdout","releaseStderr","bufferStdout","bufferTransform","bufferStderr","msgHandler","exec","weight","worker","stdout","stderr","postMessage","bind","data","type","log","level","msg","hasher","then","onMessage","on","pipe","transform","releaseStdoutStream","stream","LogLevel","unpipe","releaseStderrStream","off","priority","buffer","value","id","toJSON","reset","undefined","getStartTargetId"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../src/WrappedTarget.ts"],"sourcesContent":["import { bufferTransform } from \"./bufferTransform.js\";\nimport { getLageOutputCacheLocation } from \"./getLageOutputCacheLocation.js\";\nimport { type LogEntry, LogLevel } from \"@lage-run/logger\";\n\nimport fs from \"fs\";\nimport path from \"path\";\nimport { mkdir, writeFile } from \"fs/promises\";\n\nimport type { Pool } from \"@lage-run/worker-threads-pool\";\nimport type { TargetRun, TargetStatus } from \"@lage-run/scheduler-types\";\nimport { getStartTargetId, type Target } from \"@lage-run/target-graph\";\nimport type { Logger } from \"@lage-run/logger\";\nimport type { TargetHasher } from \"@lage-run/hasher\";\nimport type { MessagePort } from \"worker_threads\";\n\nexport interface WrappedTargetOptions {\n root: string;\n target: Target;\n logger: Logger;\n shouldCache: boolean;\n continueOnError: boolean;\n abortController: AbortController;\n pool: Pool;\n hasher: TargetHasher;\n onMessage?: (message: any, postMessage: MessagePort[\"postMessage\"]) => void;\n}\n\nexport interface WorkerResult {\n stdoutBuffer: string;\n stderrBuffer: string;\n skipped: boolean;\n hash: string;\n value: unknown;\n id: string;\n}\n\n/**\n * Wraps a target with additional functionality:\n * 1. Caching\n * 2. Logging\n * 3. Abort signal\n * 4. Continue on error\n */\nexport class WrappedTarget implements TargetRun<WorkerResult> {\n #status: TargetStatus = \"pending\";\n #result: WorkerResult | undefined;\n queueTime: [number, number] = [0, 0];\n startTime: [number, number] = [0, 0];\n duration: [number, number] = [0, 0];\n target: Target;\n threadId = 0;\n\n get result(): WorkerResult | undefined {\n return this.#result;\n }\n\n get status(): TargetStatus {\n return this.#status;\n }\n\n get abortController(): AbortController {\n return this.options.abortController;\n }\n\n set abortController(abortController: AbortController) {\n this.options.abortController = abortController;\n }\n\n get successful(): boolean {\n return this.#status === \"skipped\" || this.#status === \"success\";\n }\n\n get waiting(): boolean {\n return this.#status === \"pending\" || this.#status === \"queued\";\n }\n\n constructor(public options: WrappedTargetOptions) {\n this.target = options.target;\n\n if (this.target.id === getStartTargetId()) {\n this.#status = \"success\";\n }\n\n this.options.logger.info(\"\", { target: this.target, status: this.status });\n }\n\n onQueued(): void {\n this.#status = \"queued\";\n this.queueTime = process.hrtime();\n this.options.logger.info(\"\", { target: this.target, status: \"queued\" });\n }\n\n onAbort(): void {\n this.#status = \"aborted\";\n this.options.logger.info(\"\", { target: this.target, status: \"aborted\", threadId: this.threadId });\n }\n\n onStart(threadId: number): void {\n if (this.status !== \"running\") {\n this.threadId = threadId;\n this.#status = \"running\";\n this.startTime = process.hrtime();\n this.options.logger.info(\"\", { target: this.target, status: \"running\", threadId });\n }\n }\n\n onComplete(): void {\n this.#status = \"success\";\n this.options.logger.info(\"\", {\n target: this.target,\n status: \"success\",\n duration: this.duration,\n threadId: this.threadId,\n });\n }\n\n onFail(): void {\n this.#status = \"failed\";\n this.options.logger.info(\"\", {\n target: this.target,\n status: \"failed\",\n duration: this.duration,\n threadId: this.threadId,\n });\n\n if (!this.options.continueOnError && this.options.abortController) {\n this.options.abortController.abort();\n }\n }\n\n onSkipped(hash?: string | undefined): void {\n this.#status = \"skipped\";\n\n if (hash) {\n this.options.logger.info(\"\", {\n target: this.target,\n status: \"skipped\",\n duration: this.duration,\n hash,\n threadId: this.threadId,\n });\n }\n }\n\n async run(): Promise<WorkerResult | undefined> {\n const { target, logger, shouldCache, abortController, root } = this.options;\n\n const abortSignal = abortController.signal;\n\n if (abortSignal.aborted) {\n this.onStart(0);\n this.onAbort();\n return;\n }\n\n try {\n this.#result = await this.runInPool();\n\n const cacheEnabled = target.cache && shouldCache && this.#result.hash;\n // Save output if cache is enabled & cache is hit\n if (!this.#result.skipped && cacheEnabled) {\n const outputLocation = getLageOutputCacheLocation(root, this.#result.hash);\n const outputPath = path.dirname(outputLocation);\n await mkdir(outputPath, { recursive: true });\n\n const output = `${this.#result.stdoutBuffer}\\n${this.#result.stderrBuffer}`;\n\n await writeFile(outputLocation, output);\n\n logger.verbose(`>> Saved cache - ${this.#result.hash}`, { target });\n }\n\n if (this.#result.skipped) {\n const { hash } = this.#result;\n\n const cachedOutputFile = getLageOutputCacheLocation(root, hash ?? \"\");\n\n const shouldShowCachedOutput = fs.existsSync(cachedOutputFile);\n if (shouldShowCachedOutput) {\n const cachedOutput = fs.readFileSync(cachedOutputFile, \"utf8\");\n logger.verbose(\">> Replaying cached output\", { target });\n logger.verbose(cachedOutput.trim(), { target });\n }\n\n this.onSkipped(hash);\n } else {\n this.onComplete();\n }\n\n return this.#result;\n } catch (e) {\n if (e instanceof Error) {\n logger.error(String(e), { target });\n }\n\n if (abortSignal.aborted) {\n this.onAbort();\n } else {\n this.onFail();\n }\n\n throw e;\n }\n }\n\n private async runInPool(): Promise<WorkerResult> {\n const { target, logger, abortController, pool } = this.options;\n const abortSignal = abortController.signal;\n\n let releaseStdout: any;\n let releaseStderr: any;\n\n const bufferStdout = bufferTransform();\n const bufferStderr = bufferTransform();\n\n let msgHandler: (data: LogEntry<any> & { type: string }) => void;\n\n const result = await (pool.exec(\n { target },\n target.weight ?? 1,\n (worker, stdout, stderr) => {\n const postMessage = worker.postMessage.bind(worker);\n\n msgHandler = (data) => {\n if (data.type === \"log\") {\n logger.log(data.level, data.msg, { target, threadId: worker.threadId });\n } else if (data.type === \"hash\") {\n void this.options.hasher.hash(target).then((hash) => {\n worker.postMessage({ type: \"hash\", hash });\n });\n } else if (this.options.onMessage) {\n this.options.onMessage(data, postMessage);\n }\n };\n\n worker.on(\"message\", msgHandler);\n\n const threadId = worker.threadId;\n\n this.onStart(threadId);\n\n stdout.pipe(bufferStdout.transform);\n stderr.pipe(bufferStderr.transform);\n\n const releaseStdoutStream = logger.stream(LogLevel.verbose, stdout, { target, threadId });\n\n releaseStdout = () => {\n releaseStdoutStream();\n stdout.unpipe(bufferStdout.transform);\n };\n\n const releaseStderrStream = logger.stream(LogLevel.verbose, stderr, { target, threadId });\n\n releaseStderr = () => {\n releaseStderrStream();\n stderr.unpipe(bufferStderr.transform);\n };\n },\n (worker) => {\n worker.off(\"message\", msgHandler);\n this.duration = process.hrtime(this.startTime);\n releaseStdout();\n releaseStderr();\n },\n abortSignal,\n target.priority\n ) as Promise<{ value?: unknown; skipped: boolean; hash: string; id: string }>);\n\n return {\n stdoutBuffer: bufferStdout.buffer,\n stderrBuffer: bufferStderr.buffer,\n skipped: result?.skipped,\n hash: result?.hash,\n value: result?.value,\n id: result?.id,\n };\n }\n\n /**\n * A JSON representation of this wrapped target, suitable for serialization in tests.\n *\n * Skips the unpredictable properties of the wrapped target like the startTime and duration.\n *\n * @returns\n */\n toJSON(): {\n target: string;\n status: TargetStatus;\n } {\n return {\n target: this.target.id,\n status: this.status,\n };\n }\n\n /**\n * Reset the state of this wrapped target.\n */\n reset(): void {\n this.#result = undefined;\n this.#status = \"pending\";\n }\n}\n"],"names":["WrappedTarget","result","status","abortController","options","successful","waiting","onQueued","queueTime","process","hrtime","logger","info","target","onAbort","threadId","onStart","startTime","onComplete","duration","onFail","continueOnError","abort","onSkipped","hash","run","shouldCache","root","abortSignal","signal","aborted","runInPool","cacheEnabled","cache","skipped","outputLocation","getLageOutputCacheLocation","outputPath","path","dirname","mkdir","recursive","output","stdoutBuffer","stderrBuffer","writeFile","verbose","cachedOutputFile","shouldShowCachedOutput","fs","existsSync","cachedOutput","readFileSync","trim","e","Error","error","String","pool","releaseStdout","releaseStderr","bufferStdout","bufferTransform","bufferStderr","msgHandler","exec","weight","worker","stdout","stderr","postMessage","bind","data","type","log","level","msg","hasher","then","onMessage","on","pipe","transform","releaseStdoutStream","stream","LogLevel","unpipe","releaseStderrStream","off","priority","buffer","value","id","toJSON","reset","undefined","getStartTargetId"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/bufferTransform.ts"],"sourcesContent":["import { Transform } from \"stream\";\n\nexport function bufferTransform() {\n const chunks: string[] = [];\n\n return {\n get buffer() {\n return chunks.join(\"\");\n },\n transform: new Transform({\n transform(chunk, encoding, callback) {\n chunks.push(chunk.toString());\n callback();\n },\n }),\n };\n}\n"],"names":["bufferTransform","chunks","buffer","join","transform","Transform","chunk","encoding","callback","push","toString"],"mappings":";;;;+BAEgBA;;;eAAAA;;;wBAFU;AAEnB,SAASA;
|
|
1
|
+
{"version":3,"sources":["../src/bufferTransform.ts"],"sourcesContent":["import { Transform } from \"stream\";\n\nexport function bufferTransform(): {\n readonly buffer: string;\n transform: Transform;\n} {\n const chunks: string[] = [];\n\n return {\n get buffer() {\n return chunks.join(\"\");\n },\n transform: new Transform({\n transform(chunk, encoding, callback) {\n chunks.push(chunk.toString());\n callback();\n },\n }),\n };\n}\n"],"names":["bufferTransform","chunks","buffer","join","transform","Transform","chunk","encoding","callback","push","toString"],"mappings":";;;;+BAEgBA;;;eAAAA;;;wBAFU;AAEnB,SAASA;IAId,MAAMC,SAAmB,EAAE;IAE3B,OAAO;QACL,IAAIC,UAAS;YACX,OAAOD,OAAOE,IAAI,CAAC;QACrB;QACAC,WAAW,IAAIC,iBAAS,CAAC;YACvBD,WAAUE,KAAK,EAAEC,QAAQ,EAAEC,QAAQ;gBACjCP,OAAOQ,IAAI,CAACH,MAAMI,QAAQ;gBAC1BF;YACF;QACF;IACF;AACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/cache/createCacheProvider.ts"],"sourcesContent":["import type { CacheOptions } from \"@lage-run/cache\";\nimport { BackfillCacheProvider, RemoteFallbackCacheProvider } from \"@lage-run/cache\";\nimport type { Logger } from \"@lage-run/logger\";\nimport { isRunningFromCI } from \"./isRunningFromCI.js\";\n\ninterface CreateCacheOptions {\n cacheOptions?: CacheOptions;\n logger: Logger;\n root: string;\n skipLocalCache: boolean;\n cliArgs: string[];\n}\n\nexport async function createCache(options: CreateCacheOptions) {\n const { cacheOptions, logger, root, skipLocalCache } = options;\n\n const hasRemoteCacheConfig =\n !!cacheOptions?.cacheStorageConfig || !!process.env.BACKFILL_CACHE_PROVIDER || !!process.env.BACKFILL_CACHE_PROVIDER_OPTIONS;\n\n // Create Cache Provider\n const cacheProvider = new RemoteFallbackCacheProvider({\n root,\n logger,\n localCacheProvider:\n skipLocalCache === true\n ? undefined\n : new BackfillCacheProvider({\n logger,\n root,\n cacheOptions: {\n outputGlob: cacheOptions?.outputGlob,\n ...(cacheOptions?.internalCacheFolder && { internalCacheFolder: cacheOptions.internalCacheFolder }),\n ...(cacheOptions?.incrementalCaching && { incrementalCaching: cacheOptions.incrementalCaching }),\n },\n }),\n remoteCacheProvider: hasRemoteCacheConfig ? new BackfillCacheProvider({ logger, root, cacheOptions: cacheOptions ?? {} }) : undefined,\n writeRemoteCache:\n (cacheOptions?.writeRemoteCache === true || String(process.env.LAGE_WRITE_CACHE).toLowerCase() === \"true\" || isRunningFromCI) &&\n String(process.env.LAGE_WRITE_CACHE).toLowerCase() !== \"false\",\n });\n\n return { cacheProvider };\n}\n"],"names":["createCache","options","cacheOptions","logger","root","skipLocalCache","hasRemoteCacheConfig","cacheStorageConfig","process","env","BACKFILL_CACHE_PROVIDER","BACKFILL_CACHE_PROVIDER_OPTIONS","cacheProvider","RemoteFallbackCacheProvider","localCacheProvider","undefined","BackfillCacheProvider","outputGlob","internalCacheFolder","incrementalCaching","remoteCacheProvider","writeRemoteCache","String","LAGE_WRITE_CACHE","toLowerCase","isRunningFromCI"],"mappings":";;;;+BAasBA;;;eAAAA;;;uBAZ6C;iCAEnC;AAUzB,eAAeA,YAAYC,OAA2B;
|
|
1
|
+
{"version":3,"sources":["../../src/cache/createCacheProvider.ts"],"sourcesContent":["import type { CacheOptions } from \"@lage-run/cache\";\nimport { BackfillCacheProvider, RemoteFallbackCacheProvider } from \"@lage-run/cache\";\nimport type { Logger } from \"@lage-run/logger\";\nimport { isRunningFromCI } from \"./isRunningFromCI.js\";\n\ninterface CreateCacheOptions {\n cacheOptions?: CacheOptions;\n logger: Logger;\n root: string;\n skipLocalCache: boolean;\n cliArgs: string[];\n}\n\nexport async function createCache(options: CreateCacheOptions): Promise<{\n cacheProvider: RemoteFallbackCacheProvider;\n}> {\n const { cacheOptions, logger, root, skipLocalCache } = options;\n\n const hasRemoteCacheConfig =\n !!cacheOptions?.cacheStorageConfig || !!process.env.BACKFILL_CACHE_PROVIDER || !!process.env.BACKFILL_CACHE_PROVIDER_OPTIONS;\n\n // Create Cache Provider\n const cacheProvider = new RemoteFallbackCacheProvider({\n root,\n logger,\n localCacheProvider:\n skipLocalCache === true\n ? undefined\n : new BackfillCacheProvider({\n logger,\n root,\n cacheOptions: {\n outputGlob: cacheOptions?.outputGlob,\n ...(cacheOptions?.internalCacheFolder && { internalCacheFolder: cacheOptions.internalCacheFolder }),\n ...(cacheOptions?.incrementalCaching && { incrementalCaching: cacheOptions.incrementalCaching }),\n },\n }),\n remoteCacheProvider: hasRemoteCacheConfig ? new BackfillCacheProvider({ logger, root, cacheOptions: cacheOptions ?? {} }) : undefined,\n writeRemoteCache:\n (cacheOptions?.writeRemoteCache === true || String(process.env.LAGE_WRITE_CACHE).toLowerCase() === \"true\" || isRunningFromCI) &&\n String(process.env.LAGE_WRITE_CACHE).toLowerCase() !== \"false\",\n });\n\n return { cacheProvider };\n}\n"],"names":["createCache","options","cacheOptions","logger","root","skipLocalCache","hasRemoteCacheConfig","cacheStorageConfig","process","env","BACKFILL_CACHE_PROVIDER","BACKFILL_CACHE_PROVIDER_OPTIONS","cacheProvider","RemoteFallbackCacheProvider","localCacheProvider","undefined","BackfillCacheProvider","outputGlob","internalCacheFolder","incrementalCaching","remoteCacheProvider","writeRemoteCache","String","LAGE_WRITE_CACHE","toLowerCase","isRunningFromCI"],"mappings":";;;;+BAasBA;;;eAAAA;;;uBAZ6C;iCAEnC;AAUzB,eAAeA,YAAYC,OAA2B;IAG3D,MAAM,EAAEC,YAAY,EAAEC,MAAM,EAAEC,IAAI,EAAEC,cAAc,EAAE,GAAGJ;IAEvD,MAAMK,uBACJ,CAAC,CAACJ,cAAcK,sBAAsB,CAAC,CAACC,QAAQC,GAAG,CAACC,uBAAuB,IAAI,CAAC,CAACF,QAAQC,GAAG,CAACE,+BAA+B;IAE9H,wBAAwB;IACxB,MAAMC,gBAAgB,IAAIC,kCAA2B,CAAC;QACpDT;QACAD;QACAW,oBACET,mBAAmB,OACfU,YACA,IAAIC,4BAAqB,CAAC;YACxBb;YACAC;YACAF,cAAc;gBACZe,YAAYf,cAAce;gBAC1B,GAAIf,cAAcgB,uBAAuB;oBAAEA,qBAAqBhB,aAAagB,mBAAmB;gBAAC,CAAC;gBAClG,GAAIhB,cAAciB,sBAAsB;oBAAEA,oBAAoBjB,aAAaiB,kBAAkB;gBAAC,CAAC;YACjG;QACF;QACNC,qBAAqBd,uBAAuB,IAAIU,4BAAqB,CAAC;YAAEb;YAAQC;YAAMF,cAAcA,gBAAgB,CAAC;QAAE,KAAKa;QAC5HM,kBACE,AAACnB,CAAAA,cAAcmB,qBAAqB,QAAQC,OAAOd,QAAQC,GAAG,CAACc,gBAAgB,EAAEC,WAAW,OAAO,UAAUC,gCAAe,AAAD,KAC3HH,OAAOd,QAAQC,GAAG,CAACc,gBAAgB,EAAEC,WAAW,OAAO;IAC3D;IAEA,OAAO;QAAEZ;IAAc;AACzB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/cache/isRunningFromCI.ts"],"sourcesContent":["export const isRunningFromCI = process.env.NODE_ENV !== \"test\" && (!!process.env.CI || !!process.env.TF_BUILD);\n"],"names":["isRunningFromCI","process","env","NODE_ENV","CI","TF_BUILD"],"mappings":";;;;+BAAaA;;;eAAAA;;;AAAN,MAAMA,
|
|
1
|
+
{"version":3,"sources":["../../src/cache/isRunningFromCI.ts"],"sourcesContent":["export const isRunningFromCI: boolean = process.env.NODE_ENV !== \"test\" && (!!process.env.CI || !!process.env.TF_BUILD);\n"],"names":["isRunningFromCI","process","env","NODE_ENV","CI","TF_BUILD"],"mappings":";;;;+BAAaA;;;eAAAA;;;AAAN,MAAMA,kBAA2BC,QAAQC,GAAG,CAACC,QAAQ,KAAK,UAAW,CAAA,CAAC,CAACF,QAAQC,GAAG,CAACE,EAAE,IAAI,CAAC,CAACH,QAAQC,GAAG,CAACG,QAAQ,AAAD"}
|
package/lib/formatBytes.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/formatBytes.ts"],"sourcesContent":["export function formatBytes(bytes: number) {\n return `${(bytes / 1024 / 1024).toFixed(2)} MB`;\n}\n"],"names":["formatBytes","bytes","toFixed"],"mappings":";;;;+BAAgBA;;;eAAAA;;;AAAT,SAASA,YAAYC,KAAa;IACvC,OAAO,GAAG,AAACA,CAAAA,QAAQ,OAAO,IAAG,EAAGC,OAAO,CAAC,GAAG,GAAG,CAAC;AACjD"}
|
|
1
|
+
{"version":3,"sources":["../src/formatBytes.ts"],"sourcesContent":["export function formatBytes(bytes: number): string {\n return `${(bytes / 1024 / 1024).toFixed(2)} MB`;\n}\n"],"names":["formatBytes","bytes","toFixed"],"mappings":";;;;+BAAgBA;;;eAAAA;;;AAAT,SAASA,YAAYC,KAAa;IACvC,OAAO,GAAG,AAACA,CAAAA,QAAQ,OAAO,IAAG,EAAGC,OAAO,CAAC,GAAG,GAAG,CAAC;AACjD"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/getLageOutputCacheLocation.ts"],"sourcesContent":["import { getLogsCacheDirectory } from \"@lage-run/cache\";\nimport path from \"path\";\n\nexport function getLageOutputCacheLocation(root: string, hash: string) {\n const outputPath = getLogsCacheDirectory(root, hash);\n return path.join(outputPath, hash + \".log\");\n}\n"],"names":["getLageOutputCacheLocation","root","hash","outputPath","getLogsCacheDirectory","path","join"],"mappings":";;;;+BAGgBA;;;eAAAA;;;uBAHsB;6DACrB;;;;;;AAEV,SAASA,2BAA2BC,IAAY,EAAEC,IAAY;IACnE,MAAMC,aAAaC,IAAAA,4BAAqB,EAACH,MAAMC;IAC/C,OAAOG,aAAI,CAACC,IAAI,CAACH,YAAYD,OAAO;AACtC"}
|
|
1
|
+
{"version":3,"sources":["../src/getLageOutputCacheLocation.ts"],"sourcesContent":["import { getLogsCacheDirectory } from \"@lage-run/cache\";\nimport path from \"path\";\n\nexport function getLageOutputCacheLocation(root: string, hash: string): string {\n const outputPath = getLogsCacheDirectory(root, hash);\n return path.join(outputPath, hash + \".log\");\n}\n"],"names":["getLageOutputCacheLocation","root","hash","outputPath","getLogsCacheDirectory","path","join"],"mappings":";;;;+BAGgBA;;;eAAAA;;;uBAHsB;6DACrB;;;;;;AAEV,SAASA,2BAA2BC,IAAY,EAAEC,IAAY;IACnE,MAAMC,aAAaC,IAAAA,4BAAqB,EAACH,MAAMC;IAC/C,OAAOG,aAAI,CAACC,IAAI,CAACH,YAAYD,OAAO;AACtC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lage-run/scheduler",
|
|
3
|
-
"version": "1.5.
|
|
3
|
+
"version": "1.5.16",
|
|
4
4
|
"description": "Scheduler for Lage",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -17,17 +17,17 @@
|
|
|
17
17
|
"lint": "monorepo-scripts lint"
|
|
18
18
|
},
|
|
19
19
|
"dependencies": {
|
|
20
|
-
"@lage-run/cache": "^1.4.
|
|
21
|
-
"@lage-run/config": "^0.7.
|
|
22
|
-
"@lage-run/hasher": "^1.9.
|
|
23
|
-
"@lage-run/logger": "^1.3.
|
|
24
|
-
"@lage-run/runners": "^1.2.
|
|
25
|
-
"@lage-run/target-graph": "^0.12.
|
|
26
|
-
"@lage-run/worker-threads-pool": "^0.9.
|
|
20
|
+
"@lage-run/cache": "^1.4.4",
|
|
21
|
+
"@lage-run/config": "^0.7.2",
|
|
22
|
+
"@lage-run/hasher": "^1.9.2",
|
|
23
|
+
"@lage-run/logger": "^1.3.2",
|
|
24
|
+
"@lage-run/runners": "^1.2.6",
|
|
25
|
+
"@lage-run/target-graph": "^0.12.2",
|
|
26
|
+
"@lage-run/worker-threads-pool": "^0.9.2"
|
|
27
27
|
},
|
|
28
28
|
"devDependencies": {
|
|
29
29
|
"@lage-run/monorepo-scripts": "^1.0.0",
|
|
30
|
-
"@lage-run/scheduler-types": "^0.3.
|
|
30
|
+
"@lage-run/scheduler-types": "^0.3.28"
|
|
31
31
|
},
|
|
32
32
|
"publishConfig": {
|
|
33
33
|
"access": "public"
|