mirror of https://github.com/ouqiang/gocron
feat($task): 增加任务标签
parent
250cbdde7c
commit
c4af1653ff
|
@ -49,21 +49,30 @@ func isDatabaseExist(name string) bool {
|
||||||
|
|
||||||
// 迭代升级数据库, 新建表、新增字段等
|
// 迭代升级数据库, 新建表、新增字段等
|
||||||
func (migration *Migration) Upgrade(oldVersionId int) {
|
func (migration *Migration) Upgrade(oldVersionId int) {
|
||||||
versionIds := []int{110}
|
// v1.2版本不支持升级
|
||||||
upgradeFuncs := []func(*xorm.Session) error {
|
if oldVersionId == 120 {
|
||||||
migration.upgradeFor110,
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// 默认当前版本为v1.0
|
versionIds := []int{110, 122}
|
||||||
startIndex := 0
|
upgradeFuncs := []func(*xorm.Session) error {
|
||||||
|
migration.upgradeFor110,
|
||||||
|
migration.upgradeFor122,
|
||||||
|
}
|
||||||
|
|
||||||
|
startIndex := -1
|
||||||
// 从当前版本的下一版本开始升级
|
// 从当前版本的下一版本开始升级
|
||||||
for i, value := range versionIds {
|
for i, value := range versionIds {
|
||||||
if oldVersionId == value {
|
if value > oldVersionId {
|
||||||
startIndex = i + 1
|
startIndex = i
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if startIndex == -1 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
length := len(versionIds)
|
length := len(versionIds)
|
||||||
if startIndex >= length {
|
if startIndex >= length {
|
||||||
return
|
return
|
||||||
|
@ -135,3 +144,16 @@ func (migration *Migration) upgradeFor110(session *xorm.Session) error {
|
||||||
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 升级到1.2.2版本
|
||||||
|
func (migration *Migration) upgradeFor122(session *xorm.Session) error {
|
||||||
|
logger.Info("开始升级到v1.2.2")
|
||||||
|
|
||||||
|
tableName := TablePrefix + "task"
|
||||||
|
// task表增加tag字段
|
||||||
|
_, err := session.Exec(fmt.Sprintf("ALTER TABLE %s ADD COLUMN tag VARCHAR(32) NOT NULL DEFAULT '' ", tableName))
|
||||||
|
|
||||||
|
logger.Info("已升级到v1.2.2\n")
|
||||||
|
|
||||||
|
return err
|
||||||
|
}
|
|
@ -44,6 +44,7 @@ type Task struct {
|
||||||
NotifyStatus int8 `xorm:"smallint notnull default 1"` // 任务执行结束是否通知 0: 不通知 1: 失败通知 2: 执行结束通知
|
NotifyStatus int8 `xorm:"smallint notnull default 1"` // 任务执行结束是否通知 0: 不通知 1: 失败通知 2: 执行结束通知
|
||||||
NotifyType int8 `xorm:"smallint notnull default 0"` // 通知类型 1: 邮件 2: slack
|
NotifyType int8 `xorm:"smallint notnull default 0"` // 通知类型 1: 邮件 2: slack
|
||||||
NotifyReceiverId string `xorm:"varchar(256) notnull default '' "` // 通知接受者ID, setting表主键ID,多个ID逗号分隔
|
NotifyReceiverId string `xorm:"varchar(256) notnull default '' "` // 通知接受者ID, setting表主键ID,多个ID逗号分隔
|
||||||
|
Tag string `xorm:"varchar(32) notnull default ''"`
|
||||||
Remark string `xorm:"varchar(100) notnull default ''"` // 备注
|
Remark string `xorm:"varchar(100) notnull default ''"` // 备注
|
||||||
Status Status `xorm:"tinyint notnull index default 0"` // 状态 1:正常 0:停止
|
Status Status `xorm:"tinyint notnull index default 0"` // 状态 1:正常 0:停止
|
||||||
Created time.Time `xorm:"datetime notnull created"` // 创建时间
|
Created time.Time `xorm:"datetime notnull created"` // 创建时间
|
||||||
|
@ -73,6 +74,7 @@ func (task *Task) CreateTestTask() {
|
||||||
task.Level = TaskLevelParent
|
task.Level = TaskLevelParent
|
||||||
task.Protocol = TaskHTTP
|
task.Protocol = TaskHTTP
|
||||||
task.Spec = "*/30 * * * * *"
|
task.Spec = "*/30 * * * * *"
|
||||||
|
task.Tag = "test-task"
|
||||||
// 查询IP地址区域信息
|
// 查询IP地址区域信息
|
||||||
task.Command = "http://ip.taobao.com/service/getIpInfo.php?ip=117.27.140.253"
|
task.Command = "http://ip.taobao.com/service/getIpInfo.php?ip=117.27.140.253"
|
||||||
task.Status = Enabled
|
task.Status = Enabled
|
||||||
|
@ -81,7 +83,7 @@ func (task *Task) CreateTestTask() {
|
||||||
|
|
||||||
func (task *Task) UpdateBean(id int) (int64, error) {
|
func (task *Task) UpdateBean(id int) (int64, error) {
|
||||||
return Db.ID(id).
|
return Db.ID(id).
|
||||||
Cols("name,spec,protocol,command,timeout,multi,retry_times,remark,notify_status,notify_type,notify_receiver_id, dependency_task_id, dependency_status").
|
Cols("name,spec,protocol,command,timeout,multi,retry_times,remark,notify_status,notify_type,notify_receiver_id, dependency_task_id, dependency_status, tag").
|
||||||
Update(task)
|
Update(task)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -261,5 +263,10 @@ func (task *Task) parseWhere(session *xorm.Session, params CommonMap) {
|
||||||
if ok && status.(int) > -1 {
|
if ok && status.(int) > -1 {
|
||||||
session.And("status = ?", status)
|
session.And("status = ?", status)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tag, ok := params["Tag"]
|
||||||
|
if ok && tag.(string) != "" {
|
||||||
|
session.And("tag = ? ", tag)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -120,6 +120,10 @@ func writeConfig(form InstallForm) error {
|
||||||
"app.name", "定时任务管理系统", // 应用名称
|
"app.name", "定时任务管理系统", // 应用名称
|
||||||
"api.key", "",
|
"api.key", "",
|
||||||
"api.secret", "",
|
"api.secret", "",
|
||||||
|
"enable_tls", "false",
|
||||||
|
"ca_file", "",
|
||||||
|
"cert_file", "",
|
||||||
|
"key_file", "",
|
||||||
}
|
}
|
||||||
|
|
||||||
return setting.Write(dbConfig, app.AppConfig)
|
return setting.Write(dbConfig, app.AppConfig)
|
||||||
|
|
|
@ -29,6 +29,7 @@ type TaskForm struct {
|
||||||
Multi int8 `binding:"In(1,2)"`
|
Multi int8 `binding:"In(1,2)"`
|
||||||
RetryTimes int8
|
RetryTimes int8
|
||||||
HostId string
|
HostId string
|
||||||
|
Tag string
|
||||||
Remark string
|
Remark string
|
||||||
NotifyStatus int8 `binding:"In(1,2,3)"`
|
NotifyStatus int8 `binding:"In(1,2,3)"`
|
||||||
NotifyType int8 `binding:"In(1,2,3)"`
|
NotifyType int8 `binding:"In(1,2,3)"`
|
||||||
|
@ -63,8 +64,8 @@ func Index(ctx *macaron.Context) {
|
||||||
if ok {
|
if ok {
|
||||||
safeNameHTML = template.HTMLEscapeString(name)
|
safeNameHTML = template.HTMLEscapeString(name)
|
||||||
}
|
}
|
||||||
PageParams := fmt.Sprintf("id=%d&host_id=%d&name=%s&protocol=%d&status=%d&page_size=%d",
|
PageParams := fmt.Sprintf("id=%d&host_id=%d&name=%s&protocol=%d&tag=%s&status=%d&page_size=%d",
|
||||||
queryParams["Id"], queryParams["HostId"], safeNameHTML, queryParams["Protocol"], queryParams["Status"], queryParams["PageSize"]);
|
queryParams["Id"], queryParams["HostId"], safeNameHTML, queryParams["Protocol"], queryParams["Tag"], queryParams["Status"], queryParams["PageSize"]);
|
||||||
queryParams["PageParams"] = template.URL(PageParams)
|
queryParams["PageParams"] = template.URL(PageParams)
|
||||||
p := paginater.New(int(total), queryParams["PageSize"].(int), queryParams["Page"].(int), 5)
|
p := paginater.New(int(total), queryParams["PageSize"].(int), queryParams["Page"].(int), 5)
|
||||||
ctx.Data["Pagination"] = p
|
ctx.Data["Pagination"] = p
|
||||||
|
@ -131,6 +132,7 @@ func Store(ctx *macaron.Context, form TaskForm) string {
|
||||||
taskModel.Protocol = form.Protocol
|
taskModel.Protocol = form.Protocol
|
||||||
taskModel.Command = form.Command
|
taskModel.Command = form.Command
|
||||||
taskModel.Timeout = form.Timeout
|
taskModel.Timeout = form.Timeout
|
||||||
|
taskModel.Tag = form.Tag
|
||||||
taskModel.Remark = form.Remark
|
taskModel.Remark = form.Remark
|
||||||
taskModel.Multi = form.Multi
|
taskModel.Multi = form.Multi
|
||||||
taskModel.RetryTimes = form.RetryTimes
|
taskModel.RetryTimes = form.RetryTimes
|
||||||
|
@ -301,6 +303,7 @@ func parseQueryParams(ctx *macaron.Context) (models.CommonMap) {
|
||||||
params["HostId"] = ctx.QueryInt("host_id")
|
params["HostId"] = ctx.QueryInt("host_id")
|
||||||
params["Name"] = ctx.QueryTrim("name")
|
params["Name"] = ctx.QueryTrim("name")
|
||||||
params["Protocol"] = ctx.QueryInt("protocol")
|
params["Protocol"] = ctx.QueryInt("protocol")
|
||||||
|
params["Tag"] = ctx.QueryTrim("tag")
|
||||||
status := ctx.QueryInt("status")
|
status := ctx.QueryInt("status")
|
||||||
if status >=0 {
|
if status >=0 {
|
||||||
status -= 1
|
status -= 1
|
||||||
|
|
|
@ -14,9 +14,6 @@ import (
|
||||||
rpcClient "github.com/ouqiang/gocron/modules/rpc/client"
|
rpcClient "github.com/ouqiang/gocron/modules/rpc/client"
|
||||||
pb "github.com/ouqiang/gocron/modules/rpc/proto"
|
pb "github.com/ouqiang/gocron/modules/rpc/proto"
|
||||||
"strings"
|
"strings"
|
||||||
"text/template"
|
|
||||||
"bytes"
|
|
||||||
"encoding/base64"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// 定时任务调度管理器
|
// 定时任务调度管理器
|
||||||
|
@ -304,9 +301,6 @@ func beforeExecJob(taskModel models.Task) (taskLogId int64) {
|
||||||
|
|
||||||
// 任务执行后置操作
|
// 任务执行后置操作
|
||||||
func afterExecJob(taskModel models.Task, taskResult TaskResult, taskLogId int64) {
|
func afterExecJob(taskModel models.Task, taskResult TaskResult, taskLogId int64) {
|
||||||
if taskResult.Err != nil {
|
|
||||||
taskResult.Result = taskResult.Err.Error() + "\n" + taskResult.Result
|
|
||||||
}
|
|
||||||
_, err := updateTaskLog(taskLogId, taskResult)
|
_, err := updateTaskLog(taskLogId, taskResult)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Error("任务结束#更新任务日志失败-", err)
|
logger.Error("任务结束#更新任务日志失败-", err)
|
||||||
|
@ -349,39 +343,11 @@ func execDependencyTask(taskModel models.Task, taskResult TaskResult) {
|
||||||
}
|
}
|
||||||
serviceTask := new(Task)
|
serviceTask := new(Task)
|
||||||
for _, task := range tasks {
|
for _, task := range tasks {
|
||||||
task.Command = appendResultToCommand(task.Command, taskResult)
|
|
||||||
task.Spec = fmt.Sprintf("依赖任务(主任务ID-%d)", taskModel.Id)
|
task.Spec = fmt.Sprintf("依赖任务(主任务ID-%d)", taskModel.Id)
|
||||||
serviceTask.Run(task)
|
serviceTask.Run(task)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 添加主任务执行结果到子任务命令中, 占位符{{.Code}} {{.Message}}
|
|
||||||
*/
|
|
||||||
func appendResultToCommand(command string, taskResult TaskResult) string {
|
|
||||||
var code int8 = 0
|
|
||||||
if taskResult.Err != nil {
|
|
||||||
code = 1
|
|
||||||
}
|
|
||||||
data := map[string]interface{} {
|
|
||||||
"Code": code,
|
|
||||||
"Message": base64.StdEncoding.EncodeToString([]byte(taskResult.Result)),
|
|
||||||
}
|
|
||||||
var buf *bytes.Buffer = new(bytes.Buffer)
|
|
||||||
tmpl, err := template.New("command").Parse(command)
|
|
||||||
if err != nil {
|
|
||||||
logger.Errorf("替换子任务命令占位符失败#%s", err.Error())
|
|
||||||
return command
|
|
||||||
}
|
|
||||||
err = tmpl.Execute(buf, data)
|
|
||||||
if err != nil {
|
|
||||||
logger.Errorf("替换子任务命令占位符失败#%s", err.Error())
|
|
||||||
return command
|
|
||||||
}
|
|
||||||
|
|
||||||
return buf.String()
|
|
||||||
}
|
|
||||||
|
|
||||||
// 发送任务结果通知
|
// 发送任务结果通知
|
||||||
func SendNotification(taskModel models.Task, taskResult TaskResult) {
|
func SendNotification(taskModel models.Task, taskResult TaskResult) {
|
||||||
var statusName string
|
var statusName string
|
||||||
|
|
|
@ -22,6 +22,11 @@
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<input type="text" placeholder="任务名称" name="name" value="{{{.Params.Name}}}">
|
<input type="text" placeholder="任务名称" name="name" value="{{{.Params.Name}}}">
|
||||||
</div>
|
</div>
|
||||||
|
<div class="field">
|
||||||
|
<input type="text" placeholder="标签名称" name="tag" value="{{{.Params.Tag}}}">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="six fields search">
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<select name="host_id" id="hostId">
|
<select name="host_id" id="hostId">
|
||||||
<option value="">选择节点</option>
|
<option value="">选择节点</option>
|
||||||
|
@ -67,6 +72,7 @@
|
||||||
<th>任务ID</th>
|
<th>任务ID</th>
|
||||||
<th>任务名称</th>
|
<th>任务名称</th>
|
||||||
<th>任务类型</th>
|
<th>任务类型</th>
|
||||||
|
<th>标签</th>
|
||||||
<th>cron表达式</th>
|
<th>cron表达式</th>
|
||||||
<th>执行方式</th>
|
<th>执行方式</th>
|
||||||
<th>超时时间</th>
|
<th>超时时间</th>
|
||||||
|
@ -89,6 +95,7 @@
|
||||||
<td>{{{.Id}}}</td>
|
<td>{{{.Id}}}</td>
|
||||||
<td>{{{.Name}}}</td>
|
<td>{{{.Name}}}</td>
|
||||||
<td>{{{if eq .Level 1}}}主任务{{{else}}}子任务{{{end}}}</td>
|
<td>{{{if eq .Level 1}}}主任务{{{else}}}子任务{{{end}}}</td>
|
||||||
|
<td>{{{.Tag}}}</td>
|
||||||
<td>{{{.Spec}}}</td>
|
<td>{{{.Spec}}}</td>
|
||||||
<td>{{{if eq .Protocol 1}}} HTTP {{{else if eq .Protocol 2}}} SHELL {{{end}}}</td>
|
<td>{{{if eq .Protocol 1}}} HTTP {{{else if eq .Protocol 2}}} SHELL {{{end}}}</td>
|
||||||
<td>{{{if eq .Timeout -1}}}后台运行{{{else if gt .Timeout 0}}}{{{.Timeout}}}秒{{{else}}}不限制{{{end}}}</td>
|
<td>{{{if eq .Timeout -1}}}后台运行{{{else if gt .Timeout 0}}}{{{.Timeout}}}秒{{{else}}}不限制{{{end}}}</td>
|
||||||
|
|
|
@ -22,6 +22,15 @@
|
||||||
<input type="text" name="name" placeholder="任务名称" value="{{{.Task.Name}}}">
|
<input type="text" name="name" placeholder="任务名称" value="{{{.Task.Name}}}">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="field">
|
||||||
|
<label>
|
||||||
|
<div class="content">标签名称</div>
|
||||||
|
</label>
|
||||||
|
<div class="ui small input">
|
||||||
|
<input type="text" name="tag" placeholder="标签用于任务分类" value="{{{.Task.Tag}}}">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="two fields">
|
<div class="two fields">
|
||||||
<div class="field">
|
<div class="field">
|
||||||
|
|
Loading…
Reference in New Issue