作者:无心少年丶的诱惑 | 来源:互联网 | 2023-05-18 06:07
package main
import (
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
"os"
"os/exec"
"sync"
"time"
)
type Task struct {
Id string `json:"id"`
Cmd string `json:"cmd,omitempty"`
Args []string `json:"args,omitempty"`
Interval int `json:"interval,omitempty"`
stop chan struct{}
}
func (task *Task) Start() {
go func() {
label:
for {
select {
case <-time.After(time.Duration(task.Interval) * time.Millisecond):
cmd := exec.Command(task.Cmd, task.Args...)
cmd.Stdout = os.Stdout
cmd.Run()
case <-task.stop:
break label
}
}
}()
}
func (task *Task) Stop() {
task.stop <- struct{}{}
}
type Response struct {
Ok bool `json:"ok"`
Id string `json:"id,omitempty"`
Error string `json:"error,omitempty"`
}
var cron Cron
type Cron struct {
mutex sync.Mutex
jobs map[string]*Task
}
func cronManager(w http.ResponseWriter, req *http.Request) {
defer req.Body.Close()
var task Task
cont, _ := ioutil.ReadAll(req.Body)
json.Unmarshal(cont, &task)
reqTaskId := task.Id
cron.mutex.Lock()
defer cron.mutex.Unlock()
if req.Method == "POST" {
if _, ok := cron.jobs[reqTaskId]; ok {
response := Response{
Ok: false, Error: "The task " + reqTaskId + " already exists.",
}
cont, _ = json.Marshal(response)
w.WriteHeader(409)
w.Write(cont)
} else {
task.stop = make(chan struct{})
cron.jobs[task.Id] = &task
task.Start()
response := Response{
Ok: true, Id: task.Id,
}
cont, _ = json.Marshal(response)
w.WriteHeader(200)
w.Write(cont)
}
}
if req.Method == "DELETE" {
if task, ok := cron.jobs[task.Id]; ok {
delete(cron.jobs, task.Id)
task.Stop()
response := Response{Ok: true, Id: task.Id}
cont, _ = json.Marshal(response)
w.WriteHeader(200)
w.Write(cont)
} else {
response := Response{
Ok: false, Error: "The task " + reqTaskId + " is not found.",
}
cont, _ = json.Marshal(response)
w.WriteHeader(404)
w.Write(cont)
}
}
}
func main() {
if len(os.Args) != 2 {
fmt.Println("usage: ./gocron port")
return
}
fmt.Println("GoCron listening on 4567")
cron.jobs = make(map[string]*Task)
http.HandleFunc("/", cronManager)
http.ListenAndServe(":"+os.Args[1], nil)
}