Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
二次元的罪恶王冠
beego
提交
44127ede
B
beego
项目概览
二次元的罪恶王冠
/
beego
与 Fork 源项目一致
从无法访问的项目Fork
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
B
beego
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
提交
44127ede
编写于
9月 20, 2020
作者:
M
Ming Deng
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
design Command for governor module & decouple web module from task module
上级
08900652
变更
6
隐藏空白更改
内联
并排
Showing
6 changed file
with
311 addition
and
25 deletion
+311
-25
pkg/infrastructure/governor/command.go
pkg/infrastructure/governor/command.go
+87
-0
pkg/server/web/admin.go
pkg/server/web/admin.go
+6
-4
pkg/server/web/admin_controller.go
pkg/server/web/admin_controller.go
+10
-18
pkg/task/govenor_command.go
pkg/task/govenor_command.go
+92
-0
pkg/task/governor_command_test.go
pkg/task/governor_command_test.go
+111
-0
pkg/task/task.go
pkg/task/task.go
+5
-3
未找到文件。
pkg/infrastructure/governor/command.go
0 → 100644
浏览文件 @
44127ede
// 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
governor
import
(
"github.com/pkg/errors"
)
// Command is an experimental interface
// We try to use this to decouple modules
// All other modules depends on this, and they register the command they support
// We may change the API in the future, so be careful about this.
type
Command
interface
{
Execute
(
params
...
interface
{})
*
Result
}
var
CommandNotFound
=
errors
.
New
(
"Command not found"
)
type
Result
struct
{
// Status is the same as http.Status
Status
int
Error
error
Content
interface
{}
}
func
(
r
*
Result
)
IsSuccess
()
bool
{
return
r
.
Status
>=
200
&&
r
.
Status
<
300
}
// CommandRegistry stores all commands
// name => command
type
moduleCommands
map
[
string
]
Command
// Get returns command with the name
func
(
m
moduleCommands
)
Get
(
name
string
)
Command
{
c
,
ok
:=
m
[
name
]
if
ok
{
return
c
}
return
&
doNothingCommand
{}
}
// module name => moduleCommand
type
commandRegistry
map
[
string
]
moduleCommands
// Get returns module's commands
func
(
c
commandRegistry
)
Get
(
moduleName
string
)
moduleCommands
{
if
mcs
,
ok
:=
c
[
moduleName
];
ok
{
return
mcs
}
res
:=
make
(
moduleCommands
)
c
[
moduleName
]
=
res
return
res
}
var
cmdRegistry
=
make
(
commandRegistry
)
// RegisterCommand is not thread-safe
// do not use it in concurrent case
func
RegisterCommand
(
module
string
,
commandName
string
,
command
Command
)
{
cmdRegistry
.
Get
(
module
)[
commandName
]
=
command
}
func
GetCommand
(
module
string
,
cmdName
string
)
Command
{
return
cmdRegistry
.
Get
(
module
)
.
Get
(
cmdName
)
}
type
doNothingCommand
struct
{}
func
(
d
*
doNothingCommand
)
Execute
(
params
...
interface
{})
*
Result
{
return
&
Result
{
Status
:
404
,
Error
:
CommandNotFound
,
}
}
pkg/server/web/admin.go
浏览文件 @
44127ede
...
...
@@ -21,7 +21,6 @@ import (
"time"
"github.com/astaxie/beego/pkg/infrastructure/logs"
"github.com/astaxie/beego/pkg/task"
)
// BeeAdminApp is the default adminApp used by admin module.
...
...
@@ -86,9 +85,12 @@ type adminApp struct {
// Route adds http.HandlerFunc to adminApp with url pattern.
func
(
admin
*
adminApp
)
Run
()
{
if
len
(
task
.
AdminTaskList
)
>
0
{
task
.
StartTask
()
}
// if len(task.AdminTaskList) > 0 {
// task.StartTask()
// }
logs
.
Warning
(
"now we don't start tasks here, if you use task module,"
+
" please invoke task.StartTask, or task will not be executed"
)
addr
:=
BConfig
.
Listen
.
AdminAddr
if
BConfig
.
Listen
.
AdminPort
!=
0
{
...
...
pkg/server/web/admin_controller.go
浏览文件 @
44127ede
...
...
@@ -16,7 +16,6 @@ package web
import
(
"bytes"
context2
"context"
"encoding/json"
"fmt"
"net/http"
...
...
@@ -26,7 +25,6 @@ import (
"github.com/prometheus/client_golang/prometheus/promhttp"
"github.com/astaxie/beego/pkg/infrastructure/governor"
"github.com/astaxie/beego/pkg/task"
)
type
adminController
struct
{
...
...
@@ -90,19 +88,22 @@ func (a *adminController) TaskStatus() {
req
.
ParseForm
()
taskname
:=
req
.
Form
.
Get
(
"taskname"
)
if
taskname
!=
""
{
if
t
,
ok
:=
task
.
AdminTaskList
[
taskname
];
ok
{
if
err
:=
t
.
Run
(
nil
);
err
!=
nil
{
data
[
"Message"
]
=
[]
string
{
"error"
,
template
.
HTMLEscapeString
(
fmt
.
Sprintf
(
"%s"
,
err
))}
}
data
[
"Message"
]
=
[]
string
{
"success"
,
template
.
HTMLEscapeString
(
fmt
.
Sprintf
(
"%s run success,Now the Status is <br>%s"
,
taskname
,
t
.
GetStatus
(
nil
)))}
cmd
:=
governor
.
GetCommand
(
"task"
,
"run"
)
res
:=
cmd
.
Execute
(
taskname
)
if
res
.
IsSuccess
()
{
data
[
"Message"
]
=
[]
string
{
"success"
,
template
.
HTMLEscapeString
(
fmt
.
Sprintf
(
"%s run success,Now the Status is <br>%s"
,
taskname
,
res
.
Content
.
(
string
)))}
}
else
{
data
[
"Message"
]
=
[]
string
{
"
warning"
,
template
.
HTMLEscapeString
(
fmt
.
Sprintf
(
"there's no task which named: %s"
,
taskname
))}
data
[
"Message"
]
=
[]
string
{
"
error"
,
template
.
HTMLEscapeString
(
fmt
.
Sprintf
(
"%s"
,
res
.
Error
))}
}
}
// List Tasks
content
:=
make
(
M
)
resultList
:=
new
([][]
string
)
resultList
:=
governor
.
GetCommand
(
"task"
,
"list"
)
.
Execute
()
.
Content
.
([][]
string
)
var
fields
=
[]
string
{
"Task Name"
,
"Task Spec"
,
...
...
@@ -110,15 +111,6 @@ func (a *adminController) TaskStatus() {
"Last Time"
,
""
,
}
for
tname
,
tk
:=
range
task
.
AdminTaskList
{
result
:=
[]
string
{
template
.
HTMLEscapeString
(
tname
),
template
.
HTMLEscapeString
(
tk
.
GetSpec
(
nil
)),
template
.
HTMLEscapeString
(
tk
.
GetStatus
(
nil
)),
template
.
HTMLEscapeString
(
tk
.
GetPrev
(
context2
.
Background
())
.
String
()),
}
*
resultList
=
append
(
*
resultList
,
result
)
}
content
[
"Fields"
]
=
fields
content
[
"Data"
]
=
resultList
...
...
pkg/task/govenor_command.go
0 → 100644
浏览文件 @
44127ede
// 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
{})
}
pkg/task/governor_command_test.go
0 → 100644
浏览文件 @
44127ede
// 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
))
}
pkg/task/task.go
浏览文件 @
44127ede
...
...
@@ -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
()
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录