go-events icon indicating copy to clipboard operation
go-events copied to clipboard

Channel.Write after Channel.Close

Open Adirio opened this issue 7 years ago • 1 comments

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 avatar May 03 '18 12:05 Adirio

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

Adirio avatar May 03 '18 13:05 Adirio