docker / go-events

Composable event distribution for Go
Apache License 2.0
132 stars 23 forks source link

Channel.Write after Channel.Close #29

Open Adirio opened 6 years ago

Adirio commented 6 years ago

When calling a Channel sink's Write method after having called its Close method, the select behaviour is non-deterministic, and may result in a valid Write call when it should return ErrSinkClosed.

Example:

chSink := NewChannel(10)
ch := chSink.C
queue := NewQueue(chSink)

for i := 0; i < 50; i++ {
    queue.Write(i)
}

time.Sleep(time.Millisecond)
// 10 elements in then chan, 1 blocked and 39 in the queue events list

chSink.Close()

outer:
for {
    select {
    case i := <-ch:
        fmt.Println(i)
    case <-time.After(time.Second):
        break outer // end the infinite loop whenh there is nothing more to print
    }
}

Output:

0
1
2
3
4
5
6
7
8
9
11
12
16
18
19
22
27
28
35
37
40
42
43
44
45

Expected output: It should only print 0-9. 10 is kind of undefined as its Write function was called before the Close but it got stuck there, so either printing or droping it would be ok. 11-49 should not be printed in any way as their Write method is not called until 10's call finishes and Close is being called before that.

Adirio commented 6 years ago

The tests are not picking this error because they use a 0 buffer, setting it to any other number will make the test fail.