@@ -36,7 +36,7 @@ var log = logging.Logger("dsqueue")
36
36
// then queued items can remain in memory. When the queue is closed, any
37
37
// remaining items in memory are written to the datastore.
38
38
type DSQueue struct {
39
- close context.CancelFunc
39
+ cancel context.CancelFunc
40
40
closed chan error
41
41
closeOnce sync.Once
42
42
dequeue chan []byte
@@ -54,7 +54,7 @@ func New(ds datastore.Batching, name string, options ...Option) *DSQueue {
54
54
ctx , cancel := context .WithCancel (context .Background ())
55
55
56
56
q := & DSQueue {
57
- close : cancel ,
57
+ cancel : cancel ,
58
58
closed : make (chan error , 1 ),
59
59
dequeue : make (chan []byte ),
60
60
ds : namespace .Wrap (ds , datastore .NewKey ("/dsq-" + name )),
@@ -84,7 +84,7 @@ func (q *DSQueue) Close() error {
84
84
select {
85
85
case <- q .closed :
86
86
case <- timeoutCh :
87
- q .close () // force immediate shutdown
87
+ q .cancel () // force immediate shutdown
88
88
err = <- q .closed
89
89
}
90
90
close (q .dequeue ) // no more output from this queue
@@ -150,21 +150,30 @@ func (q *DSQueue) worker(ctx context.Context, bufferSize, dedupCacheSize int, id
150
150
151
151
defer func () {
152
152
if item != "" {
153
+ // Write the item directly, instead of pushing it to the front of
154
+ // inbuf, in order to retain it's original kay, and therefore the
155
+ // order in the datastore, which may not be empty.
153
156
if err := q .ds .Put (ctx , k , nil ); err != nil {
154
- log .Errorw ("failed to write item to datastore" , "err" , err , "qname" , q .name )
157
+ if ! errors .Is (err , context .Canceled ) {
158
+ log .Errorw ("failed to write item to datastore" , "err" , err , "qname" , q .name )
159
+ }
160
+ q .closed <- fmt .Errorf ("%d items not written to datastore" , 1 + inBuf .Len ())
161
+ return
155
162
}
156
163
}
157
164
if inBuf .Len () != 0 {
158
165
err := q .commitInput (ctx , counter , & inBuf )
159
- if err != nil && ! errors .Is (err , context .Canceled ) {
160
- log .Errorw ("error writing items to datastore" , "err" , err , "qname" , q .name )
166
+ if err != nil {
167
+ if ! errors .Is (err , context .Canceled ) {
168
+ log .Errorw ("error writing items to datastore" , "err" , err , "qname" , q .name )
169
+ }
161
170
if inBuf .Len () != 0 {
162
171
q .closed <- fmt .Errorf ("%d items not written to datastore" , inBuf .Len ())
163
172
}
164
173
}
165
174
}
166
175
if err := q .ds .Sync (ctx , datastore .NewKey ("" )); err != nil {
167
- q . closed <- fmt . Errorf ( "cannot sync datastore: %w" , err )
176
+ log . Errorw ( "failed to sync datastore" , "err" , err , "qname" , q . name )
168
177
}
169
178
}()
170
179
@@ -378,6 +387,10 @@ func (q *DSQueue) getQueueHead(ctx context.Context) (*query.Entry, error) {
378
387
}
379
388
380
389
func (q * DSQueue ) commitInput (ctx context.Context , counter uint64 , items * deque.Deque [string ]) error {
390
+ if ctx .Err () != nil {
391
+ return ctx .Err ()
392
+ }
393
+
381
394
b , err := q .ds .Batch (ctx )
382
395
if err != nil {
383
396
return fmt .Errorf ("failed to create batch: %w" , err )
0 commit comments