Refactor Notifier to return channel (#311)

This has two benefits:

1. Using channels makes it easier to time out while waiting
2. Allows us to clean up goroutines that were waiting if we timeout the
   request
This commit is contained in:
Erik Johnston 2017-10-26 11:34:54 +01:00 committed by GitHub
parent e5944e0fdb
commit 49c040c89f
4 changed files with 170 additions and 86 deletions

View file

@ -256,24 +256,22 @@ func TestNewEventAndWasPreviouslyJoinedToRoom(t *testing.T) {
// same as Notifier.WaitForEvents but with a timeout.
func waitForEvents(n *Notifier, req syncRequest) (types.StreamPosition, error) {
done := make(chan types.StreamPosition, 1)
go func() {
newPos := n.WaitForEvents(req, req.since)
done <- newPos
close(done)
}()
listener := n.GetListener(req)
defer listener.Close()
select {
case <-time.After(5 * time.Second):
return types.StreamPosition(0), fmt.Errorf(
"waitForEvents timed out waiting for %s (pos=%d)", req.userID, req.since,
)
case p := <-done:
case <-listener.GetNotifyChannel(req.since):
p := listener.GetStreamPosition()
return p, nil
}
}
// Wait until something is Wait()ing on the user stream.
func waitForBlocking(s *UserStream, numBlocking int) {
func waitForBlocking(s *UserStream, numBlocking uint) {
for numBlocking != s.NumWaiting() {
// This is horrible but I don't want to add a signalling mechanism JUST for testing.
time.Sleep(1 * time.Microsecond)
@ -288,5 +286,6 @@ func newTestSyncRequest(userID string, since types.StreamPosition) syncRequest {
wantFullState: false,
limit: defaultTimelineLimit,
log: util.GetLogger(context.TODO()),
ctx: context.TODO(),
}
}