Skip to content

Commit 6ca81f9

Browse files
author
周倩
committed
Release 0.0.4
1 parent e15abac commit 6ca81f9

File tree

2 files changed

+47
-47
lines changed

2 files changed

+47
-47
lines changed

experiment_helper.go

Lines changed: 46 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package sensorsabtest
33
import (
44
"errors"
55
"fmt"
6+
utils2 "github.com/sensorsdata/sa-sdk-go/utils"
67
"reflect"
78
"strconv"
89
"sync"
@@ -16,9 +17,10 @@ import (
1617
// 用户的试验缓存
1718
var experimentCache = lru.New(4096)
1819
var experimentLock = sync.Mutex{}
20+
var experimentTime = lru.New(4096)
1921

2022
// $ABTestTrigger 事件缓存
21-
var eventsCache = lru.New(4096)
23+
var eventsTime = lru.New(4096)
2224
var eventsLock = sync.Mutex{}
2325

2426
// 插件版本号标记位
@@ -58,12 +60,24 @@ func loadExperimentFromNetwork(sensors *SensorsABTest, distinctId string, isLogi
5860

5961
func loadExperimentFromCache(sensors *SensorsABTest, distinctId string, isLoginId bool, requestParam beans.RequestParam, isTrack bool) (error, beans.Experiment) {
6062
var experiment beans.Experiment
61-
experiments, ok := loadExperimentCache(distinctId, isLoginId, requestParam.CustomIDs)
62-
if experiments != nil || ok {
63-
experiment = filterExperiment(requestParam, experiments.([]beans.Experiment))
63+
var isRequestNetwork = false
64+
idKey := getExperimentKey(distinctId, requestParam.CustomIDs, isLoginId)
65+
if isExperimentExpired(idKey, sensors.config.ExperimentCacheTime) {
66+
idKey := getExperimentKey(distinctId, requestParam.CustomIDs, isLoginId)
67+
// 进行清理缓存
68+
experimentCache.Remove(idKey)
69+
isRequestNetwork = true
70+
} else {
71+
experiments, ok := loadExperimentCache(idKey)
72+
if experiments != nil || ok {
73+
experiment = filterExperiment(requestParam, experiments.([]beans.Experiment))
74+
}
75+
if experiments == nil || !ok || experiment.AbtestExperimentId == "" {
76+
isRequestNetwork = true
77+
}
6478
}
6579

66-
if experiments == nil || !ok || experiment.AbtestExperimentId == "" {
80+
if isRequestNetwork {
6781
// 从网络请求试验
6882
experiments, err := requestExperimentOnNetwork(sensors.config.APIUrl, distinctId, isLoginId, requestParam)
6983
if err != nil {
@@ -73,7 +87,7 @@ func loadExperimentFromCache(sensors *SensorsABTest, distinctId string, isLoginI
7387
}
7488

7589
// 缓存试验
76-
saveExperiment2Cache(distinctId, isLoginId, requestParam.CustomIDs, experiments, sensors.config.ExperimentCacheTime)
90+
saveExperiment2Cache(idKey, experiments)
7791
// 筛选试验
7892
experiment = filterExperiment(requestParam, experiments)
7993
}
@@ -120,19 +134,18 @@ func trackABTestEvent(distinctId string, isLoginId bool, experiment beans.Experi
120134
if sensors.config.SensorsAnalytics.C == nil {
121135
return
122136
}
123-
124137
// 是白名单,则不触发 $ABTestTrigger 事件
125138
if experiment.IsWhiteList {
126139
return
127140
}
128-
141+
idEvent := getEventKey(distinctId, customIDs, experiment)
129142
// 如果在缓存中,则不触发 $ABTestTrigger 事件
130-
_, ok := loadEventFromCache(distinctId, customIDs, experiment)
143+
ok := isEventExistAndNotExpired(idEvent, sensors.config.EventCacheTime)
131144
if ok {
132145
return
133146
}
134147

135-
saveEvent2Cache(distinctId, customIDs, experiment, sensors)
148+
saveEvent2Cache(idEvent, sensors)
136149
if properties == nil {
137150
properties = map[string]interface{}{
138151
"$abtest_experiment_id": experiment.AbtestExperimentId,
@@ -149,7 +162,6 @@ func trackABTestEvent(distinctId string, isLoginId bool, experiment beans.Experi
149162
isFirstEvent = false
150163
lastTimeEvent = currentTime
151164
}
152-
153165
err := sensors.sensorsAnalytics.Track(distinctId, "$ABTestTrigger", properties, isLoginId)
154166
if err != nil {
155167
fmt.Println("$ABTestTrigger track failed, error : ", err)
@@ -160,55 +172,51 @@ func trackABTestEvent(distinctId string, isLoginId bool, experiment beans.Experi
160172
// 初始化缓存大小
161173
func initCache(config beans.ABTestConfig) {
162174
if config.EventCacheSize != 0 {
163-
eventsCache = lru.New(config.EventCacheSize)
175+
eventsTime = lru.New(config.EventCacheSize)
164176
}
165177

166178
if config.ExperimentCacheSize != 0 {
167179
experimentCache = lru.New(config.ExperimentCacheSize)
180+
experimentTime = lru.New(config.ExperimentCacheSize)
168181
}
169182
}
170183

171184
// 从缓存读取 $ABTestTrigger
172-
func loadEventFromCache(distinctId string, customIDs map[string]interface{}, experiment beans.Experiment) (interface{}, bool) {
185+
func isEventExistAndNotExpired(idEvent string, timeout time.Duration) bool {
173186
eventsLock.Lock()
174187
defer eventsLock.Unlock()
175-
idEvent := getEventKey(distinctId, customIDs, experiment)
176-
return eventsCache.Get(idEvent)
188+
lastTime, ok := eventsTime.Get(idEvent)
189+
if ok {
190+
return (utils2.NowMs() - lastTime.(int64)) < int64(timeout*time.Minute/time.Millisecond)
191+
}
192+
193+
return false
177194
}
178195

179196
// 保存 $ABTestTrigger 到缓存中
180-
func saveEvent2Cache(distinctId string, customIDs map[string]interface{}, experiment beans.Experiment, sensors *SensorsABTest) {
197+
func saveEvent2Cache(idEvent string, sensors *SensorsABTest) {
181198
// 缓存 $ABTestTrigger 事件
182199
if sensors.config.EnableEventCache {
183200
eventsLock.Lock()
184201
defer eventsLock.Unlock()
185-
idEvent := getEventKey(distinctId, customIDs, experiment)
186-
eventsCache.Add(idEvent, experiment)
187-
// 进行清理缓存
188-
removeCache(idEvent, func(id string) {
189-
eventsCache.Remove(id)
190-
}, sensors.config.EventCacheTime)
202+
eventsTime.Remove(idEvent)
203+
eventsTime.Add(idEvent, utils2.NowMs())
191204
}
192205
}
193206

194207
// 从缓存读取试验
195-
func loadExperimentCache(distinctId string, isLoginId bool, customIds map[string]interface{}) (interface{}, bool) {
208+
func loadExperimentCache(idKey string) (interface{}, bool) {
196209
experimentLock.Lock()
197210
defer experimentLock.Unlock()
198-
idKey := getExperimentKey(distinctId, customIds, isLoginId)
199211
return experimentCache.Get(idKey)
200212
}
201213

202214
// 保存试验到缓存
203-
func saveExperiment2Cache(distinctId string, isLoginId bool, customIds map[string]interface{}, experiments []beans.Experiment, timeout time.Duration) {
215+
func saveExperiment2Cache(idKey string, experiments []beans.Experiment) {
204216
experimentLock.Lock()
205217
defer experimentLock.Unlock()
206-
idKey := getExperimentKey(distinctId, customIds, isLoginId)
207218
experimentCache.Add(idKey, experiments)
208-
// 进行清理缓存
209-
removeCache(idKey, func(id string) {
210-
experimentCache.Remove(id)
211-
}, timeout)
219+
experimentTime.Add(idKey, utils2.NowMs())
212220
}
213221

214222
func castValue(defaultValue interface{}, variables beans.Variables) (interface{}, error) {
@@ -252,22 +260,6 @@ func buildRequestParam(distinctId string, isLoginId bool, requestParam beans.Req
252260
return params
253261
}
254262

255-
// 清理缓存
256-
func removeCache(idExperiment string, removeCache func(id string), timeout time.Duration) {
257-
go func() {
258-
var d time.Duration
259-
if timeout == 0 {
260-
d = 24 * time.Hour
261-
} else {
262-
d = timeout * time.Minute
263-
}
264-
t := time.NewTicker(d)
265-
defer t.Stop()
266-
<-t.C
267-
removeCache(idExperiment)
268-
}()
269-
}
270-
271263
// 拼接缓存唯一标识
272264
func getEventKey(distinctId string, customIds map[string]interface{}, experiment beans.Experiment) string {
273265
return distinctId + "$" + utils.MapToJson(customIds) + "$" + experiment.AbtestExperimentId
@@ -276,3 +268,11 @@ func getEventKey(distinctId string, customIds map[string]interface{}, experiment
276268
func getExperimentKey(distinctId string, customIds map[string]interface{}, isLoginId bool) string {
277269
return distinctId + "$" + utils.MapToJson(customIds) + "$" + strconv.FormatBool(isLoginId)
278270
}
271+
272+
func isExperimentExpired(idKey string, timeout time.Duration) bool {
273+
lastTime, ok := experimentTime.Get(idKey)
274+
if ok {
275+
return (utils2.NowMs() - lastTime.(int64)) > int64(timeout*time.Minute/time.Millisecond)
276+
}
277+
return false
278+
}

sensors_abtesting.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import (
88
)
99

1010
const (
11-
SDK_VERSION = "0.0.3"
11+
SDK_VERSION = "0.0.4"
1212
LIB_NAME = "Golang"
1313
)
1414

0 commit comments

Comments
 (0)