aboutsummaryrefslogtreecommitdiffstats
path: root/event/feed.go
diff options
context:
space:
mode:
authorFelix Lange <fjl@users.noreply.github.com>2018-05-10 18:26:36 +0800
committerPéter Szilágyi <peterke@gmail.com>2018-05-10 18:26:36 +0800
commit53a18d2e2734d078200ec607055ae551245ae74b (patch)
tree0281d5d7a186cc6d79c237091b607d35a510746a /event/feed.go
parent7beccb29becf439df7bf4c033a94c019ad25bead (diff)
downloadgo-tangerine-53a18d2e2734d078200ec607055ae551245ae74b.tar
go-tangerine-53a18d2e2734d078200ec607055ae551245ae74b.tar.gz
go-tangerine-53a18d2e2734d078200ec607055ae551245ae74b.tar.bz2
go-tangerine-53a18d2e2734d078200ec607055ae551245ae74b.tar.lz
go-tangerine-53a18d2e2734d078200ec607055ae551245ae74b.tar.xz
go-tangerine-53a18d2e2734d078200ec607055ae551245ae74b.tar.zst
go-tangerine-53a18d2e2734d078200ec607055ae551245ae74b.zip
event: document select case slice use and add edge case test (#16680)
Feed keeps active subscription channels in a slice called 'f.sendCases'. The Send method tracks the active cases in a local variable 'cases' whose value is f.sendCases initially. 'cases' shrinks to a shorter prefix of f.sendCases every time a send succeeds, moving the successful case out of range of the active case list. This can be confusing because the two slices share a backing array. Add more comments to document what is going on. Also add a test for removing a case that is in 'f.sentCases' but not 'cases'.
Diffstat (limited to 'event/feed.go')
-rw-r--r--event/feed.go5
1 files changed, 4 insertions, 1 deletions
diff --git a/event/feed.go b/event/feed.go
index 78fa3d98d..f578f00c1 100644
--- a/event/feed.go
+++ b/event/feed.go
@@ -148,7 +148,9 @@ func (f *Feed) Send(value interface{}) (nsent int) {
f.sendCases[i].Send = rvalue
}
- // Send until all channels except removeSub have been chosen.
+ // Send until all channels except removeSub have been chosen. 'cases' tracks a prefix
+ // of sendCases. When a send succeeds, the corresponding case moves to the end of
+ // 'cases' and it shrinks by one element.
cases := f.sendCases
for {
// Fast path: try sending without blocking before adding to the select set.
@@ -170,6 +172,7 @@ func (f *Feed) Send(value interface{}) (nsent int) {
index := f.sendCases.find(recv.Interface())
f.sendCases = f.sendCases.delete(index)
if index >= 0 && index < len(cases) {
+ // Shrink 'cases' too because the removed case was still active.
cases = f.sendCases[:len(cases)-1]
}
} else {