diff --git a/debug/buffer/buffer.go b/debug/buffer/buffer.go index 20856582..8c55790c 100644 --- a/debug/buffer/buffer.go +++ b/debug/buffer/buffer.go @@ -3,12 +3,18 @@ package buffer import ( "sync" + "time" ) type Buffer struct { size int sync.RWMutex - vals []interface{} + vals []*Entry +} + +type Entry struct { + Value interface{} + Timestamp time.Time } func (b *Buffer) Put(v interface{}) { @@ -16,7 +22,10 @@ func (b *Buffer) Put(v interface{}) { defer b.Unlock() // append to values - b.vals = append(b.vals, v) + b.vals = append(b.vals, &Entry{ + Value: v, + Timestamp: time.Now(), + }) // trim if bigger than size required if len(b.vals) > b.size { @@ -25,7 +34,7 @@ func (b *Buffer) Put(v interface{}) { } // Get returns the last n entries -func (b *Buffer) Get(n int) []interface{} { +func (b *Buffer) Get(n int) []*Entry { // reset any invalid values if n > b.size || n < 0 { n = b.size @@ -46,6 +55,34 @@ func (b *Buffer) Get(n int) []interface{} { return b.vals[delta:] } +// Return the entries since a specific time +func (b *Buffer) Since(t time.Time) []*Entry { + b.RLock() + defer b.RUnlock() + + // return all the values + if t.IsZero() { + return b.vals + } + + // if its in the future return nothing + if time.Since(t).Seconds() < 0.0 { + return nil + } + + for i, v := range b.vals { + // find the starting point + d := v.Timestamp.Sub(t) + + // return the values + if d.Seconds() > 0.0 { + return b.vals[i:] + } + } + + return nil +} + func (b *Buffer) Size() int { return b.size } diff --git a/debug/buffer/buffer_test.go b/debug/buffer/buffer_test.go index c70935ef..3a107923 100644 --- a/debug/buffer/buffer_test.go +++ b/debug/buffer/buffer_test.go @@ -2,6 +2,7 @@ package buffer import ( "testing" + "time" ) func TestBuffer(t *testing.T) { @@ -11,7 +12,7 @@ func TestBuffer(t *testing.T) { b.Put("foo") v := b.Get(1) - if val := v[0].(string); val != "foo" { + if val := v[0].Value.(string); val != "foo" { t.Fatalf("expected foo got %v", val) } @@ -22,10 +23,11 @@ func TestBuffer(t *testing.T) { b.Put(i) } + d := time.Now() v = b.Get(10) for i := 0; i < 10; i++ { - val := v[i].(int) + val := v[i].Value.(int) if val != i { t.Fatalf("expected %d got %d", i, val) @@ -42,11 +44,36 @@ func TestBuffer(t *testing.T) { v = b.Get(10) for i := 0; i < 10; i++ { - val := v[i].(int) + val := v[i].Value.(int) expect := i * 2 if val != expect { t.Fatalf("expected %d got %d", expect, val) } } + // sleep 100 ms + time.Sleep(time.Millisecond * 100) + + // assume we'll get everything + v = b.Since(d) + + if len(v) != 10 { + t.Fatalf("expected 10 entries but got %d", len(v)) + } + + // write 1 more entry + d = time.Now() + b.Put(100) + + // sleep 100 ms + time.Sleep(time.Millisecond * 100) + + v = b.Since(d) + if len(v) != 1 { + t.Fatalf("expected 1 entries but got %d", len(v)) + } + + if v[0].Value.(int) != 100 { + t.Fatalf("expected value 100 got %v", v[0]) + } }