Skip to content

Commit 0dbc020

Browse files
committed
fix(file_list): Incorrect response after remove and add file
Remove and then immediately add same file can lead to incorrect content in response. Because pending timeout after remove may resolve early then file will be processed, and in response get not processed content.
1 parent 9ef1c81 commit 0dbc020

2 files changed

Lines changed: 41 additions & 10 deletions

File tree

lib/file_list.js

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -111,9 +111,7 @@ var List = function(patterns, excludes, emitter, preprocess, batchInterval) {
111111
};
112112

113113
var resolveDeferred = function(files) {
114-
if (pendingTimeout) {
115-
clearTimeout(pendingTimeout);
116-
}
114+
clearPendingTimeout();
117115

118116
if (!errors.length) {
119117
pendingDeferred.resolve(files || resolveFiles(self.buckets));
@@ -125,9 +123,7 @@ var List = function(patterns, excludes, emitter, preprocess, batchInterval) {
125123
};
126124

127125
var fireEventAndDefer = function() {
128-
if (pendingTimeout) {
129-
clearTimeout(pendingTimeout);
130-
}
126+
clearPendingTimeout();
131127

132128
if (!pendingDeferred) {
133129
pendingDeferred = q.defer();
@@ -137,6 +133,12 @@ var List = function(patterns, excludes, emitter, preprocess, batchInterval) {
137133
pendingTimeout = setTimeout(resolveDeferred, batchInterval);
138134
};
139135

136+
var clearPendingTimeout = function() {
137+
if (pendingTimeout) {
138+
clearTimeout(pendingTimeout);
139+
}
140+
};
141+
140142

141143
// re-glob all the patterns
142144
this.refresh = function() {
@@ -171,9 +173,7 @@ var List = function(patterns, excludes, emitter, preprocess, batchInterval) {
171173
emitter.emit('file_list_modified', pendingDeferred.promise);
172174
}
173175

174-
if (pendingTimeout) {
175-
clearTimeout(pendingTimeout);
176-
}
176+
clearPendingTimeout();
177177

178178
patterns.forEach(function(patternObject, i) {
179179
var pattern = patternObject.pattern;
@@ -302,6 +302,8 @@ var List = function(patterns, excludes, emitter, preprocess, batchInterval) {
302302
var addedFile = new File(path);
303303
buckets[i].push(addedFile);
304304

305+
clearPendingTimeout();
306+
305307
return fs.stat(path, function(err, stat) {
306308
// in the case someone refresh() the list before stat callback
307309
if (self.buckets === buckets) {

test/unit/file_list.spec.coffee

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -589,7 +589,6 @@ describe 'file_list', ->
589589
# Batch Interval processing
590590
#============================================================================
591591
describe 'batch interval', ->
592-
593592
it 'should batch multiple changes within an interval', (done) ->
594593
timeoutSpy = sinon.stub().returns true
595594
globals_ = setTimeout: timeoutSpy
@@ -631,6 +630,36 @@ describe 'file_list', ->
631630
expect(timeoutSpy).to.have.been.called
632631
timeoutSpy.lastCall.args[0]()
633632

633+
it 'should wait while file preprocessing, if file was deleted and immediately added', (done) ->
634+
clock = sinon.useFakeTimers()
635+
636+
m = mocks.loadFile __dirname + '/../../lib/file_list.js', mocks_, global
637+
list = new m.List patterns('/a.*'), [], emitter, preprocessMock, 1000
638+
639+
refreshListAndThen (files) ->
640+
preprocessMock.reset()
641+
642+
emitter.once 'file_list_modified', (promise) ->
643+
expect(promise).to.be.fulfilled.then((files)->
644+
645+
# expect file will be preprocessed when file list promise
646+
# resolved, else we will get incorrect(not processed) content in response
647+
expect(preprocessMock.callCount).to.equal 1
648+
).should.notify(done)
649+
650+
# Remove and then immediately add file to the bucket
651+
list.removeFile '/a.txt'
652+
list.addFile '/a.txt'
653+
654+
# Timed remove pending timeout
655+
# but processing file after add is not completed
656+
clock.tick(1000)
657+
658+
# Finish processing file
659+
process.nextTick -> process.nextTick ->
660+
clock.tick(1000)
661+
662+
clock.tick()
634663

635664
#============================================================================
636665
# Win Globbing

0 commit comments

Comments
 (0)