diff --git a/README.md b/README.md index b628ffe..57266db 100644 --- a/README.md +++ b/README.md @@ -141,4 +141,4 @@ There are other properties that can be read or modified. Take a look in the sour This module was partly inspired by [always-tail](https://github.com/jandre/always-tail) -No care has been given to make this module work on older versions of node. Developed and tested on GNU/Linux. But it should work on other platforms. +No care has been given to make this module work on older versions of node. Tested on Linux and Windows. But it should work on other platforms. diff --git a/tail.js b/tail.js index 91ce535..521368f 100644 --- a/tail.js +++ b/tail.js @@ -150,14 +150,14 @@ class Tail extends EventEmitter { return new Promise( (resolve,reject) =>{ function errorListener( err ){ - this.removeListener('ready', readyListener); - this.removeListener('error', errorListener); + this.removeListener('ready', readyListener); + this.removeListener('error', errorListener); reject( err ); } function readyListener(){ - this.removeListener('ready', readyListener); - this.removeListener('error', errorListener); + this.removeListener('ready', readyListener); + this.removeListener('error', errorListener); resolve(); } @@ -301,14 +301,20 @@ class Tail extends EventEmitter { this.started = filename; - const dirname = path.dirname( this.filename ); - this.watcher = fs.watch( dirname ); + fs.stat(filename, (err,stats) =>{ + this.getStat( err, stats ); - fs.stat(filename, this.getStat.bind(this) ); - this.readStuff(); // Do not wait in case we don't start at the end + // Do not wait in case we don't start at the end + if( !err ) this.readStuff(); + }); + + if( !this.watcher ){ + const dirname = path.dirname( this.filename ); + this.watcher = fs.watch( dirname ); - this.watcher.on('change', this.checkDir.bind(this) ); - this.watcher.on('error', this.onError.bind(this) ); + this.watcher.on('change', this.checkDir.bind(this) ); + this.watcher.on('error', this.onError.bind(this) ); + } if( filename == this.secondary ){ this.emit('secondary', this.secondary); @@ -333,6 +339,7 @@ class Tail extends EventEmitter { onError( err ){ // handle all file and watcher errors this.stop(); + //console.warn( new Error('Emitting error') ); debug( 'Emitting', err ); this.emit( 'error', err ); } @@ -348,7 +355,7 @@ class Tail extends EventEmitter { } if( this.fd ){ - if( this.fd !== 'init' ){ + if( this.fd !== 'init' ){ debug("Closing fd " + this.fd); fs.close( this.fd, err =>{ if( err ) return debug( "closing1 " + err ); @@ -553,7 +560,7 @@ class Tail extends EventEmitter { onEndOfFileForNext(){ debug("End of file for next"); - const err = new Error("End of file"); + const err = new Error("End of file"); err.code = 'EOF'; return this.onLine( err ); } diff --git a/test/tail-test.js b/test/tail-test.js index b0ae3e8..5677b15 100644 --- a/test/tail-test.js +++ b/test/tail-test.js @@ -7,7 +7,6 @@ const tmp = require('tmp'); const path = require('path'); const fs = require('fs'); const util = require('util'); -const unlink = util.promisify(fs.unlink); const open = util.promisify(fs.open); const rename = util.promisify(fs.rename); @@ -28,30 +27,25 @@ function event( emitter, type ){ } after(async()=>{ - await unlink( filename ).catch(X=>{}); - await unlink( secondary ).catch(X=>{}); - dir.removeCallback(); + try{ fs.unlinkSync( filename ) } catch(err){}; + try{ fs.unlinkSync( secondary ) } catch(err){}; }); describe('Tail default', function(){ // Just in case the file exists from previous tests before(async ()=>{ - await unlink( filename ).catch(X=>{}); - await unlink( secondary ).catch(X=>{}); + try{ fs.unlinkSync( filename ) } catch(err){}; + try{ fs.unlinkSync( secondary ) } catch(err){}; return; }); -// afterEach(()=>{ -// if( tail1.stop ) tail1.stop(); -// }); - it("emits error ENOENT if missing", done =>{ const tail1 = new Tail(filename); tail1.once('error', err=>{ - if( err.code == 'ENOENT' ) return done(); tail1.stop(); + if( err.code == 'ENOENT' ) return done(); done( err ); }); tail1.once('ready', X=>{ @@ -62,6 +56,7 @@ describe('Tail default', function(){ }); it("emits ready if file exists", done =>{ + debug('start emits ready if file exists'); const tail1 = new Tail(filename); (async()=>{ const fd = await open( filename, 'a'); @@ -107,6 +102,7 @@ describe('Appending', function(){ const nr = ++cnt; fs.writeSync(t.fd, `Row ${nr}\n`); + fs.fsyncSync(t.fd); const line = await t.tail1.nextLine(); debug("Recieved line " + line ); expect(line).to.be.eql(`Row ${nr}`); @@ -116,6 +112,7 @@ describe('Appending', function(){ const nr = ++cnt; fs.writeSync(t.fd, `Row ${nr}\n`); + fs.fsyncSync(t.fd); const line = await t.tail1.nextLine(); debug("Recieved line " + line ); expect(line).to.be.eql(`Row ${nr}`); @@ -128,6 +125,7 @@ describe('Appending', function(){ debug(`Appending to fd ${t.fd2}`); fs.writeSync(t.fd2, `Row ${nr}\n`); + fs.fsyncSync(t.fd2); const line = await t.tail1.nextLine(); debug("Recieved line " + line ); expect(line).to.be.eql(`Row ${nr}`); @@ -137,6 +135,7 @@ describe('Appending', function(){ const nr = ++cnt; fs.writeSync(t.fd, `Row ${nr}\n`); + fs.fsyncSync(t.fd); const line = await t.tail1.nextLine(); debug("Recieved line " + line ); expect(line).to.be.eql(`Row ${nr}`);