From 3d9d6a9da9699524efd469de12f2751b0e06b2aa Mon Sep 17 00:00:00 2001 From: kercylan98 Date: Thu, 1 Jun 2023 11:35:01 +0800 Subject: [PATCH] =?UTF-8?q?=E6=95=B0=E6=8D=AE=E5=9F=8B=E7=82=B9=E5=AE=9E?= =?UTF-8?q?=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- report/data_buried.go | 42 +++++++++++++++++++++++++++++++++++ report/data_buried_options.go | 12 ++++++++++ report/global_buried.go | 35 +++++++++++++++++++++++++++++ report/hit_logic.go | 32 ++++++++++++++++++++++++++ 4 files changed, 121 insertions(+) create mode 100644 report/data_buried.go create mode 100644 report/data_buried_options.go create mode 100644 report/global_buried.go create mode 100644 report/hit_logic.go diff --git a/report/data_buried.go b/report/data_buried.go new file mode 100644 index 0000000..54545fb --- /dev/null +++ b/report/data_buried.go @@ -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() +} diff --git a/report/data_buried_options.go b/report/data_buried_options.go new file mode 100644 index 0000000..c4bd5f3 --- /dev/null +++ b/report/data_buried_options.go @@ -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]() + } +} diff --git a/report/global_buried.go b/report/global_buried.go new file mode 100644 index 0000000..773bae1 --- /dev/null +++ b/report/global_buried.go @@ -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 +} diff --git a/report/hit_logic.go b/report/hit_logic.go new file mode 100644 index 0000000..76747d1 --- /dev/null +++ b/report/hit_logic.go @@ -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 + } +}