next-terminal/pkg/model/job.go
2021-02-28 23:56:25 +08:00

230 lines
5.3 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package model
import (
"errors"
"github.com/robfig/cron/v3"
"github.com/sirupsen/logrus"
"next-terminal/pkg/global"
"next-terminal/pkg/utils"
"strconv"
"time"
)
const (
JobStatusRunning = "running"
JobStatusNotRunning = "not-running"
FuncCheckAssetStatusJob = "check-asset-status-job"
FuncDelUnUsedSessionJob = "del-unused-session-job"
FuncDelTimeoutSessionJob = "del-timeout-session-job"
)
type Job struct {
ID string `gorm:"primary_key" json:"id"`
JobId int `json:"jobId"`
Name string `json:"name"`
Func string `json:"func"`
Cron string `json:"cron"`
Status string `json:"status"`
Created utils.JsonTime `json:"created"`
Updated utils.JsonTime `json:"updated"`
}
func (r *Job) TableName() string {
return "jobs"
}
func FindPageJob(pageIndex, pageSize int, name, status string) (o []Job, total int64, err error) {
job := Job{}
db := global.DB.Table(job.TableName())
dbCounter := global.DB.Table(job.TableName())
if len(name) > 0 {
db = db.Where("name like ?", "%"+name+"%")
dbCounter = dbCounter.Where("name like ?", "%"+name+"%")
}
if len(status) > 0 {
db = db.Where("status = ?", status)
dbCounter = dbCounter.Where("status = ?", status)
}
err = dbCounter.Count(&total).Error
if err != nil {
return nil, 0, err
}
err = db.Order("created desc").Find(&o).Offset((pageIndex - 1) * pageSize).Limit(pageSize).Error
if o == nil {
o = make([]Job, 0)
}
return
}
func FindJobByFunc(function string) (o []Job, err error) {
db := global.DB
err = db.Where("func = ?", function).Find(&o).Error
return
}
func CreateNewJob(o *Job) (err error) {
if o.Status == JobStatusRunning {
j, err := getJob(o.ID, o.Func)
if err != nil {
return err
}
jobId, err := global.Cron.AddJob(o.Cron, j)
if err != nil {
return err
}
o.JobId = int(jobId)
}
return global.DB.Create(o).Error
}
func UpdateJobById(o *Job, id string) (err error) {
if o.Status == JobStatusRunning {
return errors.New("请先停止定时任务后再修改")
}
return global.DB.Where("id = ?", id).Updates(o).Error
}
func UpdateJonUpdatedById(id string) (err error) {
err = global.DB.Where("id = ?", id).Update("updated = ?", utils.NowJsonTime()).Error
return
}
func ChangeJobStatusById(id, status string) (err error) {
var job Job
err = global.DB.Where("id = ?", id).First(&job).Error
if err != nil {
return err
}
if status == JobStatusNotRunning {
j, err := getJob(job.ID, job.Func)
if err != nil {
return err
}
entryID, err := global.Cron.AddJob(job.Cron, j)
if err != nil {
return err
}
job.JobId = int(entryID)
return global.DB.Where("id = ?", id).Update("status = ?", JobStatusRunning).Error
} else {
global.Cron.Remove(cron.EntryID(job.JobId))
return global.DB.Where("id = ?", id).Update("status = ?", JobStatusNotRunning).Error
}
}
func FindJobById(id string) (o Job, err error) {
err = global.DB.Where("id = ?").First(&o).Error
return
}
func DeleteJobById(id string) error {
job, err := FindJobById(id)
if err != nil {
return err
}
if job.Status == JobStatusRunning {
if err := ChangeJobStatusById(JobStatusNotRunning, id); err != nil {
return err
}
}
return global.DB.Where("id = ?").Delete(Job{}).Error
}
func getJob(id, function string) (job cron.Job, err error) {
switch function {
case FuncCheckAssetStatusJob:
job = CheckAssetStatusJob{ID: id}
case FuncDelUnUsedSessionJob:
job = DelUnUsedSessionJob{ID: id}
case FuncDelTimeoutSessionJob:
job = DelTimeoutSessionJob{ID: id}
default:
return nil, errors.New("未识别的任务")
}
return job, err
}
type CheckAssetStatusJob struct {
ID string
}
func (r CheckAssetStatusJob) Run() {
assets, _ := FindAllAsset()
if assets != nil && len(assets) > 0 {
for i := range assets {
asset := assets[i]
active := utils.Tcping(asset.IP, asset.Port)
UpdateAssetActiveById(active, asset.ID)
logrus.Infof("资产「%v」ID「%v」存活状态检测完成存活「%v」。", asset.Name, asset.ID, active)
}
}
if r.ID != "" {
_ = UpdateJonUpdatedById(r.ID)
}
}
type DelUnUsedSessionJob struct {
ID string
}
func (r DelUnUsedSessionJob) Run() {
sessions, _ := FindSessionByStatusIn([]string{NoConnect, Connecting})
if sessions != nil && len(sessions) > 0 {
now := time.Now()
for i := range sessions {
if now.Sub(sessions[i].ConnectedTime.Time) > time.Hour*1 {
_ = DeleteSessionById(sessions[i].ID)
s := sessions[i].Username + "@" + sessions[i].IP + ":" + strconv.Itoa(sessions[i].Port)
logrus.Infof("会话「%v」ID「%v」超过1小时未打开已删除。", s, sessions[i].ID)
}
}
}
if r.ID != "" {
_ = UpdateJonUpdatedById(r.ID)
}
}
type DelTimeoutSessionJob struct {
ID string
}
func (r DelTimeoutSessionJob) Run() {
property, err := FindPropertyByName("session-saved-limit")
if err != nil {
return
}
if property.Value == "" || property.Value == "-" {
return
}
limit, err := strconv.Atoi(property.Value)
if err != nil {
return
}
sessions, err := FindOutTimeSessions(limit)
if err != nil {
return
}
if sessions != nil && len(sessions) > 0 {
var sessionIds []string
for i := range sessions {
sessionIds = append(sessionIds, sessions[i].ID)
}
err := DeleteSessionByIds(sessionIds)
if err != nil {
logrus.Errorf("删除离线会话失败 %v", err)
}
}
if r.ID != "" {
_ = UpdateJonUpdatedById(r.ID)
}
}