concern

package
v1.0.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 24, 2021 License: AGPL-3.0 Imports: 20 Imported by: 3

Documentation

Index

Constants

View Source
const (
	FilterTypeType    = "type"
	FilterTypeNotType = "not_type"
	FilterTypeText    = "text"
)

Variables

View Source
var (
	ErrAlreadyExists  = errors.New("already exists")
	ErrLengthMismatch = errors.New("length mismatch")

	ErrTypeNotSupported   = errors.New("不支持的类型参数")
	ErrSiteNotSupported   = errors.New("不支持的网站参数")
	ErrConfigNotSupported = errors.New("不支持的配置")
)
View Source
var ErrEmitQueueNotInit = errors.New("emit queue not init")
View Source
var HookResultPass = &HookResult{
	Pass: true,
}

HookResultPass 预定义Pass状态的 HookResult

Functions

func ClearConcern

func ClearConcern()

ClearConcern 现阶段仅用于测试,如果用于其他目的将导致不可预料的后果。

func GetConcernTypes

func GetConcernTypes(site string) (concern_type.Type, error)

GetConcernTypes 根据site查询 Concern,返回 Concern.Types。 如果site没有注册过,则返回 ErrSiteNotSupported。

func GetNotifyChan

func GetNotifyChan() chan<- Notify

GetNotifyChan 推送 channel,所有推送需要发送到这个channel中。

func ListSite

func ListSite() []string

ListSite 返回所有注册的 Concern 支持的site。

func ParseRawSite

func ParseRawSite(rawSite string) (string, error)

ParseRawSite 解析string格式的site,可以安全处理用户输入的site。 返回匹配的site,如果没有匹配上,返回 ErrSiteNotSupported。

func ParseRawSiteAndType

func ParseRawSiteAndType(rawSite string, rawType string) (string, concern_type.Type, error)

ParseRawSiteAndType 尝试解析string格式的 site 和 ctype,可以安全处理用户输入的site和ctype。 如果site合法,rawType为空,则默认返回注册时的第一个type。 rawSite 和 rawType 默认为前缀匹配模式,即bi可以匹配bilibili,n可以匹配news。

func ReadNotifyChan

func ReadNotifyChan() <-chan Notify

ReadNotifyChan 读取推送 channel,应该只由框架负责调用。

func RegisterConcern

func RegisterConcern(c Concern, opts ...OptFunc)

RegisterConcern 向DDBOT注册一个 Concern。

func StartAll

func StartAll() error

StartAll 启动所有 Concern,正常情况下框架会负责启动。

func StopAll

func StopAll()

StopAll 停止所有Concern模块,正常情况下框架会负责停止。 会关闭notifyChan,所以停止后禁止再向notifyChan中写入数据。

Types

type AtSomeone

type AtSomeone struct {
	Ctype  concern_type.Type `json:"ctype"`
	AtList []int64           `json:"at_list"`
}

type Concern

type Concern interface {
	// Site 必须全局唯一,不允许注册两个相同的site
	Site() string
	// Types 返回该 Concern 支持的 concern_type.Type,此处返回的每一项必须是单个type,并且第一个type为默认type
	Types() []concern_type.Type
	// Start 启动 Concern 模块,记得调用 StateManager.Start
	Start() error
	// Stop 停止 Concern 模块,记得调用 StateManager.Stop
	Stop()
	// ParseId 会解析一个id,此处返回的id类型,即是其他地方id interface{}的类型
	// 其他所有地方的id都由此函数生成
	// 推荐在string 或者 int64类型中选择其一
	// 如果订阅源有uid等数字唯一标识,请选择int64,如 bilibili
	// 如果订阅源有数字并且有字符,请选择string, 如 douyu
	ParseId(string) (interface{}, error)

	// Add 添加一个订阅
	Add(ctx mmsg.IMsgCtx, groupCode int64, id interface{}, ctype concern_type.Type) (IdentityInfo, error)
	// Remove 删除一个订阅
	Remove(ctx mmsg.IMsgCtx, groupCode int64, id interface{}, ctype concern_type.Type) (IdentityInfo, error)
	// Get 获取一个订阅信息
	Get(id interface{}) (IdentityInfo, error)

	// GetStateManager 获取 IStateManager
	GetStateManager() IStateManager
	// FreshIndex 刷新 group 的 index,通常不需要用户主动调用,StateManager.FreshIndex 有默认实现。
	FreshIndex(groupCode ...int64)
}

Concern 是DDBOT的一个完整订阅模块,包含一个订阅源的全部信息 当一个 Concern 编写完成后,需要使用 concern.RegisterConcern 向DDBOT注册才能生效

func GetConcernByParseSite

func GetConcernByParseSite(rawSite string) (Concern, error)

GetConcernByParseSite 尝试解析string格式的 site,默认为前缀匹配模式。

func GetConcernByParseSiteAndType

func GetConcernByParseSiteAndType(rawSite, rawType string) (Concern, string, concern_type.Type, error)

GetConcernByParseSiteAndType 尝试解析string格式的 site 和 ctype,可以安全处理用户输入的site和ctype, 并返回 Concern,site,ctype。 默认为前缀匹配模式

func GetConcernBySite

func GetConcernBySite(site string) (Concern, error)

GetConcernBySite 根据site返回 Concern。 如果site没有注册过,则会返回 ErrSiteNotSupported。

func GetConcernBySiteAndType

func GetConcernBySiteAndType(site string, ctype concern_type.Type) (Concern, error)

GetConcernBySiteAndType 根据site和ctype返回 Concern。 如果site没有注册过,则会返回 ErrSiteNotSupported; 如果site注册过,但不支持指定的ctype,则会返回 ErrTypeNotSupported。

func ListConcern

func ListConcern() []Concern

ListConcern 返回所有注册过的 Concern。

type DefaultCallback

type DefaultCallback struct {
}

DefaultCallback ICallback 的默认实现,默认为空

func (DefaultCallback) NotifyAfterCallback

func (d DefaultCallback) NotifyAfterCallback(notify Notify, message *message.GroupMessage)

NotifyAfterCallback stub

func (DefaultCallback) NotifyBeforeCallback

func (d DefaultCallback) NotifyBeforeCallback(notify Notify)

NotifyBeforeCallback stub

type DispatchFunc

type DispatchFunc func(event <-chan Event, notify chan<- Notify)

DispatchFunc 是 IStateManager.Dispatch 函数的具体逻辑 它从event channel中获取 Event,把 Event 转变成(可能多个) Notify 并发送到notify channel

StateManager 可以使用 StateManager.UseDispatchFunc 来指定一个 DispatchFunc StateManager 中有一个默认实现,适用于绝大多数情况,请参考 StateManager.DefaultDispatch

type Event

type Event interface {
	Site() string
	Type() concern_type.Type
	GetUid() interface{}
	Logger() *logrus.Entry
}

Event 是对事件的一个抽象,它可以表示发表动态,发表微博,发布文章,发布视频,是订阅对象做出的行为 通常是由一个爬虫负责产生,例如:当b站主播发布了新动态的时候,爬虫抓到这条动态,就产生了一个 Event Event 不应该关联推送的接收方的信息,例如:不应含有qq群号码

type FreshFunc

type FreshFunc func(ctx context.Context, eventChan chan<- Event)

FreshFunc 是 IStateManager.Fresh 函数的具体逻辑,没有具体的限制 对于大多数网站来说,它的逻辑是访问网页获取数据,和和之前的数据对比,判断新数据,产生 Event 发送给 eventChan

使用 StateManager 时,在 StateManager.Start 之前,必须使用 StateManager.UseFreshFunc 来指定一个 FreshFunc, 否则会发生 panic

type GroupConcernAtConfig

type GroupConcernAtConfig struct {
	AtAll     concern_type.Type `json:"at_all"`
	AtSomeone []*AtSomeone      `json:"at_someone"`
}

GroupConcernAtConfig @配置

func (*GroupConcernAtConfig) CheckAtAll

func (g *GroupConcernAtConfig) CheckAtAll(ctype concern_type.Type) bool

func (*GroupConcernAtConfig) ClearAtSomeoneList

func (g *GroupConcernAtConfig) ClearAtSomeoneList(ctype concern_type.Type)

func (*GroupConcernAtConfig) GetAtSomeoneList

func (g *GroupConcernAtConfig) GetAtSomeoneList(ctype concern_type.Type) []int64

func (*GroupConcernAtConfig) MergeAtSomeoneList

func (g *GroupConcernAtConfig) MergeAtSomeoneList(ctype concern_type.Type, ids []int64)

func (*GroupConcernAtConfig) RemoveAtSomeoneList

func (g *GroupConcernAtConfig) RemoveAtSomeoneList(ctype concern_type.Type, ids []int64)

func (*GroupConcernAtConfig) SetAtSomeoneList

func (g *GroupConcernAtConfig) SetAtSomeoneList(ctype concern_type.Type, ids []int64)

type GroupConcernConfig

type GroupConcernConfig struct {
	DefaultCallback
	GroupConcernAt     GroupConcernAtConfig     `json:"group_concern_at"`
	GroupConcernNotify GroupConcernNotifyConfig `json:"group_concern_notify"`
	GroupConcernFilter GroupConcernFilterConfig `json:"group_concern_filter"`
}

GroupConcernConfig 实现了 IConfig,并附带一些默认逻辑 如果 Notify 有实现 NotifyLiveExt,则会使用默认逻辑

func NewGroupConcernConfigFromString

func NewGroupConcernConfigFromString(s string) (*GroupConcernConfig, error)

NewGroupConcernConfigFromString 从json格式反序列化 GroupConcernConfig

func (*GroupConcernConfig) AtBeforeHook

func (g *GroupConcernConfig) AtBeforeHook(notify Notify) *HookResult

AtBeforeHook 默认为Pass 当 Notify 实现了 NotifyLiveExt,则仅有上播(Living && LiveStatusChanged 均为true)的时候会Pass

func (*GroupConcernConfig) FilterHook

func (g *GroupConcernConfig) FilterHook(notify Notify) *HookResult

FilterHook 默认支持filter text配置,其他为Pass,可以重写这个函数实现自定义的过滤 b站推送使用这个Hook来支持配置动态类型的过滤(过滤转发动态等)

func (*GroupConcernConfig) GetGroupConcernAt

func (g *GroupConcernConfig) GetGroupConcernAt() *GroupConcernAtConfig

GetGroupConcernAt 返回 GroupConcernAtConfig,总是返回 non-nil

func (*GroupConcernConfig) GetGroupConcernFilter

func (g *GroupConcernConfig) GetGroupConcernFilter() *GroupConcernFilterConfig

GetGroupConcernFilter 返回 GroupConcernFilterConfig,总是返回 non-nil

func (*GroupConcernConfig) GetGroupConcernNotify

func (g *GroupConcernConfig) GetGroupConcernNotify() *GroupConcernNotifyConfig

GetGroupConcernNotify 返回 GroupConcernNotifyConfig,总是返回 non-nil

func (*GroupConcernConfig) ShouldSendHook

func (g *GroupConcernConfig) ShouldSendHook(notify Notify) *HookResult

ShouldSendHook 默认为Pass

func (*GroupConcernConfig) ToString

func (g *GroupConcernConfig) ToString() string

ToString 将 GroupConcernConfig 通过json序列化成string

func (*GroupConcernConfig) Validate

func (g *GroupConcernConfig) Validate() error

Validate 可以在此自定义config校验,每次对config修改后会在同一个事务中调用,如果返回non-nil,则改动会回滚,此次操作失败 默认支持 GroupConcernNotifyConfig GroupConcernAtConfig GroupConcernFilterConfig 默认只支持 text

type GroupConcernFilterConfig

type GroupConcernFilterConfig struct {
	Type   string `json:"type"`
	Config string `json:"config"`
}

GroupConcernFilterConfig 过滤器配置

func (*GroupConcernFilterConfig) Empty

func (g *GroupConcernFilterConfig) Empty() bool

func (*GroupConcernFilterConfig) GetFilterByText

func (*GroupConcernFilterConfig) GetFilterByType

type GroupConcernFilterConfigByText

type GroupConcernFilterConfigByText struct {
	Text []string `json:"text"`
}

func (*GroupConcernFilterConfigByText) ToString

func (g *GroupConcernFilterConfigByText) ToString() string

type GroupConcernFilterConfigByType

type GroupConcernFilterConfigByType struct {
	Type []string `json:"type"`
}

func (*GroupConcernFilterConfigByType) ToString

func (g *GroupConcernFilterConfigByType) ToString() string

type GroupConcernNotifyConfig

type GroupConcernNotifyConfig struct {
	TitleChangeNotify concern_type.Type `json:"title_change_notify"`
	OfflineNotify     concern_type.Type `json:"offline_notify"`
}

GroupConcernNotifyConfig 推送配置

func (*GroupConcernNotifyConfig) CheckOfflineNotify

func (g *GroupConcernNotifyConfig) CheckOfflineNotify(ctype concern_type.Type) bool

func (*GroupConcernNotifyConfig) CheckTitleChangeNotify

func (g *GroupConcernNotifyConfig) CheckTitleChangeNotify(ctype concern_type.Type) bool

type Hook

type Hook interface {
	// FilterHook 是更细粒度的过滤,可以根据这条推送的内容、文案来判断是否应该推送
	// 例如b站的动态类型过滤就是使用了 FilterHook
	FilterHook(notify Notify) *HookResult
	// AtBeforeHook 控制是否应该执行@操作,注意即使通过了也并不代表一定会@,还需要配置@才可以
	// 如果没有配置,则没有@的对象,也就不会进行@
	AtBeforeHook(notify Notify) *HookResult
	// ShouldSendHook 根据 Notify 本身的状态(而非推送的文案、内容)决定是否进行推送
	// 例如上播推送,下播推送
	// 如果要根据推送的文案、内容判断,则应该使用 FilterHook
	ShouldSendHook(notify Notify) *HookResult
}

Hook 定义了一些对 Notify 进行推送过程中的拦截器

type HookResult

type HookResult struct {
	Pass   bool
	Reason string
}

HookResult 定义了 Hook 的结果,Pass是false的时候,要把具体失败的地方填入Reason

func (*HookResult) PassOrReason

func (h *HookResult) PassOrReason(pass bool, reason string)

PassOrReason 如果pass为true,则 HookResult 为true,否则设置 HookResult 的 Reason

type ICallback

type ICallback interface {
	// NotifyBeforeCallback 会在 Notify 推送前获取推送文案内容之前最后一刻进行调用
	// 所以在这个callback里还可以对 Notify 推送内容进行修改
	// b站推送使用了这个callback进行缩略推送
	NotifyBeforeCallback(notify Notify)
	// NotifyAfterCallback 会在 Notify 推送后第一时间进行调用
	NotifyAfterCallback(notify Notify, message *message.GroupMessage)
}

ICallback 定义了一些针对 Notify 推送前后的 callback

type IConfig

type IConfig interface {
	Validate() error
	GetGroupConcernAt() *GroupConcernAtConfig
	GetGroupConcernNotify() *GroupConcernNotifyConfig
	GetGroupConcernFilter() *GroupConcernFilterConfig
	ICallback
	Hook
}

IConfig 定义了Config的通用接口 TODO 需要一种支持自定义配置的方法,要怎么样做呢

type IStateManager

type IStateManager interface {
	GetGroupConcernConfig(groupCode int64, id interface{}) (concernConfig IConfig)
	OperateGroupConcernConfig(groupCode int64, id interface{}, cfg IConfig, f func(concernConfig IConfig) bool) error

	GetGroupConcern(groupCode int64, id interface{}) (result concern_type.Type, err error)
	GetConcern(id interface{}) (result concern_type.Type, err error)

	CheckAndSetAtAllMark(groupCode int64, id interface{}) (result bool)
	CheckGroupConcern(groupCode int64, id interface{}, ctype concern_type.Type) error
	CheckConcern(id interface{}, ctype concern_type.Type) error

	AddGroupConcern(groupCode int64, id interface{}, ctype concern_type.Type) (newCtype concern_type.Type, err error)
	RemoveGroupConcern(groupCode int64, id interface{}, ctype concern_type.Type) (newCtype concern_type.Type, err error)
	RemoveAllByGroupCode(groupCode int64) (keys []string, err error)

	ListConcernState(filter func(groupCode int64, id interface{}, p concern_type.Type) bool) (idGroups []int64,
		ids []interface{}, idTypes []concern_type.Type, err error)
	GroupTypeById(ids []interface{}, types []concern_type.Type) ([]interface{}, []concern_type.Type, error)

	// NotifyGenerator 从 Event 产生多个 Notify
	NotifyGenerator(groupCode int64, event Event) []Notify
	// Fresh 是一个长生命周期的函数,它产生 Event
	Fresh(wg *sync.WaitGroup, eventChan chan<- Event)
	// Dispatch 是一个长生命周期的函数,它从event channel中获取 Event, 并产生 Notify 发送到notify channel
	Dispatch(wg *sync.WaitGroup, event <-chan Event, notify chan<- Notify)
}

type Identity

type Identity struct {
	// contains filtered or unexported fields
}

Identity 是一个 IdentityInfo 的默认实现

func NewIdentity

func NewIdentity(id interface{}, name string) *Identity

NewIdentity 根据 id 和 name 创建新的 Identity

func (*Identity) GetName

func (i *Identity) GetName() string

GetName 返回 name

func (*Identity) GetUid

func (i *Identity) GetUid() interface{}

GetUid 返回 uid

type IdentityInfo

type IdentityInfo interface {
	// GetUid 返回订阅对象的id
	GetUid() interface{}
	// GetName 返回订阅对象的名字
	GetName() string
}

IdentityInfo 表示订阅对象的信息,包括名字,ID

type KeySet

type KeySet interface {
	GroupConcernStateKey(keys ...interface{}) string
	GroupConcernConfigKey(keys ...interface{}) string
	FreshKey(keys ...interface{}) string
	GroupAtAllMarkKey(keys ...interface{}) string
	ParseGroupConcernStateKey(key string) (groupCode int64, id interface{}, err error)
}

KeySet 是不同 StateManager 之间用来彼此隔离的一个接口。 通常 StateManager 会创建多个,用于不同的 Concern 模块,所以创建 StateManager 的时候需要指定 KeySet。 大多数情况下可以方便的使用内置实现 PrefixKeySet。

type Notify

type Notify interface {
	Event
	GetGroupCode() int64
	ToMessage() *mmsg.MSG
}

Notify 是对推送的一个抽象,它在 Event 的基础上还包含了推送的接受方信息,例如:qq群号码 Event 产生后,通过 Event + 需要推送的QQ群信息,由 Dispatch 和 NotifyGenerator 产生一组 Notify 因为可能多个群订阅同一个 Event,所以一个 Event 可以产生多个 Notify DDBOT目前只支持向QQ群推送

type NotifyGeneratorFunc

type NotifyGeneratorFunc func(groupCode int64, event Event) []Notify

NotifyGeneratorFunc 是 IStateManager.NotifyGenerator 函数的具体逻辑 它针对一组 groupCode 把 Event 转变成一组 Notify

使用 StateManager 时,在 StateManager.Start 之前, 必须使用 StateManager.UseNotifyGeneratorFunc 来指定一个 NotifyGeneratorFunc, 否则会发生 panic

type NotifyLiveExt

type NotifyLiveExt interface {
	// IsLive 如果返回false则不会使用扩展逻辑
	IsLive() bool
	// Living 表示是否正在直播,注意有些网站在主播未直播的时候会循环播放主播的投稿或者直播回放
	// 这种情况不能算做正在直播
	Living() bool
	// TitleChanged 表示是否直播标题发生变换,当开启了OfflineNotify配置时会推送这个消息,默认为不推送
	TitleChanged() bool
	// LiveStatusChanged 表示是否直播状态发生了变化,这个配合 Living 可以用来判断是上播还是下播
	// 如果没有变化也可以发送给DDBOT,DDBOT会自动进行过滤
	LiveStatusChanged() bool
}

NotifyLiveExt 是一个针对直播推送过滤的扩展接口, Notify 可以选择性实现这个接口,如果实现了,则会自动使用默认的推送过滤逻辑 默认情况下,如果 IsLive 为 true,则根据以下规则推送: Living 为 true 且 LiveStatusChanged 为true(说明是开播了)进行推送 Living 为 false 且 LiveStatusChanged 为true(说明是下播了)根据 OfflineNotify 配置进行推送推送 Living 为 true 且 LiveStatusChanged 为false 且 TitleChanged 为true(说明是上播状态更改标题)根据 TitleChangeNotify 配置进行推送推送 如果 Notify 没有实现这个接口,则会推送所有内容

type OptFunc

type OptFunc func(opt *option) *option

OptFunc 预留的扩展字段,暂无用处

type PrefixKeySet

type PrefixKeySet struct {
	// contains filtered or unexported fields
}

PrefixKeySet 是 KeySet 的一个默认实现,它使用一个唯一的前缀彼此区分。

func NewPrefixKeySetWithInt64ID

func NewPrefixKeySetWithInt64ID(prefix string) *PrefixKeySet

NewPrefixKeySetWithInt64ID 根据 prefix 创建一个使用 int64 格式的id的 PrefixKeySet id的格式需要与 Concern.ParseId 返回的格式一致 prefix 可以简单地使用 Concern.Site

func NewPrefixKeySetWithStringID

func NewPrefixKeySetWithStringID(prefix string) *PrefixKeySet

NewPrefixKeySetWithStringID 根据 prefix 创建一个使用 string 格式的id的 PrefixKeySet id的格式需要与 Concern.ParseId 返回的格式一致 prefix 可以简单地使用 Concern.Site

func (*PrefixKeySet) FreshKey

func (p *PrefixKeySet) FreshKey(keys ...interface{}) string

func (*PrefixKeySet) GroupAtAllMarkKey

func (p *PrefixKeySet) GroupAtAllMarkKey(keys ...interface{}) string

func (*PrefixKeySet) GroupConcernConfigKey

func (p *PrefixKeySet) GroupConcernConfigKey(keys ...interface{}) string

func (*PrefixKeySet) GroupConcernStateKey

func (p *PrefixKeySet) GroupConcernStateKey(keys ...interface{}) string

func (*PrefixKeySet) ParseGroupConcernStateKey

func (p *PrefixKeySet) ParseGroupConcernStateKey(key string) (groupCode int64, id interface{}, err error)

type StateManager

type StateManager struct {
	*localdb.ShortCut
	KeySet
	// contains filtered or unexported fields
}

StateManager 定义了一些通用的状态行为,例如添加订阅,删除订阅,查询订阅, 还默认集成了一种定时刷新策略,“每隔几秒钟刷新一个id”(即:轮询)这个策略,开箱即用,如果不需要使用,也可以自定义策略。 StateManager 是每个 Concern 之间隔离的,不同的订阅源必须持有不同的 StateManager, 操作一个 StateManager 时不会对其他 StateManager 内的数据产生影响, 读取当前 StateManager 内的订阅时,也不会获取到其他 StateManager 内的订阅。

StateManager 通过 KeySet 来隔离存储的数据,创建 StateManager 时必须使用唯一的 KeySet, 请通过 NewStateManagerWithStringID / NewStateManagerWithInt64ID / NewStateManagerWithCustomKey 来创建 StateManager。

func NewStateManagerWithCustomKey

func NewStateManagerWithCustomKey(name string, keySet KeySet, notifyChan chan<- Notify) *StateManager

NewStateManagerWithCustomKey 使用自定义的 KeySet 创建 StateManager, 如果不关心 KeySet,推荐使用 NewStateManagerWithStringID 或者 NewStateManagerWithInt64ID name 可以简单地使用 Concern.Site

func NewStateManagerWithInt64ID

func NewStateManagerWithInt64ID(name string, notifyChan chan<- Notify) *StateManager

NewStateManagerWithInt64ID 创建新的 StateManager,会使用 NewPrefixKeySetWithInt64ID 创建 KeySet ID的格式必须与 Concern.ParseId 返回的格式匹配 name 可以简单地使用 Concern.Site

func NewStateManagerWithStringID

func NewStateManagerWithStringID(name string, notifyChan chan<- Notify) *StateManager

NewStateManagerWithStringID 创建新的 StateManager,会使用 NewPrefixKeySetWithStringID 创建 KeySet ID的格式必须与 Concern.ParseId 返回的格式匹配 name 可以简单地使用 Concern.Site

func (*StateManager) AddGroupConcern

func (c *StateManager) AddGroupConcern(groupCode int64, id interface{}, ctype concern_type.Type) (newCtype concern_type.Type, err error)

AddGroupConcern 在group内添加id的ctype订阅,多次添加同样的订阅会返回 ErrAlreadyExists

func (*StateManager) CheckAndSetAtAllMark

func (c *StateManager) CheckAndSetAtAllMark(groupCode int64, id interface{}) (result bool)

CheckAndSetAtAllMark 检查@全体标记是否过期,未设置过或已过期返回true,并重置标记,否则返回false。 因为@全体有次数限制,并且较为恼人,故设置标记,两次@全体之间必须有间隔。

func (*StateManager) CheckConcern

func (c *StateManager) CheckConcern(id interface{}, ctype concern_type.Type) error

CheckConcern 检查是否有任意一个群添加过id的ctype订阅,如果添加过,返回 ErrAlreadyExists

func (*StateManager) CheckGroupConcern

func (c *StateManager) CheckGroupConcern(groupCode int64, id interface{}, ctype concern_type.Type) error

CheckGroupConcern 检查group是否已经添加过id的ctype订阅,如果添加过,返回 ErrAlreadyExists

func (*StateManager) DefaultDispatch

func (c *StateManager) DefaultDispatch() DispatchFunc

DefaultDispatch 是 DispatchFunc 的默认实现。 它查询所有订阅过此 Event.GetUid 与 Event.Type 的群,并为每个群生成 Notify 发送给框架

func (*StateManager) Dispatch

func (c *StateManager) Dispatch(wg *sync.WaitGroup, eventChan <-chan Event, notifyChan chan<- Notify)

func (*StateManager) EmitQueueFresher

func (c *StateManager) EmitQueueFresher(doFresh func(p concern_type.Type, id interface{}) ([]Event, error)) FreshFunc

EmitQueueFresher 如果使用的是EmitQueue,则可以使用这个helper来产生一个Fresher

func (*StateManager) Fresh

func (c *StateManager) Fresh(wg *sync.WaitGroup, eventChan chan<- Event)

func (*StateManager) FreshIndex

func (c *StateManager) FreshIndex(groups ...int64)

FreshIndex 刷新 group 的 index,通常不需要用户主动调用 在单元测试中有时候需要主动刷新 index,否则遍历时会返回 buntdb.ErrNotFound

func (*StateManager) GetConcern

func (c *StateManager) GetConcern(id interface{}) (result concern_type.Type, err error)

GetConcern 查询一个id在所有group内的 concern_type.Type

func (*StateManager) GetGroupConcern

func (c *StateManager) GetGroupConcern(groupCode int64, id interface{}) (result concern_type.Type, err error)

GetGroupConcern 返回一个id在群内的所有 concern_type.Type

func (*StateManager) GetGroupConcernConfig

func (c *StateManager) GetGroupConcernConfig(groupCode int64, id interface{}) IConfig

GetGroupConcernConfig 总是返回non-nil

func (*StateManager) GroupTypeById

func (c *StateManager) GroupTypeById(ids []interface{}, types []concern_type.Type) ([]interface{}, []concern_type.Type, error)

GroupTypeById 按id聚合ctype,通常是配合 ListConcernState 使用,把 ListConcernState 返回的订阅按id聚合

func (*StateManager) ListConcernState

func (c *StateManager) ListConcernState(filter func(groupCode int64, id interface{}, p concern_type.Type) bool) (idGroups []int64, ids []interface{}, idTypes []concern_type.Type, err error)

ListConcernState 遍历所有订阅,并根据 filter 返回需要的订阅

func (*StateManager) Logger

func (c *StateManager) Logger() *logrus.Entry

func (*StateManager) NotifyGenerator

func (c *StateManager) NotifyGenerator(groupCode int64, event Event) []Notify

func (*StateManager) OperateGroupConcernConfig

func (c *StateManager) OperateGroupConcernConfig(groupCode int64, id interface{}, cfg IConfig, f func(concernConfig IConfig) bool) error

OperateGroupConcernConfig 在一个rw事务中获取GroupConcernConfig并交给函数,如果返回true,就保存GroupConcernConfig,否则就回滚。

func (*StateManager) RemoveAllByGroupCode

func (c *StateManager) RemoveAllByGroupCode(groupCode int64) (keys []string, err error)

RemoveAllByGroupCode 删除一个group内所有订阅

func (*StateManager) RemoveAllById

func (c *StateManager) RemoveAllById(_id interface{}) (err error)

func (*StateManager) RemoveGroupConcern

func (c *StateManager) RemoveGroupConcern(groupCode int64, id interface{}, ctype concern_type.Type) (newCtype concern_type.Type, err error)

RemoveGroupConcern 在group内删除id的ctype订阅,并返回删除后当前id的在群内的ctype,删除不存在的订阅会返回 buntdb.ErrNotFound

func (*StateManager) Start

func (c *StateManager) Start() error

Start 启动 StateManager,别忘记在 Concern.Start 中启动 启动前需要指定 FreshFunc 与 NotifyGeneratorFunc,否则会panic

func (*StateManager) Stop

func (c *StateManager) Stop()

Stop 停止 StateManager,别忘记在 Concern.Stop 中停止

func (*StateManager) UseDispatchFunc

func (c *StateManager) UseDispatchFunc(dispatchFunc DispatchFunc)

UseDispatchFunc 指定 DispatchFunc,如果启动时没有指定,则会使用默认实现 DefaultDispatch

func (*StateManager) UseEmitQueue

func (c *StateManager) UseEmitQueue()

UseEmitQueue 启用EmitQueue

func (*StateManager) UseFreshFunc

func (c *StateManager) UseFreshFunc(freshFunc FreshFunc)

UseFreshFunc 指定 FreshFunc,启动前必须指定,否则会panic

func (*StateManager) UseNotifyGeneratorFunc

func (c *StateManager) UseNotifyGeneratorFunc(notifyGeneratorFunc NotifyGeneratorFunc)

UseNotifyGeneratorFunc 指定 NotifyGeneratorFunc,启动前必须指定,否则会panic

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL