我在服務器端的方法中有以下代碼,它將流回應發送回客戶端。
var cfg = "..." // comes from request parameters
var clientId = "...." // comes from request parameters
var data = allCids.([]int64)
// can we run this in parallel with X number of workers?
for _, cid := range data {
pd := repo.GetCustomerData(strconv.FormatInt(cid, 10))
if !pd.IsCorrect {
continue
}
resources := us.helperCom.GenerateResourceString(pd)
val, _ := us.GenerateInfo(clientId, resources, cfg)
if err := stream.Send(val); err != nil {
log.Printf("send error %v", err)
}
}
我的困惑是我們可以讓它同時運行嗎?還是流媒體總是以單執行緒方式運行?
uj5u.com熱心網友回復:
您可以使作業并發,但不能使流上的發送并發。來自grpc-go檔案:
使用流時,必須注意避免從不同的 goroutine 對同一個 Stream呼叫一次
SendMsg或RecvMsg多次。[...]
因此,您可以在單獨的 goroutine 中運行并發代碼,并在公共通道上發送輸出值。然后,主流處理程式在此通道上進行范圍并按stream.Send 順序呼叫- 所以請記住,只有當網路回應花費的時間少于獲取資料時,所有這些都是值得的。
代碼如下所示:
// buffered, so the workers can send and exit immediately
out := make(chan <type of val>, len(data))
// you will have to close the out chan when all work is done
wg := &sync.WaitGroup{}
wg.Add(len(data))
go func() {
wg.Wait()
close(out)
}()
for _, cid := range data {
// don't close around the loop variable
go func (id int64) {
defer wg.Done()
val, err := // obtain output value somehow
if err != nil {
return
}
out <- val
}(cid)
}
for val := range out {
if err := stream.Send(val); err != nil {
log.Printf("send error %v", err)
}
}
goroutine 的數量是data. 如果要控制 goroutine 的數量,請使用 batch data。如果這樣做,請相應地調整通道緩沖區。
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/438848.html
