我试图在Go中构建一个包含基于从Web服务收集的数据的报告的小网站。它使用API来查询服务以获取数据。该服务只能每隔几秒查询一次。
但是,我必须多次查询才能获得完整的报告数据。现在,每次调用http处理程序(http.HandleFunc)时,我都会使用API来更新我的整个数据结构。当然,这很糟糕,因为它会触发对受限制的外部API的大量查询。所以,我的报告非常,非常,非常缓慢地出现。
我想要做的是以非阻塞方式使用updateReportData函数并将该数据存储在http.HandleFunc()可以直接摄取的某个变量中而不调用外部API。
但是,我对Go(以及闭包,信号量,并发等等)很新,所以我不确定如何构建它。我应该使用频道吗?我应该使用计时器吗?如何让updateReportData不阻止http.HandleFunc,但仍然以固定的间隔运行?
总而言之,我希望有一个后台例程以固定的间隔更新数据结构,我希望能够使用http.HandleFunc在我发出http请求的任何时候提供数据结构中的任何数据。该程序。我根本不知道如何开始。任何建议将不胜感激。
答案 0 :(得分:3)
您需要做一些事情:
这是一个简化示例,展示了如何使用goroutine和sync.RWMutext
来实现您的目标:
package main
import (
"fmt"
"net/http"
"sync"
"time"
)
var (
timeSumsMu sync.RWMutex
timeSums int64
)
func main() {
// Start the goroutine that will sum the current time
// once per second.
go runDataLoop()
// Create a handler that will read-lock the mutext and
// write the summed time to the client
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
timeSumsMu.RLock()
defer timeSumsMu.RUnlock()
fmt.Fprint(w, timeSums)
})
http.ListenAndServe(":8080", nil)
}
func runDataLoop() {
for {
// Within an infinite loop, lock the mutex and
// increment our value, then sleep for 1 second until
// the next time we need to get a value.
timeSumsMu.Lock()
timeSums += time.Now().Unix()
timeSumsMu.Unlock()
time.Sleep(1 * time.Second)
}
}