Skip to content
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

Add Build Cancellation #350

Merged
merged 1 commit into from
Mar 19, 2018
Merged

Add Build Cancellation #350

merged 1 commit into from
Mar 19, 2018

Conversation

stefanpenner
Copy link
Contributor

@stefanpenner stefanpenner commented Dec 12, 2017

Descrption

For larger builds, it is important that a mid-build <ctrl-c> can both gracefully exit, but also exist as fast as possible. In-order to accomplish this, we need to be able to terminate the build after the current step completes.

Also for larger builds, it is important that if a new change event occurs mid-build, that we can pause the build after the current step, and resume it from the beginning (in a safe way). This provides a good user-experience, as 2 changes slower then the throttle threshold but faster then a rebuild will still only produce 1 consistent output. No accidentally mid-build stale outputs.

builder.cancel().then(() => /* the build was cancelled */);

TODOS

  • a fulfilled cancel guarantees to leave the build in a resumable state
  • a rejected cancel suggests a unrecoverable build
  • builder.cancel() will currently wait for the current step to an, before cancelling the build. This is to ensure the build is resumable, and can be lifted in the future with more work.
  • a builder.buid() is not allowed if the builder currently has a pending build or cancellation
  • builder.cancel is idempotent
  • events (‘nodeStart’ ‘nodeEnd’) remain balanced in-light or cancellation
  • CancellationErrors are isSilent and isCancellation to play nicely with consumers like ember-cli

TODO:

  • mid-build change events should cancel the current build and queue up behind the existing cancel before kicking off another build.
  • better error messages
  • wire up signals so the CLI gets cancellation on etc.

@stefanpenner stefanpenner requested a review from rwjblue December 12, 2017 04:13
lib/builder.js Outdated
@@ -81,8 +83,14 @@ module.exports = class Builder {
// This method will never throw, and it will never be rejected with anything
// other than a BuildError.
build() {
if (this._cancelationRequest) {
return RSVP.Promise.reject('WTF');
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

better error message, likely a BuildError with a message similar tocannot build mid-build


const CancelationError = require('./errors/cancelation');

module.exports = class CancelationRequest {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this class needs to be unit tested

@@ -29,6 +29,9 @@ RSVP.on('error', error => {
throw error;
});

function wait(time) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like calling this settled because await wait() is weird 😝

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i think this is more nextTick

let resolveCancel;
const cancelling = new RSVP.Promise(resolve => (resolveCancel = resolve));

stepA.build = function() {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

subclass rather then hackity hack

Copy link
Contributor

@chrmod chrmod left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so far it looks pretty straightforward

@stefanpenner stefanpenner force-pushed the build-cancellation branch 3 times, most recently from 757d2fc to 527f597 Compare December 21, 2017 22:25
```
builder.cancel().then(() => /* the build was cancelled */);
```

- [x] a fulfilled `cancel` guarantees to leave the build in a resumable state
- [x]  a rejected `cancel` suggests a unrecoverable build
- [x] `builder.cancel()` will currently wait for the current step to an, before cancelling the build. This is to ensure the build is resumable, and can be lifted in the future with more work.
- [x] a `builder.buid()` is not allowed if the `builder` currently has a pending build or cancellation
- [x] `builder.cancel` is idempotent
- [x] events (‘nodeStart’ ‘nodeEnd’) remain balanced in-light or cancellation
- [x] CancellationErrors are `isSilent` and `isCancellation` to play nicely with consumers like ember-cli
- [x] better error messages

TODO:

- [ ] mid-build change events should cancel the current build and queue up behind the existing cancel before kicking off another build.
@oligriffiths
Copy link
Contributor

@stefanpenner what’s the state of play with this? Looks pretty good rn

@rwjblue rwjblue changed the title WIP: cancellation Add Build Cancellation Mar 19, 2018
@rwjblue rwjblue merged commit 7d97eba into master Mar 19, 2018
@rwjblue rwjblue deleted the build-cancellation branch March 19, 2018 12:55
@rwjblue
Copy link
Member

rwjblue commented Mar 19, 2018

@oligriffiths / @stefanpenner - Lets move the remaining TODO's:

  • mid-build change events should cancel the current build and queue up behind the existing cancel before kicking off another build.
  • wire up signals so the CLI gets cancellation on etc.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants