所有学习任务创建共享一个state
This commit is contained in:
johlanse 2022-11-06 15:01:22 +08:00
parent 4d7b8586b6
commit 1de1c28652
10 changed files with 146 additions and 124 deletions

View File

@ -35,7 +35,7 @@ func study() *grumble.Command {
Name: "study",
Aliases: []string{"study"},
Help: "study xxqg",
LongHelp: "study the xxqg",
LongHelp: "对选定序号的用户进行学习",
Args: func(a *grumble.Args) {
a.Int("index", "the index user")
},
@ -75,7 +75,7 @@ func addUser() *grumble.Command {
Name: "add user",
Aliases: []string{"add"},
Help: "add a user",
LongHelp: "add a user",
LongHelp: "添加一个用户",
Run: func(c *grumble.Context) error {
core := &lib.Core{
Push: push.GetPush(conf.GetConfig()),
@ -96,7 +96,7 @@ func getUser() *grumble.Command {
Help: "get all user",
LongHelp: "input the user,can get all user",
HelpGroup: "",
Usage: "get all user",
Usage: "获取用户列表",
Run: func(c *grumble.Context) error {
users, err := model.Query()
if err != nil {

47
lib/lib.go Normal file
View File

@ -0,0 +1,47 @@
package lib
import (
"fmt"
"time"
"github.com/sirupsen/logrus"
"github.com/johlanse/study_xxqg/conf"
"github.com/johlanse/study_xxqg/model"
)
func Study(core2 *Core, u *model.User) {
config := conf.GetConfig()
defer func() {
err := recover()
if err != nil {
logrus.Errorln("学习过程异常")
logrus.Errorln(err)
}
}()
startTime := time.Now()
core2.LearnArticle(u)
core2.LearnVideo(u)
core2.LearnVideo(u)
if config.Model == 2 {
core2.RespondDaily(u, "daily")
} else if config.Model == 3 {
core2.RespondDaily(u, "daily")
core2.RespondDaily(u, "weekly")
core2.RespondDaily(u, "special")
}
endTime := time.Now()
score, err := GetUserScore(u.ToCookies())
if err != nil {
logrus.Errorln("获取成绩失败")
logrus.Debugln(err.Error())
return
}
score, _ = GetUserScore(u.ToCookies())
message := fmt.Sprintf("%v 学习完成,用时%.1f分钟\n%v", u.Nick, endTime.Sub(startTime).Minutes(), FormatScoreShort(score))
core2.Push(u.PushId, "flush", message)
}

33
lib/state/state.go Normal file
View File

@ -0,0 +1,33 @@
package state
import (
"sync"
"github.com/johlanse/study_xxqg/lib"
)
var (
state = sync.Map{}
)
func Add(uid string, core *lib.Core) {
state.Store(uid, core)
}
func IsStudy(uid string) bool {
_, ok := state.Load(uid)
return ok
}
func Delete(uid string) {
state.Delete(uid)
}
func Get(uid string) *lib.Core {
value, _ := state.Load(uid)
return value.(*lib.Core)
}
func Range(fun func(key, value interface{}) bool) {
state.Range(fun)
}

83
main.go
View File

@ -26,6 +26,7 @@ import (
"github.com/johlanse/study_xxqg/cli"
"github.com/johlanse/study_xxqg/conf"
"github.com/johlanse/study_xxqg/lib/state"
"github.com/johlanse/study_xxqg/utils"
// "github.com/johlanse/study_xxqg/gui"
"github.com/johlanse/study_xxqg/lib"
@ -211,7 +212,7 @@ func main() {
}
c2.Run()
}
inittask()
initTask()
model.SetPush(getPush)
if now {
do()
@ -244,65 +245,53 @@ func do() {
}
c.Init()
defer c.Quit()
study(c, newUser)
lib.Study(c, newUser)
}(user)
}
s := &sync.WaitGroup{}
// 如果为定时模式则直接循环所以用户依次运行
for _, u := range users {
core := &lib.Core{ShowBrowser: config.ShowBrowser, Push: getPush}
core.Init()
t := &Task{
Core: core,
User: u,
wg: s,
if config.PoolSize == 1 {
for _, user := range users {
if state.IsStudy(user.UID) {
log.Infoln("检测到该用户已在学习中!")
continue
} else {
core := &lib.Core{ShowBrowser: config.ShowBrowser, Push: getPush}
core.Init()
state.Add(user.UID, core)
lib.Study(core, user)
core.Quit()
state.Delete(user.UID)
}
}
run(t)
s.Add(1)
} else {
for _, u := range users {
if state.IsStudy(u.UID) {
log.Infoln("检测到该用户已在学习中!")
continue
} else {
core := &lib.Core{ShowBrowser: config.ShowBrowser, Push: getPush}
core.Init()
t := &Task{
Core: core,
User: u,
wg: s,
}
run(t)
s.Add(1)
}
}
s.Wait()
}
s.Wait()
log.Infoln("定时任务执行完成")
return
}
func study(core2 *lib.Core, u *model.User) {
defer func() {
err := recover()
if err != nil {
log.Errorln("学习过程异常")
log.Errorln(err)
}
}()
startTime := time.Now()
core2.LearnArticle(u)
core2.LearnVideo(u)
core2.LearnVideo(u)
if config.Model == 2 {
core2.RespondDaily(u, "daily")
} else if config.Model == 3 {
core2.RespondDaily(u, "daily")
core2.RespondDaily(u, "weekly")
core2.RespondDaily(u, "special")
}
endTime := time.Now()
score, err := lib.GetUserScore(u.ToCookies())
if err != nil {
log.Errorln("获取成绩失败")
log.Debugln(err.Error())
return
}
score, _ = lib.GetUserScore(u.ToCookies())
message := fmt.Sprintf("%v 学习完成,用时%.1f分钟\n%v", u.Nick, endTime.Sub(startTime).Minutes(), lib.FormatScoreShort(score))
core2.Push(u.PushId, "flush", message)
}
func runBack() {
cmd, err := xdaemon.Background(os.Stdout, false)
if err != nil {

View File

@ -22,6 +22,7 @@ func init() {
log.Errorln("用户数据库打开失败请检查config目录权限")
log.Panicln(err.Error())
}
db.SetMaxOpenConns(1)
_, _ = db.Exec(`create table user
(
@ -57,6 +58,7 @@ func initQuestionDb() {
log.Errorln("题目数据库打开失败请检查QuestionDB是否存在")
log.Panicln(err.Error())
}
db1.SetMaxOpenConns(1)
})
}

View File

@ -12,11 +12,11 @@ import (
"time"
tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api/v5"
"github.com/google/uuid"
log "github.com/sirupsen/logrus"
"github.com/johlanse/study_xxqg/conf"
"github.com/johlanse/study_xxqg/lib"
"github.com/johlanse/study_xxqg/lib/state"
"github.com/johlanse/study_xxqg/model"
"github.com/johlanse/study_xxqg/utils"
"github.com/johlanse/study_xxqg/utils/update"
@ -24,7 +24,6 @@ import (
var (
handles sync.Map
datas sync.Map
tgPush func(id string, kind string, message string)
)
@ -403,10 +402,10 @@ func studyAll(bot *Telegram, from int64, args []string) {
timer := time.After(time.Minute * 30)
c := make(chan int, 1)
go func() {
u := uuid.New().String()
bot.SendMsg(from, "已创建运行实例:"+u)
datas.Store(u, &core)
defer datas.Delete(u)
bot.SendMsg(from, "已创建运行实例:"+user.UID)
state.Add(user.UID, &core)
defer state.Delete(user.UID)
core.Init()
defer core.Quit()
core.LearnArticle(user)
@ -551,10 +550,9 @@ func study(bot *Telegram, from int64, args []string) {
timer := time.After(time.Minute * 30)
c := make(chan int, 1)
go func() {
u := uuid.New().String()
bot.SendMsg(from, "已创建运行实例:"+u)
datas.Store(u, &core)
defer datas.Delete(u)
bot.SendMsg(from, "已创建运行实例:"+user.UID)
state.Add(user.UID, &core)
defer state.Delete(user.UID)
core.Init()
defer core.Quit()
@ -614,14 +612,14 @@ func getScores(bot *Telegram, from int64, args []string) {
func quit(bot *Telegram, from int64, args []string) {
if len(args) < 1 {
datas.Range(func(key, value interface{}) bool {
state.Range(func(key, value interface{}) bool {
bot.SendMsg(from, "已退出运行实例"+key.(string))
core := value.(*lib.Core)
core.Quit()
return true
})
} else {
datas.Range(func(key, value interface{}) bool {
state.Range(func(key, value interface{}) bool {
if key.(string) == args[0] {
core := value.(*lib.Core)
core.Quit()

View File

@ -15,6 +15,7 @@ import (
"github.com/johlanse/study_xxqg/conf"
"github.com/johlanse/study_xxqg/lib"
"github.com/johlanse/study_xxqg/lib/state"
"github.com/johlanse/study_xxqg/model"
"github.com/johlanse/study_xxqg/utils"
"github.com/johlanse/study_xxqg/utils/update"
@ -23,7 +24,6 @@ import (
var (
wx *mp.WeiXin
lastNonce = ""
datas1 sync.Map
wxPush func(id, kind, message string)
)
@ -580,12 +580,11 @@ func handleStartStudy(id string, msg string) {
core.Init()
defer core.Quit()
for i, user := range users {
_, ok := datas1.Load(user.UID)
if ok {
log.Warningln("用户" + user.Nick + "已经在学习中了,跳过该用户")
if state.IsStudy(user.UID) {
log.Infoln("该用户已经在学习中了,跳过学习")
continue
} else {
datas1.Store(user.UID, "")
state.Add(user.UID, core)
}
sendMsg(id, fmt.Sprintf("开始学习第%d个用户用户名%v", i+1, user.Nick))
core.LearnArticle(user)
@ -597,7 +596,7 @@ func handleStartStudy(id string, msg string) {
core.RespondDaily(user, "special")
}
datas1.Delete(user.UID)
state.Delete(user.UID)
score, _ := lib.GetUserScore(user.ToCookies())
sendMsg(id, fmt.Sprintf("第%d个用户%v学习完成学习积分\n%v", i+1, user.Nick, lib.FormatScore(score)))
}

43
run.go
View File

@ -1,14 +1,13 @@
package main
import (
"fmt"
"sync"
"time"
"github.com/panjf2000/ants/v2"
log "github.com/sirupsen/logrus"
"github.com/johlanse/study_xxqg/lib"
"github.com/johlanse/study_xxqg/lib/state"
"github.com/johlanse/study_xxqg/model"
)
@ -26,47 +25,15 @@ func run(task *Task) {
pool.Invoke(task)
}
func inittask() {
study := func(core2 *lib.Core, u *model.User) {
defer func() {
err := recover()
if err != nil {
log.Errorln("学习过程异常")
log.Errorln(err)
}
}()
startTime := time.Now()
core2.LearnArticle(u)
core2.LearnVideo(u)
core2.LearnVideo(u)
if config.Model == 2 {
core2.RespondDaily(u, "daily")
} else if config.Model == 3 {
core2.RespondDaily(u, "daily")
core2.RespondDaily(u, "weekly")
core2.RespondDaily(u, "special")
}
endTime := time.Now()
score, err := lib.GetUserScore(u.ToCookies())
if err != nil {
log.Errorln("获取成绩失败")
log.Debugln(err.Error())
return
}
score, _ = lib.GetUserScore(u.ToCookies())
message := fmt.Sprintf("%v 学习完成,用时%.1f分钟\n%v", u.Nick, endTime.Sub(startTime).Minutes(), lib.FormatScoreShort(score))
core2.Push(u.PushId, "flush", message)
}
func initTask() {
pool1, err := ants.NewPoolWithFunc(config.PoolSize, func(i2 interface{}) {
task := i2.(*Task)
log.Infoln("开始执行" + task.User.Nick)
study(task.Core, task.User)
state.Add(task.User.UID, task.Core)
lib.Study(task.Core, task.User)
defer task.Core.Quit()
defer state.Delete(task.User.UID)
task.wg.Done()
})
if err != nil {

View File

@ -135,7 +135,7 @@ func Time2Stamp() int64 {
/*时间戳->字符串*/
func Stamp2Str(stamp int64) string {
timeLayout := "2006-01-02 15:04:05"
str := time.Unix(stamp/1000, 0).Format(timeLayout)
str := time.Unix(stamp, 0).Format(timeLayout)
return str
}

View File

@ -8,7 +8,6 @@ import (
"net/http"
"net/http/httputil"
"net/url"
"sync"
"time"
"github.com/gin-gonic/gin"
@ -16,15 +15,12 @@ import (
"github.com/johlanse/study_xxqg/conf"
"github.com/johlanse/study_xxqg/lib"
"github.com/johlanse/study_xxqg/lib/state"
"github.com/johlanse/study_xxqg/model"
"github.com/johlanse/study_xxqg/push"
"github.com/johlanse/study_xxqg/utils"
)
var (
state = sync.Map{}
)
// checkToken
/* @Description:
* @return gin.HandlerFunc
@ -250,17 +246,12 @@ func getUsers() gin.HandlerFunc {
var datas []map[string]interface{}
for _, user := range users {
var isStudy = false
_, ok := state.Load(user.UID)
if ok {
isStudy = true
}
datas = append(datas, map[string]interface{}{
"nick": user.Nick,
"uid": user.UID,
"token": user.Token,
"login_time": user.LoginTime,
"is_study": isStudy,
"is_study": state.IsStudy(user.UID),
})
}
ctx.JSON(200, Resp{
@ -316,7 +307,7 @@ func study() gin.HandlerFunc {
Push: push.GetPush(conf.GetConfig()),
}
core.Init()
state.Store(uid, core)
state.Add(user.UID, core)
config := conf.GetConfig()
go func() {
core.LearnArticle(user)
@ -343,11 +334,7 @@ func study() gin.HandlerFunc {
func stopStudy() gin.HandlerFunc {
return func(ctx *gin.Context) {
uid := ctx.Query("uid")
value, ok := state.Load(uid)
if !ok {
return
}
core := value.(*lib.Core)
core := state.Get(uid)
core.Quit()
ctx.JSON(200, Resp{
Code: 200,