add main file
This commit is contained in:
parent
a48bbfd746
commit
5c8949cf8b
69
executer.go
Normal file
69
executer.go
Normal file
@ -0,0 +1,69 @@
|
||||
package executer
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"os/exec"
|
||||
"time"
|
||||
)
|
||||
|
||||
var ErrTimeout = errors.New("operation timed out")
|
||||
|
||||
type Job struct {
|
||||
Cmd *exec.Cmd
|
||||
Err chan error
|
||||
}
|
||||
|
||||
type Worker struct {
|
||||
Jobs chan Job
|
||||
Timeout time.Duration
|
||||
}
|
||||
|
||||
func NewJob(e *exec.Cmd) Job {
|
||||
return Job{
|
||||
Cmd: e,
|
||||
Err: make(chan error),
|
||||
}
|
||||
}
|
||||
|
||||
func NewWorker(timeout time.Duration) *Worker {
|
||||
w := &Worker{
|
||||
Jobs: make(chan Job, 1),
|
||||
Timeout: timeout,
|
||||
}
|
||||
// start worker routine
|
||||
go w.run()
|
||||
return w
|
||||
}
|
||||
|
||||
// runs in own goroutine
|
||||
func (e *Worker) run() {
|
||||
var done chan error
|
||||
|
||||
if e.Timeout != 0 {
|
||||
done = make(chan error)
|
||||
defer close(done)
|
||||
}
|
||||
|
||||
for j := range e.Jobs {
|
||||
if e.Timeout == 0 {
|
||||
// run synchronously
|
||||
j.Err <- j.Cmd.Run()
|
||||
} else {
|
||||
// run asyncly and timeout
|
||||
go func() {
|
||||
done <- j.Cmd.Run()
|
||||
}()
|
||||
|
||||
select {
|
||||
case err := <-done:
|
||||
j.Err <- err
|
||||
case <-time.After(e.Timeout):
|
||||
j.Err <- j.Cmd.Process.Kill()
|
||||
j.Err <- ErrTimeout
|
||||
}
|
||||
}
|
||||
|
||||
// signal done
|
||||
close(j.Err)
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user