在golang后端,我想为多个客户端提供一个值,让我们称之为分数。分数随时间而变化,计算速度很慢。计算不依赖于先前的结果。当没有客户时,我根本不想计算它。因此,计算应该只在有要求的情况下进行。但还有另一个事实 - 分数不能在5秒内改变。所以我尝试了不同的建议,一切都有其缺点:
在客户缺席的情况下进行昂贵的计算:
var score interface{}
// run in a separate goroutine
func calculateScorePeriodically() {
for{
select{
case <-time.After(5*time.Second):
score = calculateScoreExpensiveAndSlow()
}
}
}
func serveScore(w http.ResponseWriter, r* http.Request) {
b, _ := json.Marshal(score)
w.Write(b)
}
在很长的计算周期内阻止所有客户端(但实际上可能只是向它们提供旧数据)。而且你不能移动到互斥体之外,因为这样多个客户端可以同时进入计算块,并且不会在5秒间隔内进行计算,而是按顺序进行计算:if
var (
score interface{}
mutex sync.Mutex
updatedAt time.Time
)
func getCachedScore() float64 {
mutex.Lock()
defer mutex.Unlock()
currentTime := time.Now()
if currentTime.Sub(updatedAt) < 5*time.Second {
return score
}
updatedAt = currentTime
score = calculateScoreExpensiveAndSlow()
return score
}
func serveScore(w http.ResponseWriter, r* http.Request) {
b, _ := json.Marshal(getCachedScore())
w.Write(b)
}
如何解决上述两个缺点?
PS.我认为这是一个通用问题,也是一种模式 - 它有一个特殊的名字吗?
largeQ
汪汪一只猫
相关分类