cmd/syncthing, lib/events, lib/sync: Add timeout to REST event API, remove Ping (fixes #3933)
GitHub-Pull-Request: https://github.com/syncthing/syncthing/pull/3941
This commit is contained in:
@@ -10,7 +10,6 @@ package events
|
||||
import (
|
||||
"errors"
|
||||
"runtime"
|
||||
stdsync "sync"
|
||||
"time"
|
||||
|
||||
"github.com/syncthing/syncthing/lib/sync"
|
||||
@@ -19,8 +18,7 @@ import (
|
||||
type EventType int
|
||||
|
||||
const (
|
||||
Ping EventType = 1 << iota
|
||||
Starting
|
||||
Starting EventType = 1 << iota
|
||||
StartupComplete
|
||||
DeviceDiscovered
|
||||
DeviceConnected
|
||||
@@ -55,8 +53,6 @@ var runningTests = false
|
||||
|
||||
func (t EventType) String() string {
|
||||
switch t {
|
||||
case Ping:
|
||||
return "Ping"
|
||||
case Starting:
|
||||
return "Starting"
|
||||
case StartupComplete:
|
||||
@@ -279,11 +275,11 @@ type bufferedSubscription struct {
|
||||
next int
|
||||
cur int // Current SubscriptionID
|
||||
mut sync.Mutex
|
||||
cond *stdsync.Cond
|
||||
cond *sync.TimeoutCond
|
||||
}
|
||||
|
||||
type BufferedSubscription interface {
|
||||
Since(id int, into []Event) []Event
|
||||
Since(id int, into []Event, timeout time.Duration) []Event
|
||||
}
|
||||
|
||||
func NewBufferedSubscription(s *Subscription, size int) BufferedSubscription {
|
||||
@@ -292,7 +288,7 @@ func NewBufferedSubscription(s *Subscription, size int) BufferedSubscription {
|
||||
buf: make([]Event, size),
|
||||
mut: sync.NewMutex(),
|
||||
}
|
||||
bs.cond = stdsync.NewCond(bs.mut)
|
||||
bs.cond = sync.NewTimeoutCond(bs.mut)
|
||||
go bs.pollingLoop()
|
||||
return bs
|
||||
}
|
||||
@@ -319,12 +315,21 @@ func (s *bufferedSubscription) pollingLoop() {
|
||||
}
|
||||
}
|
||||
|
||||
func (s *bufferedSubscription) Since(id int, into []Event) []Event {
|
||||
func (s *bufferedSubscription) Since(id int, into []Event, timeout time.Duration) []Event {
|
||||
s.mut.Lock()
|
||||
defer s.mut.Unlock()
|
||||
|
||||
for id >= s.cur {
|
||||
s.cond.Wait()
|
||||
// Check once first before generating the TimeoutCondWaiter
|
||||
if id >= s.cur {
|
||||
waiter := s.cond.SetupWait(timeout)
|
||||
defer waiter.Stop()
|
||||
|
||||
for id >= s.cur {
|
||||
if eventsAvailable := waiter.Wait(); !eventsAvailable {
|
||||
// Timed out
|
||||
return into
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for i := s.next; i < len(s.buf); i++ {
|
||||
|
||||
@@ -219,7 +219,7 @@ func TestBufferedSub(t *testing.T) {
|
||||
|
||||
recv := 0
|
||||
for recv < 10*BufferSize {
|
||||
evs := bs.Since(recv, nil)
|
||||
evs := bs.Since(recv, nil, time.Minute)
|
||||
for _, ev := range evs {
|
||||
if ev.GlobalID != recv+1 {
|
||||
t.Fatalf("Incorrect ID; %d != %d", ev.GlobalID, recv+1)
|
||||
@@ -252,7 +252,7 @@ func BenchmarkBufferedSub(b *testing.B) {
|
||||
recv := 0
|
||||
var evs []Event
|
||||
for i := 0; i < b.N; {
|
||||
evs = bs.Since(recv, evs[:0])
|
||||
evs = bs.Since(recv, evs[:0], time.Minute)
|
||||
for _, ev := range evs {
|
||||
if ev.GlobalID != recv+1 {
|
||||
done <- fmt.Errorf("skipped event %v %v", ev.GlobalID, recv)
|
||||
@@ -299,7 +299,7 @@ func TestSinceUsesSubscriptionId(t *testing.T) {
|
||||
// delivered to the buffered subscription when we get here.
|
||||
t0 := time.Now()
|
||||
for time.Since(t0) < time.Second {
|
||||
events := bs.Since(0, nil)
|
||||
events := bs.Since(0, nil, time.Minute)
|
||||
if len(events) == 2 {
|
||||
break
|
||||
}
|
||||
@@ -308,7 +308,7 @@ func TestSinceUsesSubscriptionId(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
events := bs.Since(1, nil)
|
||||
events := bs.Since(1, nil, time.Minute)
|
||||
if len(events) != 1 {
|
||||
t.Fatal("Incorrect number of events:", len(events))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user