158 lines
3.3 KiB
Go
158 lines
3.3 KiB
Go
package zsub
|
||
|
||
import (
|
||
"bytes"
|
||
"database/sql"
|
||
"fmt"
|
||
_ "github.com/go-sql-driver/mysql"
|
||
"github.com/robfig/cron"
|
||
"log"
|
||
"os/exec"
|
||
"strings"
|
||
"text/template"
|
||
)
|
||
|
||
type ZTimer struct {
|
||
conns []*ZConn
|
||
expr string
|
||
topic string
|
||
cron *cron.Cron
|
||
single bool
|
||
}
|
||
|
||
/*
|
||
["timer", topic, expr, a|x]
|
||
*/
|
||
func (s *ZSub) timer(rcmd []string, c *ZConn) {
|
||
s.Lock()
|
||
defer s.Unlock()
|
||
timer := s.timers[rcmd[1]]
|
||
if timer == nil {
|
||
timer = &ZTimer{
|
||
conns: []*ZConn{},
|
||
topic: rcmd[1],
|
||
}
|
||
s.timers[rcmd[1]] = timer
|
||
}
|
||
if c != nil {
|
||
timer.conns = c.appendTo(timer.conns)
|
||
}
|
||
|
||
// todo: when timer.expr changed send message to all the timer‘s subscribe
|
||
if len(rcmd) == 4 && !strings.EqualFold(timer.expr, rcmd[2]) {
|
||
timer.expr = rcmd[2]
|
||
if timer.cron != nil {
|
||
timer.cron.Stop()
|
||
}
|
||
timer.cron = func() *cron.Cron {
|
||
c := cron.New()
|
||
c.AddFunc(timer.expr, func() {
|
||
for _, conn := range timer.conns {
|
||
err := send(conn.conn, "timer", timer.topic)
|
||
if timer.single && err == nil {
|
||
break
|
||
}
|
||
}
|
||
})
|
||
go c.Run()
|
||
return c
|
||
}()
|
||
timer.configSave()
|
||
}
|
||
if len(rcmd) == 4 && (strings.EqualFold("a", rcmd[3]) != timer.single) {
|
||
timer.single = strings.EqualFold("a", rcmd[3])
|
||
timer.configSave()
|
||
}
|
||
|
||
s.timers[rcmd[1]] = timer
|
||
}
|
||
|
||
func (t *ZTimer) close(c *ZConn) {
|
||
for i, item := range t.conns {
|
||
if item.conn == c.conn {
|
||
t.conns = append(t.conns[:i], t.conns[i+1:]...)
|
||
}
|
||
}
|
||
}
|
||
|
||
func (t *ZTimer) configSave() {
|
||
tpl, err := template.New("").Parse(`
|
||
if [ ! -d "/etc/zhub" ]; then
|
||
mkdir /etc/zhub
|
||
fi
|
||
if [ ! -f "/etc/zhub/ztimer.cron" ]; then
|
||
touch /etc/zhub/ztimer.cron
|
||
fi
|
||
|
||
sed -i /^{{.Name}}\|*/d /etc/zhub/ztimer.cron
|
||
echo '{{.Name}}|{{.Expr}}|{{.Single}}' >> /etc/zhub/ztimer.cron
|
||
`)
|
||
|
||
if err != nil {
|
||
log.Println(err)
|
||
}
|
||
|
||
var buf bytes.Buffer
|
||
err = tpl.Execute(&buf, map[string]string{
|
||
"Name": t.topic,
|
||
"Expr": t.expr,
|
||
"Single": func() string {
|
||
if t.single {
|
||
return "a"
|
||
} else {
|
||
return "x"
|
||
}
|
||
}(),
|
||
})
|
||
if err != nil {
|
||
log.Println(err)
|
||
}
|
||
|
||
//fmt.Println(buf.String())
|
||
|
||
rest, err, s := executeShell(buf.String())
|
||
if err != nil {
|
||
log.Println(err)
|
||
}
|
||
if !strings.EqualFold(rest, "") {
|
||
fmt.Println("res:", rest)
|
||
}
|
||
if !strings.EqualFold(s, "") {
|
||
fmt.Println("error-rest:", s)
|
||
}
|
||
}
|
||
|
||
func executeShell(command string) (string, error, string) {
|
||
var stdout bytes.Buffer
|
||
var stderr bytes.Buffer
|
||
cmd := exec.Command("/bin/bash", "-c", command)
|
||
cmd.Stdout = &stdout
|
||
cmd.Stderr = &stderr
|
||
err := cmd.Run()
|
||
return stdout.String(), err, stderr.String()
|
||
}
|
||
|
||
func (s *ZSub) reloadTimerConfig() {
|
||
db, err := sql.Open("mysql", "root:*Zhong123098!@tcp(47.111.150.118:6063)/platf_oth?charset=utf8") // dev
|
||
//db, err := sql.Open("mysql", "root:*Hello@27.com!@tcp(0.0.0.0:6033)/platf_oth?charset=utf8") // qc
|
||
//db, err := sql.Open("mysql", "root:*Hello@27.com!@tcp(122.112.180.156:6033)/platf_oth?charset=utf8") // pro
|
||
if err != nil {
|
||
log.Println(err)
|
||
return
|
||
}
|
||
defer db.Close()
|
||
|
||
rows, err := db.Query("SELECT t.`name`,t.`expr`,IF(t.`single`=1,'a','x') 'single' FROM tasktimer t WHERE t.`status`=10 ORDER BY t.`timerid`")
|
||
if err != nil {
|
||
log.Println(err)
|
||
}
|
||
|
||
for rows.Next() {
|
||
var name string
|
||
var expr string
|
||
var single string
|
||
rows.Scan(&name, &expr, &single)
|
||
s.timer([]string{"timer", name, expr, single}, nil) //["timer", topic, expr, a|x]
|
||
}
|
||
}
|