mirror of
https://github.com/astaxie/beego.git
synced 2025-06-14 13:30:40 +00:00
design Command for governor module & decouple web module from task module
This commit is contained in:
92
pkg/task/govenor_command.go
Normal file
92
pkg/task/govenor_command.go
Normal file
@ -0,0 +1,92 @@
|
||||
// Copyright 2020
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package task
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"html/template"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"github.com/astaxie/beego/pkg/infrastructure/governor"
|
||||
)
|
||||
|
||||
type listTaskCommand struct {
|
||||
}
|
||||
|
||||
func (l *listTaskCommand) Execute(params ...interface{}) *governor.Result {
|
||||
resultList := make([][]string, 0, len(AdminTaskList))
|
||||
for tname, tk := range AdminTaskList {
|
||||
result := []string{
|
||||
template.HTMLEscapeString(tname),
|
||||
template.HTMLEscapeString(tk.GetSpec(nil)),
|
||||
template.HTMLEscapeString(tk.GetStatus(nil)),
|
||||
template.HTMLEscapeString(tk.GetPrev(context.Background()).String()),
|
||||
}
|
||||
resultList = append(resultList, result)
|
||||
}
|
||||
|
||||
return &governor.Result{
|
||||
Status: 200,
|
||||
Content: resultList,
|
||||
}
|
||||
}
|
||||
|
||||
type runTaskCommand struct {
|
||||
}
|
||||
|
||||
func (r *runTaskCommand) Execute(params ...interface{}) *governor.Result {
|
||||
if len(params) == 0 {
|
||||
return &governor.Result{
|
||||
Status: 400,
|
||||
Error: errors.New("task name not passed"),
|
||||
}
|
||||
}
|
||||
|
||||
tn, ok := params[0].(string)
|
||||
|
||||
if !ok {
|
||||
return &governor.Result{
|
||||
Status: 400,
|
||||
Error: errors.New("parameter is invalid"),
|
||||
}
|
||||
}
|
||||
|
||||
if t, ok := AdminTaskList[tn]; ok {
|
||||
err := t.Run(context.Background())
|
||||
if err != nil {
|
||||
return &governor.Result{
|
||||
Status: 500,
|
||||
Error: err,
|
||||
}
|
||||
}
|
||||
return &governor.Result{
|
||||
Status: 200,
|
||||
Content: t.GetStatus(context.Background()),
|
||||
}
|
||||
} else {
|
||||
return &governor.Result{
|
||||
Status: 400,
|
||||
Error: errors.New(fmt.Sprintf("task with name %s not found", tn)),
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func registerCommands() {
|
||||
governor.RegisterCommand("task", "list", &listTaskCommand{})
|
||||
governor.RegisterCommand("task", "run", &runTaskCommand{})
|
||||
}
|
111
pkg/task/governor_command_test.go
Normal file
111
pkg/task/governor_command_test.go
Normal file
@ -0,0 +1,111 @@
|
||||
// Copyright 2020
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package task
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
type countTask struct {
|
||||
cnt int
|
||||
mockErr error
|
||||
}
|
||||
|
||||
func (c *countTask) GetSpec(ctx context.Context) string {
|
||||
return "AAA"
|
||||
}
|
||||
|
||||
func (c *countTask) GetStatus(ctx context.Context) string {
|
||||
return "SUCCESS"
|
||||
}
|
||||
|
||||
func (c *countTask) Run(ctx context.Context) error {
|
||||
c.cnt++
|
||||
return c.mockErr
|
||||
}
|
||||
|
||||
func (c *countTask) SetNext(ctx context.Context, time time.Time) {
|
||||
}
|
||||
|
||||
func (c *countTask) GetNext(ctx context.Context) time.Time {
|
||||
return time.Now()
|
||||
}
|
||||
|
||||
func (c *countTask) SetPrev(ctx context.Context, time time.Time) {
|
||||
}
|
||||
|
||||
func (c *countTask) GetPrev(ctx context.Context) time.Time {
|
||||
return time.Now()
|
||||
}
|
||||
|
||||
func TestRunTaskCommand_Execute(t *testing.T) {
|
||||
task := &countTask{}
|
||||
AddTask("count", task)
|
||||
|
||||
cmd := &runTaskCommand{}
|
||||
|
||||
res := cmd.Execute()
|
||||
assert.NotNil(t, res)
|
||||
assert.NotNil(t, res.Error)
|
||||
assert.Equal(t, "task name not passed", res.Error.Error())
|
||||
|
||||
res = cmd.Execute(10)
|
||||
assert.NotNil(t, res)
|
||||
assert.NotNil(t, res.Error)
|
||||
assert.Equal(t, "parameter is invalid", res.Error.Error())
|
||||
|
||||
res = cmd.Execute("CCCC")
|
||||
assert.NotNil(t, res)
|
||||
assert.NotNil(t, res.Error)
|
||||
assert.Equal(t, "task with name CCCC not found", res.Error.Error())
|
||||
|
||||
res = cmd.Execute("count")
|
||||
assert.NotNil(t, res)
|
||||
assert.True(t, res.IsSuccess())
|
||||
|
||||
task.mockErr = errors.New("mock error")
|
||||
res = cmd.Execute("count")
|
||||
assert.NotNil(t, res)
|
||||
assert.NotNil(t, res.Error)
|
||||
assert.Equal(t, "mock error", res.Error.Error())
|
||||
}
|
||||
|
||||
func TestListTaskCommand_Execute(t *testing.T) {
|
||||
task := &countTask{}
|
||||
|
||||
cmd := &listTaskCommand{}
|
||||
|
||||
res := cmd.Execute()
|
||||
|
||||
assert.True(t, res.IsSuccess())
|
||||
|
||||
_, ok := res.Content.([][]string)
|
||||
assert.True(t, ok)
|
||||
|
||||
AddTask("count", task)
|
||||
|
||||
res = cmd.Execute()
|
||||
|
||||
assert.True(t, res.IsSuccess())
|
||||
|
||||
rl, ok := res.Content.([][]string)
|
||||
assert.True(t, ok)
|
||||
assert.Equal(t, 1, len(rl))
|
||||
}
|
@ -189,9 +189,9 @@ func (t *Task) GetPrev(context.Context) time.Time {
|
||||
// SetCron some signals:
|
||||
// *: any time
|
||||
// ,: separate signal
|
||||
// -:duration
|
||||
// -:duration
|
||||
// /n : do as n times of time duration
|
||||
/////////////////////////////////////////////////////////
|
||||
// ///////////////////////////////////////////////////////
|
||||
// 0/30 * * * * * every 30s
|
||||
// 0 43 21 * * * 21:43
|
||||
// 0 15 05 * * * 05:15
|
||||
@ -401,10 +401,12 @@ func StartTask() {
|
||||
taskLock.Lock()
|
||||
defer taskLock.Unlock()
|
||||
if isstart {
|
||||
//If already started, no need to start another goroutine.
|
||||
// If already started, no need to start another goroutine.
|
||||
return
|
||||
}
|
||||
isstart = true
|
||||
|
||||
registerCommands()
|
||||
go run()
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user