自己写的go定时器执行任务,欢迎拍砖。
package main
import (
"fmt"
"time"
"bufio"
"os"
"strings"
"errors"
"io/ioutil"
"strconv"
"regexp"
"net/http"
)
var taskList []*Task
type MyTimer struct{
Config []map[string]interface{}
}
func NewMyTimer() *MyTimer{
return &MyTimer{}
}
func (t *MyTimer) Start(){
for _, v := range t.Config{
//针对每个设置,启动任务
myTask := NewTask(v)
myTask.Start()
taskList = append(taskList, myTask)
}
fmt.Println("---------- Timer Started ---------")
}
func (t *MyTimer) Stop(){
for _, task := range taskList{
task.Stop()
}
//清空task列表
taskList = make([]*Task, 0)
fmt.Println("--------- Timer Stoped ----------")
}
func (t *MyTimer) Restart(){
t.Stop()
t.Start()
fmt.Println("-------- Timer Restarted ----------")
}
func (t *MyTimer) LoadConfigFile(fileName string) error{
file,err:=os.Open(fileName)
if nil!=err{
return errors.New("config file load failed:"+fileName)
}
defer file.Close()
config:=make([]map[string]interface{}, 0)
content,ok:=ioutil.ReadAll(file)
if ok!=nil{
return errors.New("read config file error")
}
str:=string(content)
reg:=regexp.MustCompile("[\r\n]+")
array := reg.Split(str, -1)
for _,val:=range array{
//#;号开头的,作为注释
if strings.HasPrefix(val, "#") || strings.HasPrefix(val, ";"){
continue
}
if len(val) > 0{
kv := strings.Split(val, "|")
m:=make(map[string]interface{})
m["url"] = kv[0]
if len(kv) > 1{
m["duration"], _ = strconv.Atoi(kv[1])
} else {
m["duration"] = 10
}
if len(kv) > 2{
m["times"], _ = strconv.Atoi(kv[2])
} else {
m["times"] = 1
}
config = append(config, m)
}
}
t.Config = config;
return nil
}
type Task struct{
Times int
Duration int
Url string
Ch chan int
}
func NewTask(v map[string]interface{}) *Task{
c:=make(chan int,1)
return &Task{Times: v["times"].(int), Duration: v["duration"].(int), Url: v["url"].(string), Ch: c}
}
func (task *Task) Start(){
timer := time.NewTicker(time.Duration(task.Duration) * time.Second)
go func(c chan int){
if task.Times == 0{
forEnd1:
for {
select{
case <- timer.C:
http.Get(task.Url)
fmt.Println("task request url: "+task.Url)
case <-c:
break forEnd1
}
}
} else {
forEnd2:
for i := 0; i < task.Times; i ++{
select{
case <- timer.C:
http.Get(task.Url)
fmt.Println("task request url: "+task.Url)
case <- c:
break forEnd2
}
}
//执行完成后,需要销毁计时器
for k,v := range taskList{
if v == task{
if k == 0{
taskList = taskList[1:]
} else if (k + 1) == len(taskList){
taskList = taskList[:k]
} else {
taskList = append(taskList[k+1:], taskList[:k+2]...)
}
break
}
}
}
}(task.Ch)
}
func (task *Task) Stop(){
task.Ch <- 1
fmt.Println("---task stoped---")
}
func main() {
//控制台输入
reader:=bufio.NewReader(os.Stdin)
timer:=NewMyTimer()
ok:=timer.LoadConfigFile("config.txt")
if ok!=nil{
fmt.Println(ok)
// panic("error")
}
for{
fmt.Println("Enter a command :")
rawLine,_,_:=reader.ReadLine()
command:=string(rawLine)
if "q" == command || "quit" == command{
timer.Stop()
fmt.Println("bye")
break
} else if "start" == command{
timer.Start()
} else if "stop" == command{
timer.Stop()
} else if "restart" == command {
timer.Restart()
} else if "help" == command {
fmt.Println("****Welcome to use MyTimer****")
fmt.Println("There is commands and options:")
fmt.Println("start --start task jobs")
fmt.Println("stop --stop task jobs")
fmt.Println("restart --restart jobs")
fmt.Println("quit --quit the job task, also can use short command q")
fmt.Println("help --help infomation of MyTimer")
} else {
fmt.Println("Unknow command")
}
}
}
有疑问加站长微信联系(非本文作者)