Add context

This commit adds and passes context around to (almost) every function.
This allows cancelling (almost) every function call globally.
This commit is contained in:
Tom Wiesing 2022-11-28 13:30:08 +01:00
parent 996ecb9f80
commit 3455f491ca
No known key found for this signature in database
104 changed files with 836 additions and 511 deletions

View file

@ -45,7 +45,7 @@ type Environment interface {
DialContext(context context.Context, network, address string) (net.Conn, error)
Executable() (string, error)
Exec(io stream.IOStream, workdir string, exe string, argv ...string) int
Exec(ctx context.Context, io stream.IOStream, workdir string, exe string, argv ...string) int
LookPathAbs(name string) (string, error)
}

View file

@ -2,6 +2,7 @@ package environment
import (
"bytes"
"context"
"io"
"io/fs"
"os"
@ -64,6 +65,6 @@ func ReadFile(env Environment, path string) ([]byte, error) {
}
// MustExec is like Exec, except that it returns true if the command exited successfully, and else false.
func MustExec(env Environment, io stream.IOStream, workdir string, exe string, argv ...string) bool {
return env.Exec(io, workdir, exe, argv...) == 0
func MustExec(ctx context.Context, env Environment, io stream.IOStream, workdir string, exe string, argv ...string) bool {
return env.Exec(ctx, io, workdir, exe, argv...) == 0
}

View file

@ -1,8 +1,10 @@
package environment
import (
"context"
"os/exec"
"github.com/FAU-CDI/wisski-distillery/pkg/cancel"
"github.com/tkw1536/goprogram/stream"
)
@ -10,7 +12,7 @@ import (
//
// If the command executes, it's exit code will be returned.
// If the command can not be executed, returns [ExecCommandError].
func (*Native) Exec(io stream.IOStream, workdir string, exe string, argv ...string) int {
func (*Native) Exec(ctx context.Context, io stream.IOStream, workdir string, exe string, argv ...string) int {
// setup the command
cmd := exec.Command(exe, argv...)
cmd.Dir = workdir
@ -18,8 +20,27 @@ func (*Native) Exec(io stream.IOStream, workdir string, exe string, argv ...stri
cmd.Stdout = io.Stdout
cmd.Stderr = io.Stderr
// run it
err := cmd.Run()
// run the process in a cancelable fashion
err, cErr := cancel.WithContext(ctx, func(cancelable func()) error {
// start the process
err := cmd.Start()
if err != nil {
return err
}
// allow it to be cancellable
cancelable()
// and wait for the rest of the process
return cmd.Wait()
}, func() {
if cmd.Process != nil {
cmd.Process.Kill()
}
})
if err == nil {
err = cErr
}
// non-zero exit
if err, ok := err.(*exec.ExitError); ok {