您的位置:首页 > 编程语言 > Go语言

Go实现控制任程序的生命周期

2017-04-23 23:49 483 查看
runner/runner.go:

package runner

import (
"errors"
"os"
"os/signal"
"time"
)

type Runner struct {
interrupt chan os.Signal

complete chan error

timeout <-chan time.Time

tasks []func(int)
}

var ErrTimeout = errors.New("received timeout")

var ErrInterrupt = errors.New("received interrupt")

func New(d time.Duration) *Runner {
return &Runner{
interrupt: make(chan os.Signal, 1),
complete: make(chan error),
timeout: time.After(d),
}
}

func (r *Runner) Add(tasks ...func(int)){
r.tasks = append(r.tasks, tasks...)
}

func (r *Runner) Start() error {
signal.Notify(r.interrupt, os.Interrupt)

go func() {
r.complete <- r.run()
}()

select {
case err := <-r.complete:
return err
case <-r.timeout:
return ErrTimeout
}
}

func (r *Runner) run() error {
for id, task := range r.tasks {
if r.gotInterrupt() {
return ErrInterrupt
}

task(id)
}

return nil
}

func (r *Runner) gotInterrupt() bool {
select {
case <-r.interrupt:
signal.Stop(r.interrupt)
return true

default:
return false
}
}


runner/main/main.go:

package main

import (
"log"
"time"
"os"
"runner"
)

const timeout = 3 * time.Second

func main(){
log.Println("Starting work.")

r := runner.New(timeout)

r.Add(createTask(), createTask(), createTask())

if err := r.Start(); err != nil {
switch err {
case runner.ErrTimeout:
log.Println("Terminating due to timeout.")
os.Exit(1)
case runner.ErrInterrupt:
log.Println("Terminating due to interrupt.")
os.Exit(2)
}

log.Println("Process ended.")
}

}

func createTask() func(int) {
return func(id int){
log.Printf("Processor - Task #%d.", id)
time.Sleep(time.Duration(id) * time.Second)
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  go runner channel goroutine