@@ -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,33 @@ 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
+ case <- s .newItems :
153
+ default :
154
+ }
141
155
}
142
156
143
157
res , err := s .queue .GetN (s .batchSize )
144
158
if err != nil {
145
159
logger .Warnf ("BufferedSweepingProvider unable to dequeue: %v" , err )
146
160
continue
147
161
}
162
+ if len (res ) < s .batchSize {
163
+ // Queue was fully drained.
164
+ emptyQueue = true
165
+ }
148
166
ops , err := getOperations (res )
149
167
if err != nil {
150
168
logger .Warnf ("BufferedSweepingProvider unable to parse dequeued item: %v" , err )
@@ -174,6 +192,10 @@ func (s *SweepingProvider) enqueue(op byte, keys ...mh.Multihash) error {
174
192
return err
175
193
}
176
194
}
195
+ select {
196
+ case s .newItems <- struct {}{}:
197
+ default :
198
+ }
177
199
return nil
178
200
}
179
201
0 commit comments