Skip to content

Commit d455371

Browse files
committed
Merge pull request #413 from philips/event_history
fix(event_history): fix a bug in event queue
2 parents 70c8c09 + e1d909e commit d455371

File tree

4 files changed

+35
-18
lines changed

4 files changed

+35
-18
lines changed

server/v2/get_handler.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ func GetHandler(w http.ResponseWriter, req *http.Request, s Server) error {
5757
// Start the watcher on the store.
5858
eventChan, err := s.Store().Watch(key, recursive, sinceIndex)
5959
if err != nil {
60-
return etcdErr.NewError(500, key, s.Store().Index())
60+
return err
6161
}
6262

6363
cn, _ := w.(http.CloseNotifier)

store/event_history.go

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -39,26 +39,27 @@ func (eh *EventHistory) addEvent(e *Event) *Event {
3939
return e
4040
}
4141

42-
// scan function is enumerating events from the index in history and
43-
// stops till the first point where the key has identified key
42+
// scan enumerates events from the index history and stops at the first point
43+
// where the key matches.
4444
func (eh *EventHistory) scan(key string, recursive bool, index uint64) (*Event, *etcdErr.Error) {
4545
eh.rwl.RLock()
4646
defer eh.rwl.RUnlock()
4747

48-
// the index should locate after the event history's StartIndex
49-
if index-eh.StartIndex < 0 {
48+
// index should be after the event history's StartIndex
49+
if index < eh.StartIndex {
5050
return nil,
5151
etcdErr.NewError(etcdErr.EcodeEventIndexCleared,
5252
fmt.Sprintf("the requested history has been cleared [%v/%v]",
5353
eh.StartIndex, index), 0)
5454
}
5555

56-
// the index should locate before the size of the queue minus the duplicate count
56+
// the index should come before the size of the queue minus the duplicate count
5757
if index > eh.LastIndex { // future index
5858
return nil, nil
5959
}
6060

61-
i := eh.Queue.Front
61+
offset := index - eh.StartIndex
62+
i := (eh.Queue.Front + int(offset)) % eh.Queue.Capacity
6263

6364
for {
6465
e := eh.Queue.Events[i]
@@ -75,13 +76,13 @@ func (eh *EventHistory) scan(key string, recursive bool, index uint64) (*Event,
7576
ok = ok || strings.HasPrefix(e.Node.Key, key)
7677
}
7778

78-
if ok && index <= e.Index() { // make sure we bypass the smaller one
79+
if ok {
7980
return e, nil
8081
}
8182

8283
i = (i + 1) % eh.Queue.Capacity
8384

84-
if i > eh.Queue.back() {
85+
if i == eh.Queue.Back {
8586
return nil, nil
8687
}
8788
}
@@ -95,6 +96,7 @@ func (eh *EventHistory) clone() *EventHistory {
9596
Events: make([]*Event, eh.Queue.Capacity),
9697
Size: eh.Queue.Size,
9798
Front: eh.Queue.Front,
99+
Back: eh.Queue.Back,
98100
}
99101

100102
for i, e := range eh.Queue.Events {

store/event_queue.go

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,22 +4,17 @@ type eventQueue struct {
44
Events []*Event
55
Size int
66
Front int
7+
Back int
78
Capacity int
89
}
910

10-
func (eq *eventQueue) back() int {
11-
return (eq.Front + eq.Size - 1 + eq.Capacity) % eq.Capacity
12-
}
13-
1411
func (eq *eventQueue) insert(e *Event) {
15-
index := (eq.back() + 1) % eq.Capacity
16-
17-
eq.Events[index] = e
12+
eq.Events[eq.Back] = e
13+
eq.Back = (eq.Back + 1) % eq.Capacity
1814

1915
if eq.Size == eq.Capacity { //dequeue
20-
eq.Front = (index + 1) % eq.Capacity
16+
eq.Front = (eq.Front + 1) % eq.Capacity
2117
} else {
2218
eq.Size++
2319
}
24-
2520
}

store/event_test.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,3 +64,23 @@ func TestScanHistory(t *testing.T) {
6464
t.Fatalf("bad index shoud reuturn nil")
6565
}
6666
}
67+
68+
// TestFullEventQueue tests a queue with capacity = 10
69+
// Add 1000 events into that queue, and test if scanning
70+
// works still for previous events.
71+
func TestFullEventQueue(t *testing.T) {
72+
73+
eh := newEventHistory(10)
74+
75+
// Add
76+
for i := 0; i < 1000; i++ {
77+
e := newEvent(Create, "/foo", uint64(i), uint64(i))
78+
eh.addEvent(e)
79+
e, err := eh.scan("/foo", true, uint64(i-1))
80+
if i > 0 {
81+
if e == nil || err != nil {
82+
t.Fatalf("scan error [/foo] [%v] %v", i-1, i)
83+
}
84+
}
85+
}
86+
}

0 commit comments

Comments
 (0)