1 回答

TA貢獻1773條經驗 獲得超3個贊
Go 有一個非常酷的模式,在多個通道上使用for / select 。這允許您使用超時和最大記錄大小來批量寫入距離。使用這種模式需要使用通道。
首先是將您的距離建模為通道:
distances := make(chan Delta)
然后你跟蹤當前批次
var deltas []Delta
然后
ticker := time.NewTicker(time.Second * 5)
var deltas []Delta
for {
select {
case <-ticker.C:
// 5 seconds up flush to db
// reset deltas
case d := <-distances:
deltas = append(deltas, d)
if len(deltas) >= maxDeltasPerFlush {
// flush
// reset deltas
}
}
}
我不知道如何確保距離,所以當我在另一個例程中添加它時,我在其他地方閱讀它,一切都很好?。▎栴}是我想使用 go 頻道并且不知道該怎么做)
如果您打算保留地圖并共享內存,則需要使用互斥(互斥)來保護它,以同步 go 例程之間的訪問。使用通道允許您將副本發送到通道,從而無需跨 Delta 對象進行同步。根據您的架構,您還可以創建由通道連接的 go 例程管道,這可以使其只有一個 go 例程(monitor goroutine)正在訪問Delta,也無需同步。
對于這個問題,我如何安排任務?
使用通道作為傳遞Deltas給不同 go 例程的原語 :)
可能我會添加一個 redis 來存儲所有在線設備,這樣我就可以更快地進行選擇查詢并更新實際的數據庫。還為 redis 添加過期時間,因此如果設備在一段時間內沒有發送和數據,它就會消失!我應該把這段代碼放在哪里?
這取決于您完成的架構。您可以為 select 操作編寫一個裝飾器,它會先檢查 redis,然后再訪問數據庫。此功能的客戶端不必知道這一點。寫操作可以以相同的方式完成:寫入持久存儲,然后使用緩存值和過期時間寫回 redis。使用裝飾器,客戶端不需要知道這一點,他們只需執行讀取和寫入,緩存邏輯將在裝飾器內部實現。有很多方法可以做到這一點,這在很大程度上取決于您的實現在哪里解決。
- 1 回答
- 0 關注
- 176 瀏覽
添加回答
舉報