Skip to content

Commit 9ac83ef

Browse files
authored
Add PeekChan() (#14)
* Add PeekChan() based on nsqio@2cb4338 * Add peekchan test
1 parent bb13b3d commit 9ac83ef

File tree

2 files changed

+90
-0
lines changed

2 files changed

+90
-0
lines changed

diskqueue.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ func (l LogLevel) String() string {
5353
type Interface interface {
5454
Put([]byte) error
5555
ReadChan() <-chan []byte // this is expected to be an *unbuffered* channel
56+
PeekChan() <-chan []byte // this is expected to be an *unbuffered* channel
5657
Close() error
5758
Delete() error
5859
Depth() int64
@@ -102,6 +103,9 @@ type diskQueue struct {
102103
// exposed via ReadChan()
103104
readChan chan []byte
104105

106+
// exposed via PeekChan()
107+
peekChan chan []byte
108+
105109
// internal channels
106110
depthChan chan int64
107111
writeChan chan []byte
@@ -148,6 +152,7 @@ func NewWithDiskSpace(name string, dataPath string,
148152
minMsgSize: minMsgSize,
149153
maxMsgSize: maxMsgSize,
150154
readChan: make(chan []byte),
155+
peekChan: make(chan []byte),
151156
depthChan: make(chan int64),
152157
writeChan: make(chan []byte),
153158
writeResponseChan: make(chan error),
@@ -196,6 +201,10 @@ func (d *diskQueue) start() error {
196201
return nil
197202
}
198203

204+
func (d *diskQueue) PeekChan() <-chan []byte {
205+
return d.peekChan
206+
}
207+
199208
// Depth returns the depth of the queue
200209
func (d *diskQueue) Depth() int64 {
201210
depth, ok := <-d.depthChan
@@ -988,6 +997,7 @@ func (d *diskQueue) ioLoop() {
988997
var err error
989998
var count int64
990999
var r chan []byte
1000+
var p chan []byte
9911001

9921002
syncTicker := time.NewTicker(d.syncTimeout)
9931003

@@ -1016,13 +1026,16 @@ func (d *diskQueue) ioLoop() {
10161026
}
10171027
}
10181028
r = d.readChan
1029+
p = d.peekChan
10191030
} else {
10201031
r = nil
1032+
p = nil
10211033
}
10221034

10231035
select {
10241036
// the Go channel spec dictates that nil channel operations (read or write)
10251037
// in a select are skipped, we set r to d.readChan only when there is data to read
1038+
case p <- dataRead:
10261039
case r <- dataRead:
10271040
count++
10281041
// moveForward sets needSync flag if a file is removed

diskqueue_test.go

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1260,3 +1260,80 @@ func benchmarkDiskQueueGet(size int64, b *testing.B) {
12601260
<-dq.ReadChan()
12611261
}
12621262
}
1263+
1264+
func TestDiskQueuePeek(t *testing.T) {
1265+
l := NewTestLogger(t)
1266+
dqName := "test_disk_queue_peek" + strconv.Itoa(int(time.Now().Unix()))
1267+
tmpDir, err := ioutil.TempDir("", fmt.Sprintf("nsq-test-%d", time.Now().UnixNano()))
1268+
if err != nil {
1269+
panic(err)
1270+
}
1271+
defer os.RemoveAll(tmpDir)
1272+
msg := bytes.Repeat([]byte{0}, 10)
1273+
ml := int64(len(msg))
1274+
dq := New(dqName, tmpDir, 10*(ml+4), int32(ml), 1<<10, 2500, 2*time.Second, l)
1275+
defer dq.Close()
1276+
NotNil(t, dq)
1277+
Equal(t, int64(0), dq.Depth())
1278+
1279+
t.Run("roll", func(t *testing.T) {
1280+
for i := 0; i < 10; i++ {
1281+
err := dq.Put(msg)
1282+
Nil(t, err)
1283+
Equal(t, int64(i+1), dq.Depth())
1284+
}
1285+
1286+
for i := 10; i > 0; i-- {
1287+
Equal(t, msg, <-dq.PeekChan())
1288+
Equal(t, int64(i), dq.Depth())
1289+
1290+
Equal(t, msg, <-dq.ReadChan())
1291+
Equal(t, int64(i-1), dq.Depth())
1292+
}
1293+
1294+
Nil(t, dq.Empty())
1295+
})
1296+
1297+
t.Run("peek-read", func(t *testing.T) {
1298+
for i := 0; i < 10; i++ {
1299+
err := dq.Put(msg)
1300+
Nil(t, err)
1301+
Equal(t, int64(i+1), dq.Depth())
1302+
}
1303+
1304+
for i := 10; i > 0; i-- {
1305+
Equal(t, msg, <-dq.PeekChan())
1306+
Equal(t, int64(i), dq.Depth())
1307+
1308+
Equal(t, msg, <-dq.PeekChan())
1309+
Equal(t, int64(i), dq.Depth())
1310+
1311+
Equal(t, msg, <-dq.ReadChan())
1312+
Equal(t, int64(i-1), dq.Depth())
1313+
}
1314+
1315+
Nil(t, dq.Empty())
1316+
})
1317+
1318+
t.Run("read-peek", func(t *testing.T) {
1319+
for i := 0; i < 10; i++ {
1320+
err := dq.Put(msg)
1321+
Nil(t, err)
1322+
Equal(t, int64(i+1), dq.Depth())
1323+
}
1324+
1325+
for i := 10; i > 1; i-- {
1326+
Equal(t, msg, <-dq.PeekChan())
1327+
Equal(t, int64(i), dq.Depth())
1328+
1329+
Equal(t, msg, <-dq.ReadChan())
1330+
Equal(t, int64(i-1), dq.Depth())
1331+
1332+
Equal(t, msg, <-dq.PeekChan())
1333+
Equal(t, int64(i-1), dq.Depth())
1334+
}
1335+
1336+
Nil(t, dq.Empty())
1337+
})
1338+
1339+
}

0 commit comments

Comments
 (0)