Documentation ¶
Index ¶
- Constants
- Variables
- func ClearConcern()
- func GetConcernTypes(site string) (concern_type.Type, error)
- func GetNotifyChan() chan<- Notify
- func ListSite() []string
- func ParseRawSite(rawSite string) (string, error)
- func ParseRawSiteAndType(rawSite string, rawType string) (string, concern_type.Type, error)
- func ReadNotifyChan() <-chan Notify
- func RegisterConcern(c Concern, opts ...OptFunc)
- func StartAll() error
- func StopAll()
- type AtSomeone
- type Concern
- func GetConcernByParseSite(rawSite string) (Concern, error)
- func GetConcernByParseSiteAndType(rawSite, rawType string) (Concern, string, concern_type.Type, error)
- func GetConcernBySite(site string) (Concern, error)
- func GetConcernBySiteAndType(site string, ctype concern_type.Type) (Concern, error)
- func ListConcern() []Concern
- type DefaultCallback
- type DispatchFunc
- type Event
- type FreshFunc
- type GroupConcernAtConfig
- func (g *GroupConcernAtConfig) CheckAtAll(ctype concern_type.Type) bool
- func (g *GroupConcernAtConfig) ClearAtSomeoneList(ctype concern_type.Type)
- func (g *GroupConcernAtConfig) GetAtSomeoneList(ctype concern_type.Type) []int64
- func (g *GroupConcernAtConfig) MergeAtSomeoneList(ctype concern_type.Type, ids []int64)
- func (g *GroupConcernAtConfig) RemoveAtSomeoneList(ctype concern_type.Type, ids []int64)
- func (g *GroupConcernAtConfig) SetAtSomeoneList(ctype concern_type.Type, ids []int64)
- type GroupConcernConfig
- func (g *GroupConcernConfig) AtBeforeHook(notify Notify) *HookResult
- func (g *GroupConcernConfig) FilterHook(notify Notify) *HookResult
- func (g *GroupConcernConfig) GetGroupConcernAt() *GroupConcernAtConfig
- func (g *GroupConcernConfig) GetGroupConcernFilter() *GroupConcernFilterConfig
- func (g *GroupConcernConfig) GetGroupConcernNotify() *GroupConcernNotifyConfig
- func (g *GroupConcernConfig) ShouldSendHook(notify Notify) *HookResult
- func (g *GroupConcernConfig) ToString() string
- func (g *GroupConcernConfig) Validate() error
- type GroupConcernFilterConfig
- type GroupConcernFilterConfigByText
- type GroupConcernFilterConfigByType
- type GroupConcernNotifyConfig
- type Hook
- type HookResult
- type ICallback
- type IConfig
- type IStateManager
- type Identity
- type IdentityInfo
- type KeySet
- type Notify
- type NotifyGeneratorFunc
- type NotifyLiveExt
- type OptFunc
- type PrefixKeySet
- func (p *PrefixKeySet) FreshKey(keys ...interface{}) string
- func (p *PrefixKeySet) GroupAtAllMarkKey(keys ...interface{}) string
- func (p *PrefixKeySet) GroupConcernConfigKey(keys ...interface{}) string
- func (p *PrefixKeySet) GroupConcernStateKey(keys ...interface{}) string
- func (p *PrefixKeySet) ParseGroupConcernStateKey(key string) (groupCode int64, id interface{}, err error)
- type StateManager
- func (c *StateManager) AddGroupConcern(groupCode int64, id interface{}, ctype concern_type.Type) (newCtype concern_type.Type, err error)
- func (c *StateManager) CheckAndSetAtAllMark(groupCode int64, id interface{}) (result bool)
- func (c *StateManager) CheckConcern(id interface{}, ctype concern_type.Type) error
- func (c *StateManager) CheckGroupConcern(groupCode int64, id interface{}, ctype concern_type.Type) error
- func (c *StateManager) DefaultDispatch() DispatchFunc
- func (c *StateManager) Dispatch(wg *sync.WaitGroup, eventChan <-chan Event, notifyChan chan<- Notify)
- func (c *StateManager) EmitQueueEnabled() bool
- func (c *StateManager) EmitQueueFresher(doFresh func(p concern_type.Type, id interface{}) ([]Event, error)) FreshFunc
- func (c *StateManager) Fresh(wg *sync.WaitGroup, eventChan chan<- Event)
- func (c *StateManager) FreshIndex(groups ...int64)
- func (c *StateManager) GetConcern(id interface{}) (result concern_type.Type, err error)
- func (c *StateManager) GetGroupConcern(groupCode int64, id interface{}) (result concern_type.Type, err error)
- func (c *StateManager) GetGroupConcernConfig(groupCode int64, id interface{}) IConfig
- func (c *StateManager) GroupTypeById(ids []interface{}, types []concern_type.Type) ([]interface{}, []concern_type.Type, error)
- func (c *StateManager) ListConcernState(filter func(groupCode int64, id interface{}, p concern_type.Type) bool) (groupCodes []int64, ids []interface{}, idTypes []concern_type.Type, err error)
- func (c *StateManager) Logger() *logrus.Entry
- func (c *StateManager) NotifyGenerator(groupCode int64, event Event) []Notify
- func (c *StateManager) OperateGroupConcernConfig(groupCode int64, id interface{}, cfg IConfig, ...) error
- func (c *StateManager) RemoveAllByGroupCode(groupCode int64) (keys []string, err error)
- func (c *StateManager) RemoveAllById(_id interface{}) (err error)
- func (c *StateManager) RemoveGroupConcern(groupCode int64, id interface{}, ctype concern_type.Type) (newCtype concern_type.Type, err error)
- func (c *StateManager) SetMaxGroupConcern(maxGroupConcern int)
- func (c *StateManager) Start() error
- func (c *StateManager) Stop()
- func (c *StateManager) UseDispatchFunc(dispatchFunc DispatchFunc)
- func (c *StateManager) UseEmitQueue()
- func (c *StateManager) UseFreshFunc(freshFunc FreshFunc)
- func (c *StateManager) UseNotifyGeneratorFunc(notifyGeneratorFunc NotifyGeneratorFunc)
Constants ¶
const ( FilterTypeType = "type" FilterTypeNotType = "not_type" FilterTypeText = "text" )
Variables ¶
var ( ErrAlreadyExists = errors.New("already exists") ErrLengthMismatch = errors.New("length mismatch") ErrTypeNotSupported = errors.New("不支持的类型参数") ErrSiteNotSupported = errors.New("不支持的网站参数") ErrConfigNotSupported = errors.New("不支持的配置") )
var ErrEmitQueueNotInit = errors.New("emit queue not init")
var ErrMaxGroupConcernExceed = errors.New("本群已达到订阅上限")
var HookResultPass = &HookResult{ Pass: true, }
HookResultPass 预定义Pass状态的 HookResult
Functions ¶
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 ParseRawSite ¶
ParseRawSite 解析string格式的site,可以安全处理用户输入的site。 返回匹配的site,如果没有匹配上,返回 ErrSiteNotSupported。
func ParseRawSiteAndType ¶
ParseRawSiteAndType 尝试解析string格式的 site 和 ctype,可以安全处理用户输入的site和ctype。 如果site合法,rawType为空,则默认返回注册时的第一个type。 rawSite 和 rawType 默认为前缀匹配模式,即bi可以匹配bilibili,n可以匹配news。
func RegisterConcern ¶
RegisterConcern 向DDBOT注册一个 Concern。
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 ¶
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 ¶
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。
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 ¶
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 ¶
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 ¶
GroupConcernFilterConfig 过滤器配置
func (*GroupConcernFilterConfig) Empty ¶
func (g *GroupConcernFilterConfig) Empty() bool
func (*GroupConcernFilterConfig) GetFilterByText ¶
func (g *GroupConcernFilterConfig) GetFilterByText() (*GroupConcernFilterConfigByText, error)
func (*GroupConcernFilterConfig) GetFilterByType ¶
func (g *GroupConcernFilterConfig) GetFilterByType() (*GroupConcernFilterConfigByType, error)
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 ¶
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 ¶
NewIdentity 根据 id 和 name 创建新的 Identity
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 ¶
Notify 是对推送的一个抽象,它在 Event 的基础上还包含了推送的接受方信息,例如:qq群号码 Event 产生后,通过 Event + 需要推送的QQ群信息,由 Dispatch 和 NotifyGenerator 产生一组 Notify 因为可能多个群订阅同一个 Event,所以一个 Event 可以产生多个 Notify DDBOT目前只支持向QQ群推送
type NotifyGeneratorFunc ¶
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 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 ¶
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,如果超过订阅上限,则会返回 ErrMaxGroupConcernExceed。 订阅上限可以使用 SetMaxGroupConcern 设置。
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) EmitQueueEnabled ¶ added in v1.0.6
func (c *StateManager) EmitQueueEnabled() bool
EmitQueueEnabled 返回是否使用了EmitQueue
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) (groupCodes []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) SetMaxGroupConcern ¶ added in v1.0.4
func (c *StateManager) SetMaxGroupConcern(maxGroupConcern int)
SetMaxGroupConcern 设置单个群订阅的数量上限,当设置为0或者负数表示无限制。
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) UseFreshFunc ¶
func (c *StateManager) UseFreshFunc(freshFunc FreshFunc)
UseFreshFunc 指定 FreshFunc,启动前必须指定,否则会panic
func (*StateManager) UseNotifyGeneratorFunc ¶
func (c *StateManager) UseNotifyGeneratorFunc(notifyGeneratorFunc NotifyGeneratorFunc)
UseNotifyGeneratorFunc 指定 NotifyGeneratorFunc,启动前必须指定,否则会panic