imitater/person.go
2018-12-07 19:09:38 +08:00

182 lines
3.5 KiB
Go

package imitater
import (
"fmt"
"log"
"reflect"
"time"
"474420502.top/eson/structure/circular_linked"
"474420502.top/eson/curl2info"
)
// ITask 继承这个接口的类
type ITask interface {
Execute(data interface{}) ITask
SetCrontab(cron string)
SetLastStatus(status bool)
SetName(name string)
GetName() string
SetCurl(Curl *curl2info.CURL)
GetCurl() *curl2info.CURL
GetProxies() *clinked.CircularLinked
AddProxies(proxy string)
TimeUp() bool
NextTime() time.Time
}
var register = make(map[string]reflect.Type)
func init() {
log.SetFlags(log.Llongfile)
}
// Register 注册 类型 ITask为样本的类型
func Register(name string, itask ITask) {
register[name] = reflect.TypeOf(itask).Elem()
}
func makeRegisterType(name string) ITask {
result := reflect.New(register[name]).Interface().(ITask)
result.SetName(name)
return result
}
// Person 以人为单位
type Person struct {
Tasks []ITask
Conf *Config
}
// NewPerson 创建一个人实例
func NewPerson() *Person {
person := &Person{}
// person.Conf = NewConfig(conf)
// person.Tasks = SplitTasks(person.Conf)
return person
}
// Config 加载配置
func (person *Person) Config(conf string) {
person.Conf = NewConfig(conf)
person.Tasks = splitTasks(person.Conf)
}
// NewPersonWithConfig 创建一个person
func NewPersonWithConfig(conf string) *Person {
person := NewPerson()
person.Config(conf)
return person
}
// SplitTasks 拆开出需求的任务
func splitTasks(conf *Config) []ITask {
var tasks []ITask
proxies := (*clinked.CircularLinked)(conf.Proxies)
for _, scurl := range conf.Curls {
curl, err := curl2info.ParseRawCURL(scurl)
if err != nil {
panic(err)
}
if curl.ITask == "" {
curl.ITask = conf.ITask
}
task := makeRegisterType(curl.ITask)
switch conf.Mode {
case 0:
initTask(conf, task, curl)
for _, cnode := range proxies.GetLoopValues() {
proxy := cnode.GetValue().(string)
task.AddProxies(proxy)
}
tasks = append(tasks, task)
case 1:
for _, cnode := range proxies.GetLoopValues() {
proxy := cnode.GetValue().(string)
ncurl, err := curl2info.ParseRawCURL(scurl)
if err != nil {
panic(err)
}
if curl.ITask == "" {
curl.ITask = conf.ITask
}
ptask := makeRegisterType(ncurl.ITask).(ITask)
initTask(conf, ptask, ncurl)
ptask.AddProxies(proxy)
tasks = append(tasks, task)
}
}
}
return tasks
}
// Execute 人的执行所有任务
func (person *Person) Execute() {
taskLen := len(person.Tasks)
result := make(chan string, 1)
for _, task := range person.Tasks {
go ExecuteOnPlan(task, result)
}
for t := range result {
log.Println(t)
taskLen--
if taskLen <= 0 {
close(result)
}
}
// engine := gin.Default()
// engine.Run()
}
// initTask 生成一个新任务
func initTask(conf *Config, task ITask, curl *curl2info.CURL) {
if curl.Crontab != "" {
task.SetCrontab(curl.Crontab)
} else {
task.SetCrontab(conf.Crontab)
}
task.SetCurl(curl)
}
// ExecuteOnPlan 按照计划执行任务并返回结果
func ExecuteOnPlan(task ITask, result chan string) {
data := make(map[string]interface{})
var rtask ITask
taskname := task.GetName()
urlname := task.GetCurl().Name
for {
if task.TimeUp() {
rtask = task.Execute(data) // 事件 在这里变化
if rtask == nil {
// log.Println("rtask is nil")
result <- fmt.Sprintf("rtask is nil, the first task = %s, name = %s", taskname, urlname)
return
}
}
interval := task.NextTime().Sub(time.Now())
time.Sleep(interval)
task = rtask
}
}