Fix events timeout errors

Resetting the timeout doesn't fully cut it, as it may timeout after we
got an event and be delivered later. This should fix it well enough for
the moment. https://github.com/golang/go/issues/11513
This commit is contained in:
Jakob Borg 2015-08-24 09:38:39 +02:00
parent 98effcd8e3
commit d6e34761dc
2 changed files with 18 additions and 3 deletions

View File

@ -188,12 +188,19 @@ func (s *Subscription) Poll(timeout time.Duration) (Event, error) {
dl.Debugln("poll", timeout) dl.Debugln("poll", timeout)
} }
s.timeout.Reset(timeout) if !s.timeout.Reset(timeout) {
select {
case <-s.timeout.C:
default:
}
}
select { select {
case e, ok := <-s.events: case e, ok := <-s.events:
if !ok { if !ok {
return e, ErrClosed return e, ErrClosed
} }
s.timeout.Stop()
return e, nil return e, nil
case <-s.timeout.C: case <-s.timeout.C:
return Event{}, ErrTimeout return Event{}, ErrTimeout

View File

@ -14,7 +14,7 @@ import (
"github.com/syncthing/syncthing/lib/events" "github.com/syncthing/syncthing/lib/events"
) )
const timeout = 500 * time.Millisecond const timeout = 100 * time.Millisecond
func TestNewLogger(t *testing.T) { func TestNewLogger(t *testing.T) {
l := events.NewLogger() l := events.NewLogger()
@ -26,6 +26,7 @@ func TestNewLogger(t *testing.T) {
func TestSubscriber(t *testing.T) { func TestSubscriber(t *testing.T) {
l := events.NewLogger() l := events.NewLogger()
s := l.Subscribe(0) s := l.Subscribe(0)
defer l.Unsubscribe(s)
if s == nil { if s == nil {
t.Fatal("Unexpected nil Subscription") t.Fatal("Unexpected nil Subscription")
} }
@ -34,6 +35,7 @@ func TestSubscriber(t *testing.T) {
func TestTimeout(t *testing.T) { func TestTimeout(t *testing.T) {
l := events.NewLogger() l := events.NewLogger()
s := l.Subscribe(0) s := l.Subscribe(0)
defer l.Unsubscribe(s)
_, err := s.Poll(timeout) _, err := s.Poll(timeout)
if err != events.ErrTimeout { if err != events.ErrTimeout {
t.Fatal("Unexpected non-Timeout error:", err) t.Fatal("Unexpected non-Timeout error:", err)
@ -45,6 +47,7 @@ func TestEventBeforeSubscribe(t *testing.T) {
l.Log(events.DeviceConnected, "foo") l.Log(events.DeviceConnected, "foo")
s := l.Subscribe(0) s := l.Subscribe(0)
defer l.Unsubscribe(s)
_, err := s.Poll(timeout) _, err := s.Poll(timeout)
if err != events.ErrTimeout { if err != events.ErrTimeout {
@ -56,6 +59,7 @@ func TestEventAfterSubscribe(t *testing.T) {
l := events.NewLogger() l := events.NewLogger()
s := l.Subscribe(events.AllEvents) s := l.Subscribe(events.AllEvents)
defer l.Unsubscribe(s)
l.Log(events.DeviceConnected, "foo") l.Log(events.DeviceConnected, "foo")
ev, err := s.Poll(timeout) ev, err := s.Poll(timeout)
@ -80,6 +84,7 @@ func TestEventAfterSubscribeIgnoreMask(t *testing.T) {
l := events.NewLogger() l := events.NewLogger()
s := l.Subscribe(events.DeviceDisconnected) s := l.Subscribe(events.DeviceDisconnected)
defer l.Unsubscribe(s)
l.Log(events.DeviceConnected, "foo") l.Log(events.DeviceConnected, "foo")
_, err := s.Poll(timeout) _, err := s.Poll(timeout)
@ -91,7 +96,8 @@ func TestEventAfterSubscribeIgnoreMask(t *testing.T) {
func TestBufferOverflow(t *testing.T) { func TestBufferOverflow(t *testing.T) {
l := events.NewLogger() l := events.NewLogger()
_ = l.Subscribe(events.AllEvents) s := l.Subscribe(events.AllEvents)
defer l.Unsubscribe(s)
t0 := time.Now() t0 := time.Now()
for i := 0; i < events.BufferSize*2; i++ { for i := 0; i < events.BufferSize*2; i++ {
@ -126,6 +132,7 @@ func TestIDs(t *testing.T) {
l := events.NewLogger() l := events.NewLogger()
s := l.Subscribe(events.AllEvents) s := l.Subscribe(events.AllEvents)
defer l.Unsubscribe(s)
l.Log(events.DeviceConnected, "foo") l.Log(events.DeviceConnected, "foo")
l.Log(events.DeviceConnected, "bar") l.Log(events.DeviceConnected, "bar")
@ -154,6 +161,7 @@ func TestBufferedSub(t *testing.T) {
l := events.NewLogger() l := events.NewLogger()
s := l.Subscribe(events.AllEvents) s := l.Subscribe(events.AllEvents)
defer l.Unsubscribe(s)
bs := events.NewBufferedSubscription(s, 10*events.BufferSize) bs := events.NewBufferedSubscription(s, 10*events.BufferSize)
go func() { go func() {