On Mon, Nov 23, 2020 at 6:05 AM 叶志辉 <
yezhihui...@gmail.com> wrote:
>
> A little confused by the test case of `singleflight` of `internal/singleflight`.
>
> Which is the codes singleflight.
>
> 1. wg1
>
> Purpose for wg1 is as commented as:
>
> // At least one goroutine is in fn now and all of them have at
> // least reached the line before the Do.
>
> Confused about `At least one goroutine is in fn `,what test situation for this?
> I mean, for example, if 'no one goroutine is in fn', would be any problem?
The point of the test is to make sure that the singleflight code only
makes a single concurrent call to the function. Writing to c will
cause fn to return. There should only be one goroutine in fn at a
time. Waiting until at least one goroutine is in fn before writing to
c maximizes the possibility of detecting a bug that causes fn to be
called more than once simultaneously.
> 2. the channel `c`
>
> Each `fn` just read from `c`, and write value back, as codes:
>
> v := <-c
> c <- v // pump; make available for any future calls
>
> Don't really get the purpose.
We are testing that fn is only called once concurrently. There can be
multiple calls to fn. Writing a value to the channel after reading
one is an easy way to make sure that the next call to fn will succeed.
> 3. got value
> The expect value of got is: 0<got<N.
>
> Why not 0<got<=N, I mean there is case got==N?
got == n means that every all to g.Do called fn. While that is
technically possible, it is quite unlikely, because the use of wg1
means that all n goroutines will be at least very close to calling
g.Do before fn ever returns. So got == n suggests that fn was called
concurrently by multiple goroutines, which would be a bug.
Ian