Skip to content

Commit

Permalink
添加定时同步数据到热存储容器功能 (#191)
Browse files Browse the repository at this point in the history
  • Loading branch information
eatmoreapple authored Jan 10, 2023
1 parent 102af67 commit 87036e2
Show file tree
Hide file tree
Showing 3 changed files with 82 additions and 7 deletions.
7 changes: 6 additions & 1 deletion bot.go
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,7 @@ func (b *Bot) Block() error {
if b.self == nil {
return errors.New("`Block` must be called after user login")
}
<-b.context.Done()
<-b.Context().Done()
return nil
}

Expand Down Expand Up @@ -298,6 +298,11 @@ func (b *Bot) UUID() string {
return b.uuid
}

// Context returns current context of bot
func (b *Bot) Context() context.Context {
return b.context
}

func (b *Bot) reload() error {
if b.hotReloadStorage == nil {
return errors.New("hotReloadStorage is nil")
Expand Down
54 changes: 48 additions & 6 deletions bot_login.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
package openwechat

import (
"time"
)

// BotLogin 定义了一个Login的接口
type BotLogin interface {
Login(bot *Bot) error
Expand Down Expand Up @@ -28,8 +32,9 @@ func (s *SacnLogin) checkLogin(bot *Bot, uuid string) error {
}

type hotLoginOption struct {
withRetry bool
_ struct{}
withRetry bool
syncDuration time.Duration
_ struct{}
}

type HotLoginOptionFunc func(o *hotLoginOption)
Expand All @@ -40,6 +45,13 @@ func HotLoginWithRetry(flag bool) HotLoginOptionFunc {
}
}

// HotLoginWithSyncReloadData 定时同步 HotLogin 的数据
func HotLoginWithSyncReloadData(duration time.Duration) HotLoginOptionFunc {
return func(o *hotLoginOption) {
o.syncDuration = duration
}
}

// HotLogin 热登录模式
type HotLogin struct {
storage HotReloadStorage
Expand All @@ -48,6 +60,17 @@ type HotLogin struct {

// Login 实现了 BotLogin 接口
func (h *HotLogin) Login(bot *Bot) error {
if err := h.loginWrapper(bot); err != nil {
return err
}
if h.opt.syncDuration > 0 {
syncer := NewHotReloadStorageSyncer(bot, h.opt.syncDuration)
go func() { _ = syncer.Sync() }()
}
return nil
}

func (h *HotLogin) loginWrapper(bot *Bot) error {
err := h.login(bot)
if err != nil && h.opt.withRetry {
scanLogin := SacnLogin{}
Expand All @@ -73,6 +96,7 @@ type pushLoginOption struct {
withoutScanCallback bool
withoutLoginCallback bool
withRetry bool
syncDuration time.Duration
}

type PushLoginOptionFunc func(o *pushLoginOption)
Expand Down Expand Up @@ -105,6 +129,13 @@ func PushLoginWithRetry(flag bool) PushLoginOptionFunc {
}
}

// PushLoginWithSyncReloadData 定时同步 PushLogin 的数据
func PushLoginWithSyncReloadData(duration time.Duration) PushLoginOptionFunc {
return func(o *pushLoginOption) {
o.syncDuration = duration
}
}

// defaultPushLoginOpts 默认的 PushLogin
var defaultPushLoginOpts = [...]PushLoginOptionFunc{
PushLoginWithoutUUIDCallback(true),
Expand All @@ -118,7 +149,18 @@ type PushLogin struct {
}

// Login 实现了 BotLogin 接口
func (p PushLogin) Login(bot *Bot) error {
func (p *PushLogin) Login(bot *Bot) error {
if err := p.loginWrapper(bot); err != nil {
return err
}
if p.opt.syncDuration > 0 {
syncer := NewHotReloadStorageSyncer(bot, p.opt.syncDuration)
go func() { _ = syncer.Sync() }()
}
return nil
}

func (p *PushLogin) loginWrapper(bot *Bot) error {
err := p.login(bot)
if err != nil && p.opt.withRetry {
scanLogin := SacnLogin{}
Expand All @@ -127,7 +169,7 @@ func (p PushLogin) Login(bot *Bot) error {
return err
}

func (p PushLogin) login(bot *Bot) error {
func (p *PushLogin) login(bot *Bot) error {
if err := p.pushLoginInit(bot); err != nil {
return err
}
Expand All @@ -141,13 +183,13 @@ func (p PushLogin) login(bot *Bot) error {
return p.checkLogin(bot, resp.UUID)
}

func (p PushLogin) pushLoginInit(bot *Bot) error {
func (p *PushLogin) pushLoginInit(bot *Bot) error {
bot.hotReloadStorage = p.storage
return bot.reload()
}

// checkLogin 登录检查
func (p PushLogin) checkLogin(bot *Bot, uuid string) error {
func (p *PushLogin) checkLogin(bot *Bot, uuid string) error {
bot.uuid = uuid
loginChecker := &LoginChecker{
Bot: bot,
Expand Down
28 changes: 28 additions & 0 deletions stroage.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package openwechat
import (
"io"
"os"
"time"
)

// Storage 身份信息, 维持整个登陆的Session会话
Expand Down Expand Up @@ -75,3 +76,30 @@ func NewJsonFileHotReloadStorage(filename string) io.ReadWriteCloser {
}

var _ HotReloadStorage = (*jsonFileHotReloadStorage)(nil)

type HotReloadStorageSyncer struct {
duration time.Duration
bot *Bot
}

// Sync 定时同步数据到登陆存储中
func (h *HotReloadStorageSyncer) Sync() error {
// 定时器
ticker := time.NewTicker(h.duration)
for {
select {
case <-ticker.C:
// 每隔一段时间, 将数据同步到storage中
if err := h.bot.DumpHotReloadStorage(); err != nil {
return err
}
case <-h.bot.Context().Done():
// 当Bot关闭的时候, 退出循环
return nil
}
}
}

func NewHotReloadStorageSyncer(bot *Bot, duration time.Duration) *HotReloadStorageSyncer {
return &HotReloadStorageSyncer{duration: duration, bot: bot}
}

0 comments on commit 87036e2

Please sign in to comment.