-
Couldn't load subscription status.
- Fork 213
[Incremental] stop if no -driver-continue-building-after-errors #387
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
Conversation
| @swift-ci please test |
| I’ll take a look at this tomorrow! Was a few weeks ago when I posted that PR, but I do remember not being completely satisfied with it. |
Thank you, @cltnschlosser . I'll look forward to your thoughts. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like this, although I'm surprised testInputModifiedDuringMultiJobBuild didn't fail. Also I think we should bring over the test that I included in my PR.
| allJobs: [Job], | ||
| forceResponseFiles: Bool | ||
| ) throws { | ||
| let continueBuildingAfterErrors = parsedOptions.contains(.continueBuildingAfterErrors) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You'll see in my PR I made a function for computing this and copied over a comment from the c++ driver. ContineuBuildingAfterErrors is set to true when compiling in batch mode.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes. Good idea! Since I'm not storing this value as a driver instance variable, the function doesn't have to be static, though the test is a little more complicated. The test will require my other PR to land to support -driver-use-frontend-path. But I do like the idea of the test.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I think I stored it specifically for test, but it's also not that important of a test.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks! I know at least one legacy will fail of the driver doesn't cancel when it needs to, but I like the idea of testing what your test does, so I put one in.
| public enum DriverExecutorWorkload { | ||
| case all([Job]) | ||
| case incremental(IncrementalCompilationState) | ||
| public struct DriverExecutorWorkload { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I do like this better, from a SPM compatibility perspective.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks!
| private(set) var executeAllJobsTaskBuildEngine: LLTaskBuildEngine? = nil | ||
| | ||
| /// If a job fails, the driver needs to stop running jobs. | ||
| private(set) var shouldStopRunningJobs = false |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
naming: shouldStopRunningNewJobs, because it doesn't stop any actively running jobs, just scheduled ones.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, good catch!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about isBuildCancelled ? I like the specificity of including the object.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That name seems fine :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks!
| if context.shouldStopRunningJobs { | ||
| engine.taskIsComplete(DriverBuildValue.jobExecution(success: false)) | ||
| return | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You mentioned you liked my implementation better here. I'm fine with either. They should be logically equivalent, I was stopping before the call to executeJob and you're stopping near the beginning. I do think this should either be moved outside of executeJob or moved all the way to the top, because skips any job startup work that might occur. Environment variable merging in this case (Even though that's probably near 0 overhead anyway).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you. Yes, I've gone with your design, tightened up a bit.
| case (.terminated(let code), false) where code != EXIT_SUCCESS: | ||
| shouldStopRunningJobs = true | ||
| #if !os(Windows) | ||
| case (.signalled, _): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm guessing this is more correct than in my solution where I used result.success as the flag and never considered if the failure was due to a signal or not.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks!
| @cltnschlosser Thank you for your thoughtful review. I'll work on incorporating your suggestions. |
Yes! I'll bring over that test. |
| @cltnschlosser If this looks good at this point, it would be productive to have your official approval. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just realized that there might be a data race on the isBuildCancelled property because the operationQueue can run concurrent jobs, but that can be fixed in a follow up, and it's worth considering the thread safety of the whole context.
| guard allInputsSucceeded, !context.isBuildCancelled else { | ||
| return engine.taskIsComplete(DriverBuildValue.jobExecution(success: false)) | ||
| } | ||
| |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh @davidungar Looks like you are missing https://github.com/apple/swift-driver/pull/371/files/a00c657b31853c25f2544f0cef6d836f517c2179#diff-b2d6d242100a7556a15175d3576106d4a413a2b7b5ffa3bbb52f74210b7408e3R454-R456 Right below this. It's needed to stop jobs which have been scheduled(inputs are available) but haven't started yet(due to throttling the number of concurrent jobs). This is why you don't see the test failure I was talking about in my recent comment on #371
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, yes, I see. Given the issue, I think it means the other way is better, moving the test to the top of executeJob.
Thanks a lot for pointing it out!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I had it in both spots, inside the queue and before it, but inside only should be fine.
| @swift-ci please test |
Great point! And thanks for the approval. |
| Fixes rdar://71869814 |
| @swift-ci please test |
Without being aware of @cltnschlosser 's similar PR ( https://github.com/apple/swift-driver/pull/371/files ), I wrote this code last week. I suspect the two PRs do the same thing. So, not being sure how to proceed, I thought I would put this up and we might review each other's work and come up with a nice synthesis, (hence the "DNM").
Rather than disturb the interface that goes across to swiftpm, I included the extra parameter in the workload structure.
BTW, some version of this functionality is needed for the legacy lit tests.
Have incorporated several great ideas from @cltnschlosser 's PR.