@@ -36,6 +36,8 @@ type SweepingProvider struct {
36
36
closeOnce sync.Once
37
37
done chan struct {}
38
38
closed chan struct {}
39
+
40
+ newItems chan struct {}
39
41
provider internal.Provider
40
42
queue * dsqueue.DSQueue
41
43
batchSize int
@@ -50,6 +52,7 @@ func New(prov internal.Provider, ds datastore.Batching, opts ...Option) *Sweepin
50
52
done : make (chan struct {}),
51
53
closed : make (chan struct {}),
52
54
55
+ newItems : make (chan struct {}, 1 ),
53
56
provider : prov ,
54
57
queue : dsqueue .New (ds , cfg .dsName ,
55
58
dsqueue .WithDedupCacheSize (0 ), // disable deduplication
@@ -133,18 +136,32 @@ func executeOperation(f func(...mh.Multihash) error, keys []mh.Multihash) {
133
136
// It runs in a separate goroutine and continues until the provider is closed.
134
137
func (s * SweepingProvider ) worker () {
135
138
defer close (s .done )
139
+ var emptyQueue bool
136
140
for {
137
- select {
138
- case <- s .closed :
139
- return
140
- default :
141
+ if emptyQueue {
142
+ select {
143
+ case <- s .closed :
144
+ return
145
+ case <- s .newItems :
146
+ }
147
+ emptyQueue = false
148
+ } else {
149
+ select {
150
+ case <- s .closed :
151
+ return
152
+ default :
153
+ }
141
154
}
142
155
143
156
res , err := s .queue .GetN (s .batchSize )
144
157
if err != nil {
145
158
logger .Warnf ("BufferedSweepingProvider unable to dequeue: %v" , err )
146
159
continue
147
160
}
161
+ if len (res ) < s .batchSize {
162
+ // Queue was fully drained.
163
+ emptyQueue = true
164
+ }
148
165
ops , err := getOperations (res )
149
166
if err != nil {
150
167
logger .Warnf ("BufferedSweepingProvider unable to parse dequeued item: %v" , err )
@@ -174,6 +191,10 @@ func (s *SweepingProvider) enqueue(op byte, keys ...mh.Multihash) error {
174
191
return err
175
192
}
176
193
}
194
+ select {
195
+ case s .newItems <- struct {}{}:
196
+ default :
197
+ }
177
198
return nil
178
199
}
179
200
0 commit comments