2024-03-31 20:09:20 +08:00
|
|
|
package model
|
|
|
|
|
|
|
|
import (
|
|
|
|
"encoding/json"
|
|
|
|
"github.com/loveuer/nfflow/internal/sqlType"
|
2024-04-02 18:12:02 +08:00
|
|
|
"github.com/samber/lo"
|
|
|
|
"github.com/sirupsen/logrus"
|
|
|
|
"gorm.io/gorm"
|
2024-03-31 20:09:20 +08:00
|
|
|
)
|
|
|
|
|
|
|
|
type InputType int64
|
|
|
|
|
|
|
|
const (
|
|
|
|
InputTypeES InputType = iota + 1
|
|
|
|
InputTypePG
|
|
|
|
InputTypeMQ
|
|
|
|
)
|
|
|
|
|
|
|
|
type OutputType int64
|
|
|
|
|
|
|
|
const (
|
|
|
|
OutputTypeES OutputType = iota + 1
|
|
|
|
OutputTypeFile
|
|
|
|
OutputTypeMQ
|
|
|
|
)
|
|
|
|
|
2024-04-02 18:12:02 +08:00
|
|
|
type PipeType int64
|
|
|
|
|
|
|
|
func (p PipeType) Value() int64 { return int64(p) }
|
|
|
|
|
|
|
|
func (p PipeType) Code() string {
|
|
|
|
switch p {
|
|
|
|
case PipeTypeLoadashMap:
|
|
|
|
return "pipe_map"
|
|
|
|
default:
|
|
|
|
return "unknown"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (p PipeType) Label() string {
|
|
|
|
switch p {
|
|
|
|
case PipeTypeLoadashMap:
|
|
|
|
return "Map"
|
|
|
|
default:
|
|
|
|
return "未知"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (p PipeType) MarshalJSON() ([]byte, error) {
|
|
|
|
return json.Marshal(map[string]any{"value": p.Value(), "code": p.Code(), "label": p.Label()})
|
|
|
|
}
|
|
|
|
|
|
|
|
func (p PipeType) All() []Enum {
|
|
|
|
return []Enum{PipeTypeLoadashMap}
|
|
|
|
}
|
|
|
|
|
|
|
|
const (
|
|
|
|
PipeTypeLoadashMap PipeType = iota + 1
|
|
|
|
)
|
|
|
|
|
|
|
|
var _ Enum = PipeType(0)
|
|
|
|
|
2024-03-31 20:09:20 +08:00
|
|
|
type TaskStatus int64
|
|
|
|
|
|
|
|
func (t TaskStatus) MarshalJSON() ([]byte, error) {
|
|
|
|
return json.Marshal(map[string]any{
|
|
|
|
"value": t.Value(),
|
|
|
|
"code": t.Code(),
|
|
|
|
"label": t.Label(),
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
func (t TaskStatus) All() []Enum {
|
|
|
|
return []Enum{
|
|
|
|
TaskStatusNotReady,
|
|
|
|
TaskStatusReady,
|
|
|
|
TaskStatusRunning,
|
|
|
|
TaskStatusSucceed,
|
|
|
|
TaskStatusFailed,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
var _ Enum = TaskStatus(0)
|
|
|
|
|
|
|
|
const (
|
|
|
|
TaskStatusNotReady TaskStatus = iota
|
|
|
|
TaskStatusReady
|
|
|
|
TaskStatusRunning
|
|
|
|
TaskStatusSucceed
|
|
|
|
TaskStatusFailed
|
|
|
|
)
|
|
|
|
|
|
|
|
func (t TaskStatus) Value() int64 {
|
|
|
|
return int64(t)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (t TaskStatus) Code() string {
|
|
|
|
switch t {
|
|
|
|
case TaskStatusNotReady:
|
|
|
|
return "not_ready"
|
|
|
|
case TaskStatusReady:
|
|
|
|
return "ready"
|
|
|
|
case TaskStatusRunning:
|
|
|
|
return "running"
|
|
|
|
case TaskStatusSucceed:
|
|
|
|
return "succeed"
|
|
|
|
case TaskStatusFailed:
|
|
|
|
return "failed"
|
|
|
|
default:
|
|
|
|
return "unknown"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (t TaskStatus) Label() string {
|
|
|
|
switch t {
|
|
|
|
case TaskStatusNotReady:
|
|
|
|
return "未完善"
|
|
|
|
case TaskStatusReady:
|
|
|
|
return "等待执行"
|
|
|
|
case TaskStatusRunning:
|
|
|
|
return "执行中"
|
|
|
|
case TaskStatusSucceed:
|
|
|
|
return "执行成功"
|
|
|
|
case TaskStatusFailed:
|
|
|
|
return "执行失败"
|
|
|
|
default:
|
|
|
|
return "未知"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-04-01 18:13:10 +08:00
|
|
|
type TaskRunType int64
|
|
|
|
|
|
|
|
const (
|
|
|
|
TaskRunTypeOnce TaskRunType = iota
|
|
|
|
TaskRunTypeTiming
|
|
|
|
TaskRunTypeCron
|
|
|
|
)
|
|
|
|
|
|
|
|
func (t TaskRunType) Value() int64 { return int64(t) }
|
|
|
|
|
|
|
|
func (t TaskRunType) Code() string {
|
|
|
|
switch t {
|
|
|
|
case TaskRunTypeOnce:
|
|
|
|
return "once"
|
|
|
|
case TaskRunTypeTiming:
|
|
|
|
return "timing"
|
|
|
|
case TaskRunTypeCron:
|
|
|
|
return "cron"
|
|
|
|
default:
|
|
|
|
return "unknown"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (t TaskRunType) Label() string {
|
|
|
|
switch t {
|
|
|
|
case TaskRunTypeOnce:
|
|
|
|
return "手动执行"
|
|
|
|
case TaskRunTypeTiming:
|
|
|
|
return "定时执行"
|
|
|
|
case TaskRunTypeCron:
|
|
|
|
return "周期执行"
|
|
|
|
default:
|
|
|
|
return "未知"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (t TaskRunType) MarshalJSON() ([]byte, error) {
|
|
|
|
return json.Marshal(map[string]any{"code": t.Code(), "value": t.Value(), "label": t.Label()})
|
|
|
|
}
|
|
|
|
|
|
|
|
func (t TaskRunType) All() []Enum {
|
|
|
|
return []Enum{TaskRunTypeOnce, TaskRunTypeTiming, TaskRunTypeCron}
|
|
|
|
}
|
|
|
|
|
|
|
|
var _ Enum = TaskRunType(0)
|
|
|
|
|
2024-03-31 20:09:20 +08:00
|
|
|
type Task struct {
|
|
|
|
Id uint64 `json:"id" gorm:"primaryKey;column:id"`
|
|
|
|
CreatedAt int64 `json:"created_at" gorm:"column:created_at;autoCreateTime:milli"`
|
|
|
|
UpdatedAt int64 `json:"updated_at" gorm:"column:updated_at;autoUpdateTime:milli"`
|
|
|
|
DeletedAt int64 `json:"deleted_at" gorm:"index;column:deleted_at;default:0"`
|
|
|
|
|
2024-04-01 18:13:10 +08:00
|
|
|
TaskName string `json:"task_name" gorm:"column:task_name;type:varchar(256)"`
|
|
|
|
TaskRunType TaskRunType `json:"task_run_type" gorm:"column:task_run_type;type:varchar(16);default:0"` // cron: C-"cron syntax", "once", timestamp: T-1234567890123 毫秒时间戳
|
|
|
|
TaskRunAt int64 `json:"task_run_at" gorm:"column:task_run_at"`
|
|
|
|
TaskCron string `json:"task_cron" gorm:"column:task_cron;type:varchar(32)"`
|
|
|
|
TaskTimeout int `json:"task_timeout" gorm:"column:task_timeout"`
|
|
|
|
TaskStatus TaskStatus `json:"task_status" gorm:"column:task_status"`
|
|
|
|
TaskLog string `json:"task_log" gorm:"task_log"`
|
2024-03-31 20:09:20 +08:00
|
|
|
}
|
|
|
|
|
2024-04-02 18:12:02 +08:00
|
|
|
type TaskInput struct {
|
|
|
|
Id uint64 `json:"id" gorm:"primaryKey;column:id"`
|
|
|
|
TaskId uint64 `json:"task_id" gorm:"column:task_id"`
|
|
|
|
Type InputType `json:"type" gorm:"column:type"`
|
|
|
|
Config sqlType.JSONB `json:"config" gorm:"config"`
|
2024-03-31 20:09:20 +08:00
|
|
|
}
|
|
|
|
|
2024-04-02 18:12:02 +08:00
|
|
|
func (t *Task) GetInput(tx *gorm.DB) (*TaskInput, error) {
|
|
|
|
var (
|
|
|
|
err error
|
|
|
|
ti = new(TaskInput)
|
|
|
|
)
|
|
|
|
|
|
|
|
if err = tx.Model(&TaskInput{}).
|
|
|
|
Where("task_id", t.Id).
|
|
|
|
Take(ti).
|
|
|
|
Error; err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return ti, nil
|
2024-03-31 20:09:20 +08:00
|
|
|
}
|
|
|
|
|
2024-04-02 18:12:02 +08:00
|
|
|
type TaskOutput struct {
|
|
|
|
Id uint64 `json:"id" gorm:"primaryKey;column:id"`
|
|
|
|
TaskId uint64 `json:"task_id" gorm:"column:task_id"`
|
|
|
|
Type OutputType `json:"type" gorm:"column:type"`
|
|
|
|
Config sqlType.JSONB `json:"config" gorm:"config"`
|
|
|
|
}
|
|
|
|
|
|
|
|
func (t *Task) GetOutputs(tx *gorm.DB) ([]*TaskOutput, error) {
|
|
|
|
var (
|
|
|
|
err error
|
|
|
|
outputs = make([]*TaskOutput, 0)
|
|
|
|
)
|
|
|
|
|
|
|
|
if err = tx.Model(&TaskOutput{}).
|
|
|
|
Where("task_id", t.Id).
|
|
|
|
Find(&outputs).
|
|
|
|
Error; err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return outputs, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
type TaskPipe struct {
|
|
|
|
Id uint64 `json:"id" gorm:"primaryKey;column:id"`
|
|
|
|
TaskId uint64 `json:"task_id" gorm:"column:task_id"`
|
|
|
|
Pid uint64 `json:"pid" gorm:"column:pid"`
|
|
|
|
Type PipeType `json:"type" gorm:"column:type"`
|
|
|
|
Config sqlType.JSONB `json:"config" gorm:"config"`
|
|
|
|
Next []*TaskPipe `json:"next" gorm:"-"`
|
|
|
|
}
|
|
|
|
|
|
|
|
func (t *Task) GetPipes(tx *gorm.DB) ([]*TaskPipe, error) {
|
|
|
|
var (
|
|
|
|
err error
|
|
|
|
list = make([]*TaskPipe, 0)
|
|
|
|
)
|
|
|
|
|
|
|
|
if err = tx.Model(&TaskPipe{}).
|
|
|
|
Where("task_id", t.Id).
|
|
|
|
Find(&list).
|
|
|
|
Error; err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
m := lo.SliceToMap(list, func(item *TaskPipe) (uint64, *TaskPipe) {
|
|
|
|
item.Next = make([]*TaskPipe, 0)
|
|
|
|
return item.Id, item
|
|
|
|
})
|
|
|
|
|
|
|
|
m[0] = &TaskPipe{Next: make([]*TaskPipe, 0)}
|
|
|
|
|
|
|
|
for idx := range list {
|
|
|
|
x := list[idx]
|
|
|
|
if _, exist := m[x.Pid]; !exist {
|
|
|
|
logrus.Warnf("GetPipes: pipe=[task_id=%d id=%d pid=%d type=%s] pid not found", x.TaskId, x.Id, x.Pid, x.Type.Code())
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
|
|
|
m[x.Pid].Next = append(m[x.Pid].Next, x)
|
|
|
|
}
|
|
|
|
|
|
|
|
return m[0].Next, nil
|
2024-03-31 20:09:20 +08:00
|
|
|
}
|