数据埋点实现
This commit is contained in:
parent
6def300d4a
commit
3d9d6a9da9
|
@ -0,0 +1,42 @@
|
||||||
|
package report
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/kercylan98/minotaur/utils/asynchronization"
|
||||||
|
"github.com/kercylan98/minotaur/utils/hash"
|
||||||
|
)
|
||||||
|
|
||||||
|
// NewDataBuried 创建一个数据埋点
|
||||||
|
func NewDataBuried[DataID comparable, Data any](hitLogic HitLogic[Data], options ...DataBuriedOption[DataID, Data]) *DataBuried[DataID, Data] {
|
||||||
|
buried := &DataBuried[DataID, Data]{
|
||||||
|
data: asynchronization.NewMap[DataID, Data](),
|
||||||
|
hitLogic: hitLogic,
|
||||||
|
}
|
||||||
|
for _, option := range options {
|
||||||
|
option(buried)
|
||||||
|
}
|
||||||
|
return buried
|
||||||
|
}
|
||||||
|
|
||||||
|
// DataBuried 数据埋点
|
||||||
|
// - 数据埋点通常用于统计不同类型的数据,例如用户数据、商城数据等
|
||||||
|
type DataBuried[DataID comparable, Data any] struct {
|
||||||
|
data hash.Map[DataID, Data]
|
||||||
|
hitLogic HitLogic[Data]
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hit 命中数据埋点
|
||||||
|
func (slf *DataBuried[DataID, Data]) Hit(id DataID, data Data) {
|
||||||
|
slf.data.Atom(func(m hash.Map[DataID, Data]) {
|
||||||
|
m.Set(id, slf.hitLogic(m.Get(id), data))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetData 获取数据
|
||||||
|
func (slf *DataBuried[DataID, Data]) GetData(id DataID) Data {
|
||||||
|
return slf.data.Get(id)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetSize 获取已触发该埋点的id数量
|
||||||
|
func (slf *DataBuried[DataID, Data]) GetSize() int {
|
||||||
|
return slf.data.Size()
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
package report
|
||||||
|
|
||||||
|
import "github.com/kercylan98/minotaur/utils/synchronization"
|
||||||
|
|
||||||
|
type DataBuriedOption[DataID comparable, Data any] func(buried *DataBuried[DataID, Data])
|
||||||
|
|
||||||
|
// WithDataBuriedSync 通过并发安全的方式创建数据埋点
|
||||||
|
func WithDataBuriedSync[DataId comparable, Data any]() DataBuriedOption[DataId, Data] {
|
||||||
|
return func(buried *DataBuried[DataId, Data]) {
|
||||||
|
buried.data = synchronization.NewMap[DataId, Data]()
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,35 @@
|
||||||
|
package report
|
||||||
|
|
||||||
|
import (
|
||||||
|
"sync"
|
||||||
|
)
|
||||||
|
|
||||||
|
// NewGlobalBuried 创建一个全局埋点
|
||||||
|
func NewGlobalBuried[Data any](hitLogic HitLogic[Data]) *GlobalBuried[Data] {
|
||||||
|
return &GlobalBuried[Data]{
|
||||||
|
hitLogic: hitLogic,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// GlobalBuried 全局埋点
|
||||||
|
// - 天然并发安全
|
||||||
|
// - 全局埋点适用于活跃用户数等统计
|
||||||
|
type GlobalBuried[Data any] struct {
|
||||||
|
rw sync.RWMutex
|
||||||
|
data Data
|
||||||
|
hitLogic HitLogic[Data]
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hit 命中数据埋点
|
||||||
|
func (slf *GlobalBuried[Data]) Hit(data Data) {
|
||||||
|
slf.rw.Lock()
|
||||||
|
defer slf.rw.Unlock()
|
||||||
|
slf.data = slf.hitLogic(slf.data, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetData 获取数据
|
||||||
|
func (slf *GlobalBuried[Data]) GetData() Data {
|
||||||
|
slf.rw.RLock()
|
||||||
|
defer slf.rw.RUnlock()
|
||||||
|
return slf.data
|
||||||
|
}
|
|
@ -0,0 +1,32 @@
|
||||||
|
package report
|
||||||
|
|
||||||
|
import "github.com/kercylan98/minotaur/utils/generic"
|
||||||
|
|
||||||
|
// HitLogic 埋点命中逻辑
|
||||||
|
// - data: 当前数据
|
||||||
|
// - input: 新输入的数据
|
||||||
|
// - return: 设置当前数据
|
||||||
|
type HitLogic[Data any] func(data Data, input Data) Data
|
||||||
|
|
||||||
|
// WithHitLogicCustomize 通过自定义命中处理逻辑处理命中事件
|
||||||
|
// - 通过对旧数据和新数据的处理,将返回的值作为新的数据值
|
||||||
|
func WithHitLogicCustomize[Data any](logic func(data Data, input Data) Data) HitLogic[Data] {
|
||||||
|
return func(data Data, input Data) Data {
|
||||||
|
return logic(data, input)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithHitLogicCover 通过覆盖原数值的方式处理命中事件
|
||||||
|
func WithHitLogicCover[Data any]() HitLogic[Data] {
|
||||||
|
return func(data Data, input Data) Data {
|
||||||
|
return input
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithHitLogicOverlay 通过数值叠加的方式处理命中事件
|
||||||
|
// - 例如原始值为100,新输入为200,最终结果为300
|
||||||
|
func WithHitLogicOverlay[Data generic.Number]() HitLogic[Data] {
|
||||||
|
return func(data Data, input Data) Data {
|
||||||
|
return data + input
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue