@lage-run/scheduler 1.5.22 → 1.6.0

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.
@@ -26,6 +26,7 @@ export interface SimpleSchedulerOptions {
26
26
  pool?: Pool;
27
27
  workerIdleMemoryLimit: number;
28
28
  hasher: TargetHasher;
29
+ logMemory?: boolean;
29
30
  onMessage?: (message: any, postMessage: MessagePort["postMessage"]) => void;
30
31
  }
31
32
  /**
@@ -88,6 +88,7 @@ class SimpleScheduler {
88
88
  abortController,
89
89
  pool,
90
90
  hasher: this.options.hasher,
91
+ logMemory: this.options.logMemory,
91
92
  onMessage: this.options.onMessage
92
93
  });
93
94
  }
@@ -259,7 +260,7 @@ async function generateTargetRunPromise(target) {
259
260
  try {
260
261
  const runner = await this.runnerPicker.pick(target.target);
261
262
  shouldRun = await runner.shouldRun(target.target);
262
- } catch (e) {
263
+ } catch {
263
264
  // pass - default to run anyway
264
265
  }
265
266
  if (shouldRun) {
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/SimpleScheduler.ts"],"sourcesContent":["import type { CacheOptions } from \"@lage-run/cache\";\nimport type { TargetHasher } from \"@lage-run/hasher\";\nimport type { Logger } from \"@lage-run/logger\";\nimport type { TargetRunnerPickerOptions } from \"@lage-run/runners\";\nimport { TargetRunnerPicker } from \"@lage-run/runners\";\nimport type { SchedulerRunResults, SchedulerRunSummary, TargetRunSummary, TargetScheduler } from \"@lage-run/scheduler-types\";\nimport type { TargetGraph } from \"@lage-run/target-graph\";\nimport { type Target, getStartTargetId, sortTargetsByPriority } from \"@lage-run/target-graph\";\nimport type { Pool } from \"@lage-run/worker-threads-pool\";\nimport { AggregatedPool } from \"@lage-run/worker-threads-pool\";\nimport type { MessagePort } from \"worker_threads\";\nimport { categorizeTargetRuns } from \"./categorizeTargetRuns.js\";\nimport { formatBytes } from \"./formatBytes.js\";\nimport type { WorkerResult } from \"./WrappedTarget.js\";\nimport { WrappedTarget } from \"./WrappedTarget.js\";\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 public readonly targetRuns: Map<string, WrappedTarget> = new Map();\n private rerunTargets: Set<string> = new Set();\n private abortController: AbortController = new AbortController();\n private abortSignal: AbortSignal = this.abortController.signal;\n private pool: Pool;\n public readonly runnerPicker: TargetRunnerPicker;\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 private 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 public 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 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 */\n private 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 private 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 private 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 private 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 private 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 public 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 public 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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"}
1
+ {"version":3,"sources":["../src/SimpleScheduler.ts"],"sourcesContent":["import type { CacheOptions } from \"@lage-run/cache\";\nimport type { TargetHasher } from \"@lage-run/hasher\";\nimport type { Logger } from \"@lage-run/logger\";\nimport type { TargetRunnerPickerOptions } from \"@lage-run/runners\";\nimport { TargetRunnerPicker } from \"@lage-run/runners\";\nimport type { SchedulerRunResults, SchedulerRunSummary, TargetRunSummary, TargetScheduler } from \"@lage-run/scheduler-types\";\nimport type { TargetGraph } from \"@lage-run/target-graph\";\nimport { type Target, getStartTargetId, sortTargetsByPriority } from \"@lage-run/target-graph\";\nimport type { Pool } from \"@lage-run/worker-threads-pool\";\nimport { AggregatedPool } from \"@lage-run/worker-threads-pool\";\nimport type { MessagePort } from \"worker_threads\";\nimport { categorizeTargetRuns } from \"./categorizeTargetRuns.js\";\nimport { formatBytes } from \"./formatBytes.js\";\nimport type { WorkerResult } from \"./WrappedTarget.js\";\nimport { WrappedTarget } from \"./WrappedTarget.js\";\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 logMemory?: boolean;\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 public readonly targetRuns: Map<string, WrappedTarget> = new Map();\n private rerunTargets: Set<string> = new Set();\n private abortController: AbortController = new AbortController();\n private abortSignal: AbortSignal = this.abortController.signal;\n private pool: Pool;\n public readonly runnerPicker: TargetRunnerPicker;\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 private 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 public 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 logMemory: this.options.logMemory,\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 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 */\n private 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 private 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 private 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 private 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 private 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 {\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 public 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 public 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","logMemory","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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"}
@@ -13,6 +13,7 @@ export interface WrappedTargetOptions {
13
13
  abortController: AbortController;
14
14
  pool: Pool;
15
15
  hasher: TargetHasher;
16
+ logMemory?: boolean;
16
17
  onMessage?: (message: any, postMessage: MessagePort["postMessage"]) => void;
17
18
  }
18
19
  export interface WorkerResult {
@@ -121,7 +121,10 @@ class WrappedTarget {
121
121
  target: this.target,
122
122
  status: "success",
123
123
  duration: this.duration,
124
- threadId: this.threadId
124
+ threadId: this.threadId,
125
+ ...this.options.logMemory && {
126
+ memoryUsage: process.memoryUsage()
127
+ }
125
128
  });
126
129
  }
127
130
  onFail() {
@@ -130,7 +133,10 @@ class WrappedTarget {
130
133
  target: this.target,
131
134
  status: "failed",
132
135
  duration: this.duration,
133
- threadId: this.threadId
136
+ threadId: this.threadId,
137
+ ...this.options.logMemory && {
138
+ memoryUsage: process.memoryUsage()
139
+ }
134
140
  });
135
141
  if (!this.options.continueOnError && this.options.abortController) {
136
142
  this.options.abortController.abort();
@@ -144,7 +150,10 @@ class WrappedTarget {
144
150
  status: "skipped",
145
151
  duration: this.duration,
146
152
  hash,
147
- threadId: this.threadId
153
+ threadId: this.threadId,
154
+ ...this.options.logMemory && {
155
+ memoryUsage: process.memoryUsage()
156
+ }
148
157
  });
149
158
  }
150
159
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/WrappedTarget.ts"],"sourcesContent":["import type { TargetHasher } from \"@lage-run/hasher\";\nimport type { Logger } from \"@lage-run/logger\";\nimport { type LogEntry, LogLevel } from \"@lage-run/logger\";\nimport type { TargetRun, TargetStatus } from \"@lage-run/scheduler-types\";\nimport { getStartTargetId, type Target } from \"@lage-run/target-graph\";\nimport type { Pool } from \"@lage-run/worker-threads-pool\";\nimport fs from \"fs\";\nimport { mkdir, writeFile } from \"fs/promises\";\nimport path from \"path\";\nimport type { MessagePort } from \"worker_threads\";\nimport { bufferTransform } from \"./bufferTransform.js\";\nimport { getLageOutputCacheLocation } from \"./getLageOutputCacheLocation.js\";\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 public queueTime: [number, number] = [0, 0];\n public startTime: [number, number] = [0, 0];\n public duration: [number, number] = [0, 0];\n public target: Target;\n public threadId = 0;\n\n public get result(): WorkerResult | undefined {\n return this.#result;\n }\n\n public get status(): TargetStatus {\n return this.#status;\n }\n\n public get successful(): boolean {\n return this.#status === \"skipped\" || this.#status === \"success\";\n }\n\n public 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 public onQueued(): void {\n this.#status = \"queued\";\n this.queueTime = process.hrtime();\n this.options.logger.info(\"\", { target: this.target, status: \"queued\" });\n }\n\n private onAbort(): void {\n this.#status = \"aborted\";\n this.options.logger.info(\"\", { target: this.target, status: \"aborted\", threadId: this.threadId });\n }\n\n private 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 private 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 private 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 public 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 public 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\n .hash(target)\n .then((hash) => {\n worker.postMessage({ type: \"hash\", hash });\n })\n .catch((e) => {\n logger.warn(`Failed to hash target ${target.id}: ${e instanceof Error ? e.message : String(e)}`);\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, used in Jest snapshots.\n *\n * Skips the unpredictable properties of the wrapped target like the startTime and duration.\n */\n public 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 public reset(): void {\n this.#result = undefined;\n this.#status = \"pending\";\n }\n}\n"],"names":["WrappedTarget","result","status","successful","waiting","onQueued","queueTime","process","hrtime","options","logger","info","target","onAbort","threadId","onStart","startTime","onComplete","duration","onFail","continueOnError","abortController","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","catch","warn","id","message","onMessage","on","pipe","transform","releaseStdoutStream","stream","LogLevel","unpipe","releaseStderrStream","off","priority","buffer","value","toJSON","reset","undefined","getStartTargetId"],"mappings":"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"}
1
+ {"version":3,"sources":["../src/WrappedTarget.ts"],"sourcesContent":["import type { TargetHasher } from \"@lage-run/hasher\";\nimport type { Logger } from \"@lage-run/logger\";\nimport { type LogEntry, LogLevel } from \"@lage-run/logger\";\nimport type { TargetRun, TargetStatus } from \"@lage-run/scheduler-types\";\nimport { getStartTargetId, type Target } from \"@lage-run/target-graph\";\nimport type { Pool } from \"@lage-run/worker-threads-pool\";\nimport fs from \"fs\";\nimport { mkdir, writeFile } from \"fs/promises\";\nimport path from \"path\";\nimport type { MessagePort } from \"worker_threads\";\nimport { bufferTransform } from \"./bufferTransform.js\";\nimport { getLageOutputCacheLocation } from \"./getLageOutputCacheLocation.js\";\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 logMemory?: boolean;\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 public queueTime: [number, number] = [0, 0];\n public startTime: [number, number] = [0, 0];\n public duration: [number, number] = [0, 0];\n public target: Target;\n public threadId = 0;\n\n public get result(): WorkerResult | undefined {\n return this.#result;\n }\n\n public get status(): TargetStatus {\n return this.#status;\n }\n\n public get successful(): boolean {\n return this.#status === \"skipped\" || this.#status === \"success\";\n }\n\n public 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 public onQueued(): void {\n this.#status = \"queued\";\n this.queueTime = process.hrtime();\n this.options.logger.info(\"\", { target: this.target, status: \"queued\" });\n }\n\n private onAbort(): void {\n this.#status = \"aborted\";\n this.options.logger.info(\"\", { target: this.target, status: \"aborted\", threadId: this.threadId });\n }\n\n private 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 private 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 ...(this.options.logMemory && { memoryUsage: process.memoryUsage() }),\n });\n }\n\n private 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 ...(this.options.logMemory && { memoryUsage: process.memoryUsage() }),\n });\n\n if (!this.options.continueOnError && this.options.abortController) {\n this.options.abortController.abort();\n }\n }\n\n public 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 ...(this.options.logMemory && { memoryUsage: process.memoryUsage() }),\n });\n }\n }\n\n public 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\n .hash(target)\n .then((hash) => {\n worker.postMessage({ type: \"hash\", hash });\n })\n .catch((e) => {\n logger.warn(`Failed to hash target ${target.id}: ${e instanceof Error ? e.message : String(e)}`);\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, used in Jest snapshots.\n *\n * Skips the unpredictable properties of the wrapped target like the startTime and duration.\n */\n public 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 public reset(): void {\n this.#result = undefined;\n this.#status = \"pending\";\n }\n}\n"],"names":["WrappedTarget","result","status","successful","waiting","onQueued","queueTime","process","hrtime","options","logger","info","target","onAbort","threadId","onStart","startTime","onComplete","duration","logMemory","memoryUsage","onFail","continueOnError","abortController","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","catch","warn","id","message","onMessage","on","pipe","transform","releaseStdoutStream","stream","LogLevel","unpipe","releaseStderrStream","off","priority","buffer","value","toJSON","reset","undefined","getStartTargetId"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lage-run/scheduler",
3
- "version": "1.5.22",
3
+ "version": "1.6.0",
4
4
  "description": "Scheduler for Lage",
5
5
  "repository": {
6
6
  "type": "git",
@@ -19,17 +19,17 @@
19
19
  "lint": "monorepo-scripts lint"
20
20
  },
21
21
  "dependencies": {
22
- "@lage-run/cache": "^1.4.10",
23
- "@lage-run/config": "^0.9.2",
24
- "@lage-run/hasher": "^1.9.6",
22
+ "@lage-run/cache": "^1.4.12",
23
+ "@lage-run/config": "^0.9.3",
24
+ "@lage-run/hasher": "^1.10.0",
25
25
  "@lage-run/logger": "^1.3.3",
26
- "@lage-run/runners": "^1.4.1",
27
- "@lage-run/target-graph": "^0.14.1",
28
- "@lage-run/worker-threads-pool": "^0.9.4"
26
+ "@lage-run/runners": "^1.4.2",
27
+ "@lage-run/target-graph": "^0.14.2",
28
+ "@lage-run/worker-threads-pool": "^0.10.0"
29
29
  },
30
30
  "devDependencies": {
31
31
  "@lage-run/monorepo-scripts": "^1.0.0",
32
- "@lage-run/scheduler-types": "^0.3.32",
32
+ "@lage-run/scheduler-types": "^0.4.0",
33
33
  "@lage-run/test-utilities": "^0.1.0"
34
34
  },
35
35
  "files": [