-
Notifications
You must be signed in to change notification settings - Fork 700
[rush] Add per-iteration runner persistence control #5888
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
55e1bf4
94af331
4854b5b
9eb5f0c
e20c69f
bd9cd75
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| { | ||
| "changes": [ | ||
| { | ||
| "packageName": "@microsoft/rush", | ||
| "comment": "Add a per-iteration, host-driven runner persist policy so IPC runners can be kept hot or torn down per operation per iteration, instead of fixing persistence at plugin construction.", | ||
| "type": "patch" | ||
| } | ||
| ] | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -799,6 +799,8 @@ export class OperationGraph implements IOperationGraph { | |
| onStartAsync: onOperationStartAsync, | ||
| onResultAsync: onOperationCompleteAsync | ||
| }; | ||
| const recordsWithRunnerCleanup: Set<OperationExecutionRecord> = new Set(); | ||
| const graph: OperationGraph = this; | ||
|
|
||
| if (!this.quietMode) { | ||
| const plural: string = totalOperations === 1 ? '' : 's'; | ||
|
|
@@ -873,9 +875,36 @@ export class OperationGraph implements IOperationGraph { | |
| }); | ||
| } | ||
|
|
||
| const recordsToClose: OperationExecutionRecord[] = []; | ||
| for (const record of executionRecords.values()) { | ||
| if (!recordsWithRunnerCleanup.has(record) && !record.shouldRunnerPersist) { | ||
| recordsToClose.push(record); | ||
| } | ||
| } | ||
| function reportRunnerCleanupFailure(record: OperationExecutionRecord, error: Error): void { | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If a non-persistent runner fails to close at end-of-iteration (not mid-execution), should this always turn the iteration into a Failure, or should it be a Warning? |
||
| record.error = error; | ||
| record.status = OperationStatus.Failure; | ||
| _reportOperationErrorIfAny(record); | ||
| state.hasAnyFailures = true; | ||
| } | ||
| await Async.forEachAsync( | ||
| recordsToClose, | ||
| async (record: OperationExecutionRecord) => { | ||
| try { | ||
| await this.closeRunnersAsync([record.operation]); | ||
| } catch (e) { | ||
| reportRunnerCleanupFailure(record, e); | ||
| } | ||
| }, | ||
| { concurrency: this.parallelism } | ||
| ); | ||
|
Comment on lines
+890
to
+900
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Are runners designed to handle concurrent closeAsync() calls if they're still being used elsewhere? Seems handled by the fact that non-persistent runners are closed immediately after completion (lines 1059-1068), but worth documenting. |
||
| for (const record of executionRecords.values()) { | ||
| record.finalize(); | ||
| } | ||
|
|
||
| const status: OperationStatus = (() => { | ||
| if (bailStatus) return bailStatus; | ||
| if (state.hasAnyFailures) return OperationStatus.Failure; | ||
| if (bailStatus) return bailStatus; | ||
| if (state.hasAnyAborted) return OperationStatus.Aborted; | ||
| if (state.hasAnyNonAllowedWarnings) return OperationStatus.SuccessWithWarning; | ||
| if (iterationContext.totalOperations === 0) return OperationStatus.NoOp; | ||
|
|
@@ -1027,6 +1056,16 @@ export class OperationGraph implements IOperationGraph { | |
| record.error = e; | ||
| record.status = OperationStatus.Failure; | ||
| } | ||
| if (!record.shouldRunnerPersist) { | ||
| recordsWithRunnerCleanup.add(record); | ||
| try { | ||
| await graph.closeRunnersAsync([record.operation]); | ||
| } catch (e) { | ||
| _reportOperationErrorIfAny(record); | ||
| record.error = e; | ||
| record.status = OperationStatus.Failure; | ||
| } | ||
| } | ||
| _onOperationComplete(record, state); | ||
| } | ||
| } | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.