You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I think the design of this function errChan will have potential coroutine blocking problems, which will lead to coroutine leaks.
If more than one goroutine encounters an error, all goroutines will block except for the first error goroutine.
And here is my test demo, which confirmed my guess.
package main
import (
"errors""fmt""sync""time"
)
funcList() error {
wg:= sync.WaitGroup{}
errChan:=make(chanerror, 1)
finished:=make(chanbool, 1)
// arr is form 1 to 10arr:=make([]int, 10)
fori:=0; i<len(arr); i++ {
arr[i] =i+1
}
for_, v:=rangearr {
wg.Add(1)
gofunc(itemint) {
deferwg.Done()
// We assume an even number of entries will get an error// And We send it to errChanifitem%2==0 {
for {
// the select is used to detect whether the coroutine is blocked hereselect {
caseerrChan<-errors.New(fmt.Sprint("error message: ", item)):
returncase<-time.After(time.Second*2):
fmt.Printf("goroutine %d get an error and blocked...\n", item)
}
}
}
}(v)
}
gofunc() {
wg.Wait()
close(finished)
}()
select {
case<-finished:
// If we get more than one error here,// the goroutine that sends the error will be blockedcaseerr:=<-errChan:
returnerr
}
returnnil
}
funcmain() {
iferr:=List(); err!=nil {
fmt.Println("catch error:", err)
}
ch:=make(chanstruct{})
<-ch
}
/*Output:catch error: error message: 6goroutine 10 get an error and blocked...goroutine 8 get an error and blocked...goroutine 4 get an error and blocked...goroutine 8 get an error and blocked...goroutine 10 get an error and blocked...goroutine 4 get an error and blocked...goroutine 10 get an error and blocked...goroutine 8 get an error and blocked...goroutine 4 get an error and blocked...goroutine 4 get an error and blocked...goroutine 8 get an error and blocked...goroutine 10 get an error and blocked...goroutine 10 get an error and blocked...goroutine 8 get an error and blocked...goroutine 4 get an error and blocked...*/
One way to solve this problem is to set errChan's cap to the length of arrary.
And I found that go-zero is use mapreduce to solve this kind of problem about concurrent processing of list data.
And another problem in this file is that if we use the naked goroutine without 'defer recover', the whole application will panic when the naked goroutine get an unpredictable panic.
for example,
package main
import"fmt"// sub-goroutine panic will cause the application to crashfuncmain() {
deferfunc() {
iferr:=recover(); err!=nil {
fmt.Println("catch: ", err)
}
}()
gofunc() {
panic("sub-goroutine panic")
}()
ch:=make(chanstruct{})
<-ch
}
/*Output:panic: sub-goroutine panicgoroutine 6 [running]:main.main.func2() E:/Projects/go/go-cas-demos/goroutine/main.go:14 +0x27created by main.main E:/Projects/go/go-cas-demos/goroutine/main.go:13 +0x4*/
I think we can refer to the design of go-zero, and uniformly use the packaged function to start the coroutine, so as to avoid the collapse of online business.
In the past few days, I am learning the beautiful design of go-zero. If I can, I will submit a pull request to solve these problems.
The text was updated successfully, but these errors were encountered:
iam/internal/apiserver/service/v1/user.go
Lines 44 to 111 in f39d410
I think the design of this function errChan will have potential coroutine blocking problems, which will lead to coroutine leaks.
If more than one goroutine encounters an error, all goroutines will block except for the first error goroutine.
And here is my test demo, which confirmed my guess.
One way to solve this problem is to set errChan's cap to the length of arrary.
And I found that go-zero is use mapreduce to solve this kind of problem about concurrent processing of list data.
And another problem in this file is that if we use the naked goroutine without 'defer recover', the whole application will panic when the naked goroutine get an unpredictable panic.
for example,
I think we can refer to the design of go-zero, and uniformly use the packaged function to start the coroutine, so as to avoid the collapse of online business.
In the past few days, I am learning the beautiful design of go-zero. If I can, I will submit a pull request to solve these problems.
The text was updated successfully, but these errors were encountered: