-
Notifications
You must be signed in to change notification settings - Fork 64
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 fail-fast flag to src batch #1049
base: main
Are you sure you want to change the base?
Changes from all commits
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 |
---|---|---|
|
@@ -101,7 +101,7 @@ Examples: | |
} | ||
|
||
ctx, cancel := contextCancelOnInterrupt(context.Background()) | ||
defer cancel() | ||
defer cancel(nil) | ||
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. I wonder if we should be passing in nil directly here, an error could occur at any point in the execution of a batch spec. Is there a reason why the handler := func(args []string) (err error) {
...
ctx, cancel := contextCancelOnInterrupt(context.Background())
defer cancel(err)
...
} This way we are guaranteed to always have access to whatever error occurs in the lifecycle of an execution. |
||
|
||
err := executeBatchSpecInWorkspaces(ctx, flags) | ||
if err != nil { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,6 +5,7 @@ import ( | |
"flag" | ||
"fmt" | ||
|
||
"github.com/sourcegraph/src-cli/internal/batches/executor" | ||
"github.com/sourcegraph/src-cli/internal/cmderrors" | ||
) | ||
|
||
|
@@ -40,9 +41,20 @@ Examples: | |
} | ||
|
||
ctx, cancel := contextCancelOnInterrupt(context.Background()) | ||
defer cancel() | ||
|
||
if err = executeBatchSpec(ctx, executeBatchSpecOpts{ | ||
defer cancel(nil) | ||
|
||
failFastCancel := func(error) {} | ||
if flags.failFast { | ||
failFastCancel = cancel | ||
} | ||
|
||
cctx := executor.CancelableContext{ | ||
Context: ctx, | ||
Cancel: failFastCancel, | ||
} | ||
Comment on lines
+52
to
+55
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. Is there a need for this struct? Is there a reason we can't pass in the context and Or better still have the |
||
|
||
if err = executeBatchSpec(cctx, executeBatchSpecOpts{ | ||
flags: flags, | ||
client: cfg.apiClient(flags.api, flagSet.Output()), | ||
file: file, | ||
|
Original file line number | Diff line number | Diff line change | ||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -13,10 +13,15 @@ import ( | |||||||||||||||||||
) | ||||||||||||||||||||
|
||||||||||||||||||||
type taskExecutor interface { | ||||||||||||||||||||
Start(context.Context, []*Task, TaskExecutionUI) | ||||||||||||||||||||
Start(CancelableContext, []*Task, TaskExecutionUI) | ||||||||||||||||||||
Wait(context.Context) ([]taskResult, error) | ||||||||||||||||||||
} | ||||||||||||||||||||
|
||||||||||||||||||||
type CancelableContext struct { | ||||||||||||||||||||
context.Context | ||||||||||||||||||||
Cancel context.CancelCauseFunc | ||||||||||||||||||||
} | ||||||||||||||||||||
|
||||||||||||||||||||
// Coordinator coordinates the execution of Tasks. It makes use of an executor, | ||||||||||||||||||||
// checks the ExecutionCache whether execution is necessary, and builds | ||||||||||||||||||||
// batcheslib.ChangesetSpecs out of the executionResults. | ||||||||||||||||||||
|
@@ -177,7 +182,7 @@ func (c *Coordinator) buildSpecs(ctx context.Context, batchSpec *batcheslib.Batc | |||||||||||||||||||
|
||||||||||||||||||||
// ExecuteAndBuildSpecs executes the given tasks and builds changeset specs for the results. | ||||||||||||||||||||
// It calls the ui on updates. | ||||||||||||||||||||
func (c *Coordinator) ExecuteAndBuildSpecs(ctx context.Context, batchSpec *batcheslib.BatchSpec, tasks []*Task, ui TaskExecutionUI) ([]*batcheslib.ChangesetSpec, []string, error) { | ||||||||||||||||||||
func (c *Coordinator) ExecuteAndBuildSpecs(ctx CancelableContext, batchSpec *batcheslib.BatchSpec, tasks []*Task, ui TaskExecutionUI) ([]*batcheslib.ChangesetSpec, []string, error) { | ||||||||||||||||||||
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. Since the arguments to this method is getting bulky, we can move it into a struct and pass in the cancel function explicitly.
Suggested change
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. The cancelFunc isn't being used here, I wonder if we need to pass it in here as an argument? |
||||||||||||||||||||
ui.Start(tasks) | ||||||||||||||||||||
|
||||||||||||||||||||
// Run executor. | ||||||||||||||||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -92,12 +92,14 @@ func NewExecutor(opts NewExecutorOpts) *executor { | |
} | ||
} | ||
|
||
var ErrFastFail = errors.New("Execution stopped due to fast-fail mode.") | ||
|
||
// Start starts the execution of the given Tasks in goroutines, calling the | ||
// given taskStatusHandler to update the progress of the tasks. | ||
func (x *executor) Start(ctx context.Context, tasks []*Task, ui TaskExecutionUI) { | ||
func (x *executor) Start(ctx CancelableContext, tasks []*Task, ui TaskExecutionUI) { | ||
defer func() { close(x.doneEnqueuing) }() | ||
|
||
for _, task := range tasks { | ||
fmt.Println(task.Repository) | ||
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. Left over debug statement |
||
select { | ||
case <-ctx.Done(): | ||
return | ||
|
@@ -115,6 +117,7 @@ func (x *executor) Start(ctx context.Context, tasks []*Task, ui TaskExecutionUI) | |
default: | ||
err := x.do(ctx, task, ui) | ||
if err != nil { | ||
ctx.Cancel(ErrFastFail) | ||
x.par.Error(err) | ||
} | ||
} | ||
|
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.
This is awesome. TIL I learned about the
.WithCancelCause
method.