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) log.Println(proxy) task.AddProxies(proxy) } log.Println(task.GetProxies()) 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, ptask) } } } 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 { interval := time.Second * 2 if task.TimeUp() { rtask = task.Execute(data) // 事件 在这里变化 ntime := task.NextTime() interval = ntime.Sub(time.Now()) if rtask == nil { // log.Println("rtask is nil") result <- fmt.Sprintf("rtask is nil, the first task = %s, name = %s", taskname, urlname) return } task = rtask } time.Sleep(interval) } }