TODO: 解决改版后递归逻辑错误

This commit is contained in:
huangsimin 2020-04-08 17:40:02 +08:00
parent d7c4848d63
commit 9a7bfe6c4d
5 changed files with 138 additions and 44 deletions

View File

@ -4,11 +4,15 @@ import "github.com/474420502/requests"
// TaskContext 上下文 // TaskContext 上下文
type TaskContext struct { type TaskContext struct {
share map[string]interface{} hunter *Hunter
hunter *Hunter
curNode ITaskNode curPath string
session *requests.Session curTaskID string
workflow *requests.Workflow workflow *requests.Workflow
parent ITaskNode
current ITaskNode
} }
// NewContext 任务上下文 // NewContext 任务上下文
@ -18,24 +22,23 @@ func NewContext() *TaskContext {
// AddTask 添加到当前子任务队列 // AddTask 添加到当前子任务队列
func (cxt *TaskContext) AddTask(itask ITask) { func (cxt *TaskContext) AddTask(itask ITask) {
if children := cxt.curNode.Children(); children == nil { if children := cxt.current.Children(); children == nil {
cxt.curNode.SetChildren(cxt.hunter.createQueue()) cxt.current.SetChildren(cxt.hunter.createQueue())
} }
bt := &BaseTask{task: itask} bt := &BaseTask{task: itask}
cxt.curNode.Children().Push(bt) cxt.current.Children().Push(bt)
} }
// AddParentTask 添加到当前任务队列 // AddParentTask 添加到当前任务队列
func (cxt *TaskContext) AddParentTask(itask ITask) { func (cxt *TaskContext) AddParentTask(itask ITask) {
bt := &BaseTask{task: itask} bt := &BaseTask{task: itask}
cxt.curNode.Parent().Children().Push(bt) cxt.current.Parent().Children().Push(bt)
} }
// GetShare 获取share的数据, 存储用的 // GetShare 获取share的数据, 存储用的
func (cxt *TaskContext) GetShare(key string) interface{} { func (cxt *TaskContext) GetShare(key string) interface{} {
if v, ok := cxt.share[key]; ok { if v, ok := cxt.hunter.share[key]; ok {
return v return v
} }
return nil return nil
@ -43,20 +46,15 @@ func (cxt *TaskContext) GetShare(key string) interface{} {
// SetShare 设置share的数据, 存储用的 // SetShare 设置share的数据, 存储用的
func (cxt *TaskContext) SetShare(key string, value interface{}) { func (cxt *TaskContext) SetShare(key string, value interface{}) {
cxt.share[key] = value cxt.hunter.share[key] = value
} }
// Session Get return session *requests.Session // Session Get return session *requests.Session
func (cxt *TaskContext) Session() *requests.Session { func (cxt *TaskContext) Session() *requests.Session {
if cxt.session == nil { if cxt.hunter.Session() == nil {
cxt.session = requests.NewSession() cxt.hunter.SetSession(requests.NewSession())
} }
return cxt.session return cxt.hunter.Session()
}
// SetSession Set session *requests.Session
func (cxt *TaskContext) SetSession(session *requests.Session) {
cxt.session = session
} }
// Workflow Get return Workflow *requests.Workflow. not exists, return nil // Workflow Get return Workflow *requests.Workflow. not exists, return nil
@ -69,6 +67,16 @@ func (cxt *TaskContext) SetWorkflow(workflow *requests.Workflow) {
cxt.workflow = workflow cxt.workflow = workflow
} }
// TaskID Get Task ID
func (cxt *TaskContext) TaskID() string {
return cxt.curTaskID
}
// Path curren Task tree path.
func (cxt *TaskContext) Path() string {
return cxt.curPath
}
// Hunt Hunt() = cxt.Workflow().Execute() // Hunt Hunt() = cxt.Workflow().Execute()
func (cxt *TaskContext) Hunt() (*requests.Response, error) { func (cxt *TaskContext) Hunt() (*requests.Response, error) {
return cxt.workflow.Execute() return cxt.workflow.Execute()

110
hunter.go
View File

@ -1,23 +1,29 @@
package hunter package hunter
import ( import (
"strconv"
pqueue "github.com/474420502/focus/priority_queue" pqueue "github.com/474420502/focus/priority_queue"
"github.com/474420502/requests"
) )
// IGobalBefore 全局任务执行之前 // IGobalBefore 全局任务执行之前
type IGobalBefore interface { type IGobalBefore interface {
GobalBefore() GobalBefore(cxt *TaskContext)
} }
// IGobalAfter 全局任务执行之后 // IGobalAfter 全局任务执行之后
type IGobalAfter interface { type IGobalAfter interface {
GobalAfter() GobalAfter(cxt *TaskContext)
} }
// Hunter 任务相关 必须有序 // Hunter 任务相关 必须有序
type Hunter struct { type Hunter struct {
cxt *TaskContext share map[string]interface{}
task ITaskNode
session *requests.Session
tasks []ITask
createQueue func() *pqueue.PriorityQueue createQueue func() *pqueue.PriorityQueue
} }
@ -30,13 +36,15 @@ func NewHunter() *Hunter {
func NewPriorityHunter(queueCreator func() *pqueue.PriorityQueue) *Hunter { func NewPriorityHunter(queueCreator func() *pqueue.PriorityQueue) *Hunter {
hunter := &Hunter{} hunter := &Hunter{}
hunter.createQueue = queueCreator hunter.createQueue = queueCreator
hunter.task = &BaseTask{}
hunter.task.SetParent(nil)
hunter.task.SetChildren(hunter.createQueue())
hunter.cxt = NewContext() // hunter.task = &BaseTask{}
hunter.cxt.curNode = hunter.task // hunter.task.SetParent(nil)
hunter.cxt.share = make(map[string]interface{}) // hunter.task.SetChildren(hunter.createQueue())
// hunter.cxt = NewContext()
// hunter.cxt.curNode = hunter.task
hunter.share = make(map[string]interface{})
return hunter return hunter
} }
@ -50,28 +58,86 @@ func NewPriorityMinHunter() *Hunter {
return NewPriorityHunter(CreatePriorityMinQueue) return NewPriorityHunter(CreatePriorityMinQueue)
} }
// Execute 执行任务 // Session Get session *requests.Session
func (hunter *Hunter) Execute() { func (hunter *Hunter) Session() *requests.Session {
hunter.recursionTasks(hunter.task) return hunter.session
} }
func (hunter *Hunter) recursionTasks(itask ITaskNode) { // SetSession Set session *requests.Session
func (hunter *Hunter) SetSession(session *requests.Session) {
hunter.session = session
}
for children := itask.Children(); children != nil && children.Size() > 0; { // GetShare 获取share的数据, 存储用的
func (hunter *Hunter) GetShare(key string) interface{} {
if v, ok := hunter.share[key]; ok {
return v
}
return nil
}
// SetShare 设置share的数据, 存储用的
func (hunter *Hunter) SetShare(key string, value interface{}) {
hunter.share[key] = value
}
// Execute 执行任务
func (hunter *Hunter) Execute() {
for _, task := range hunter.tasks {
hunter.execute(task)
}
}
// Execute 执行任务
func (hunter *Hunter) execute(task ITask) {
cxt := NewContext()
btask := &BaseTask{}
// btask.SetTask(task)
btask.SetParent(nil)
btask.SetChildren(hunter.createQueue())
cxt.parent = btask
cxt.hunter = hunter
cxt.AddTask(task)
hunter.recursionTasks(cxt)
}
func (hunter *Hunter) recursionTasks(cxt *TaskContext) {
autoid := 0
for children := cxt.parent.Children(); children != nil && children.Size() > 0; {
if itask, ok := children.Pop(); ok { if itask, ok := children.Pop(); ok {
tasknode := itask.(ITaskNode)
ncxt := NewContext()
tasknode := itask.(ITaskNode)
task := tasknode.Task() task := tasknode.Task()
if before, ok := task.(IBefore); ok {
before.Before(hunter.cxt) ncxt.curPath = cxt.parent.Path()
if itid, ok := task.(IIdentity); ok {
ncxt.curTaskID = itid.GetID()
} else {
ncxt.curTaskID = strconv.Itoa(autoid)
autoid++
} }
tasknode.Task().Execute(hunter.cxt) if before, ok := task.(IBefore); ok {
before.Before(cxt)
}
tasknode.Task().Execute(cxt)
if after, ok := task.(IAfter); ok { if after, ok := task.(IAfter); ok {
after.After(hunter.cxt) after.After(cxt)
} }
hunter.recursionTasks(tasknode)
tasknode.SetPath(cxt.parent.Path() + "." + ncxt.curTaskID)
ncxt.parent = cxt.current
ncxt.current = tasknode
hunter.recursionTasks(ncxt)
} }
} }
@ -84,7 +150,7 @@ func (hunter *Hunter) Stop() {
// AddTask 执行任务 // AddTask 执行任务
func (hunter *Hunter) AddTask(task ITask) { func (hunter *Hunter) AddTask(task ITask) {
hunter.cxt.AddTask(task) hunter.tasks = append(hunter.tasks, task)
} }
// Execute 执行 // Execute 执行

View File

@ -23,7 +23,7 @@ func TestCasePreUrl(t *testing.T) {
hunter.Execute() hunter.Execute()
data := make(map[string]interface{}) data := make(map[string]interface{})
content := hunter.cxt.GetShare("test").(string) content := hunter.GetShare("test").(string)
err := json.Unmarshal([]byte(content), &data) err := json.Unmarshal([]byte(content), &data)
if err != nil { if err != nil {
t.Error(err) t.Error(err)
@ -55,7 +55,7 @@ func TestCasePostForm(t *testing.T) {
hunter.Execute() hunter.Execute()
data := make(map[string]interface{}) data := make(map[string]interface{})
content := hunter.cxt.GetShare("test").(string) content := hunter.GetShare("test").(string)
err := json.Unmarshal([]byte(content), &data) err := json.Unmarshal([]byte(content), &data)
if err != nil { if err != nil {
t.Error(err) t.Error(err)
@ -88,7 +88,7 @@ func TestCaseWebSub(t *testing.T) {
hunter.Execute() hunter.Execute()
data := make(map[string]interface{}) data := make(map[string]interface{})
content := hunter.cxt.GetShare("test").(string) content := hunter.GetShare("test").(string)
err := json.Unmarshal([]byte(content), &data) err := json.Unmarshal([]byte(content), &data)
if err != nil { if err != nil {
t.Error(err) t.Error(err)

1
id_com.go Normal file
View File

@ -0,0 +1 @@
package hunter

19
task.go
View File

@ -24,6 +24,11 @@ type ITask interface {
Execute(ctx *TaskContext) Execute(ctx *TaskContext)
} }
// IIdentity 身份id接口
type IIdentity interface {
GetID() string
}
// ITaskNode 任务节点 // ITaskNode 任务节点
type ITaskNode interface { type ITaskNode interface {
Parent() ITaskNode Parent() ITaskNode
@ -34,12 +39,16 @@ type ITaskNode interface {
Task() ITask // ITaskNode Task() ITask // ITaskNode
SetTask(itask ITask) SetTask(itask ITask)
SetPath(path string)
Path() string
} }
// BaseTask 任务,必须包含子任务. 执行了第一个 // BaseTask 任务,必须包含子任务. 执行了第一个
type BaseTask struct { type BaseTask struct {
parent ITaskNode parent ITaskNode
children *pqueue.PriorityQueue // ITask类型 children *pqueue.PriorityQueue // ITask类型
path string // id 联合体, 禁用.命名
task ITask task ITask
} }
@ -73,6 +82,16 @@ func (task *BaseTask) SetTask(itask ITask) {
task.task = itask task.task = itask
} }
// Path 路径 例如: web.subweb.subsubweb
func (task *BaseTask) Path() string {
return task.path
}
// SetPath 路径 例如: web.subweb.subsubweb
func (task *BaseTask) SetPath(path string) {
task.path = path
}
// // Task 孩子节点 // // Task 孩子节点
// func (task *BaseTask) Task() ITask { // func (task *BaseTask) Task() ITask {
// return *task // return *task