Beispiel #1
0
Leaflet.prototype.read = function (filename) {
  var self = this,
      output, pipelink;

  if (this.ready === false) {
    return new Error('leaflet object is not ready');
  }

  // absolute paths will be relative to read dir
  filename = trimPath(filename);

  // resolve read and write filepath
  var source = path.resolve(this.options.source, filename);
  var cache = path.resolve(this.options.cache, filename);

  // check ignorefiles list
  if (this.ignorefiles.filepath.indexOf( filename ) !== -1 ||
      this.ignorefiles.filename.indexOf( path.basename(filename) ) !== -1) {

    return streamError("ENOENT, open '" + source + "'", {
      errno: 34,
      code: 'ENOENT',
      path: source,
      ignored: true
    });
  }

  // Get stores properties
  var cacheStat = this.state[filename];

  var memory = getMemory(this, filename);

  // Increase request counter
  memory.request += 1;

  // Read from memory
  if (memory.stream && this.cacheSize) {
    output = this.cache[filename].stream.relay();
    output.pause();

    // Add stat emit to query or emit now if ready
    emitStat(self, filename, output, new Date(cacheStat.mtime));

    return output;
  }

  // in case this file isn't cached but should be cached
  var memorizeFile = (!!cacheStat && resolveCache(this, memory));
  if (memorizeFile) {
    pipelink = memory.stream = flower.memoryStream();

    // since there is no link between memory.relay().resume and source.resume
    // we will source.resume as soon as something has been piped to memory
    pipelink.once('pipe', function (source) {
      source.resume();
    });

    // cleanup cache memory
    pipelink.once('close', function () {
      resolveCache(self, memory);
    });

    // Live refresh memoryStream when source file is updated
    if (this.watching) {
      memory.watch = fs.watch(source, { persistent: false }, function (event) {
        // TODO: what if the file was deleted?
        if (event !== 'change') return;

        var step = memory.stream.modified || 1;

        // refresh memoryStream
        memory.stream = flower.memoryStream();
        memory.stream.modified = step + 1;

        // since there is no link between memory.relay().resume and source.resume
        // we will source.resume as soon as something has been piped to memory
        memory.stream.once('pipe', function (source) {
          source.resume();
        });

        compileSource(self, filename, source, cache, memory.stream);
      });
    }

    output = pipelink.relay();
    output.pause();
  }

  // just read from cache
  if (cacheStat && this.watching === false) {

    if (memorizeFile) {
      fs.createReadStream(cache, { bufferSize: chunkSize }).pipe(pipelink);
    } else {
      output = fs.createReadStream(cache, { bufferSize: chunkSize });
      output.pause();
    }

    // emit stat event to output
    emitStat(self, filename, output, new Date(cacheStat.mtime));

    return output;
  }

  // create a relay stream since async handling will be needed
  if (!memorizeFile) {
    pipelink = output = flower.relayReadStream();
    output.pause();
  }

  // at this point some async opration will be required before the streams can be linked
  // set memory.inProgress flag, so mtime requests will be pushed to query
  if (memorizeFile) {
    memory.inProgress = true;

   emitStat(self, filename, output);
  }

  // has never read from source before or dont need to validate source
  if (!cacheStat || this.watching === false) {
    compileSource(self, filename, source, cache, pipelink);

    return output;
  }

  // check source file for modification
  fs.stat(source, function (error, stat) {
    if (error) {
      updateStat(self, filename);
      return pipelink.emit('error', error);
    }

    // source has been modified, read from source
    if (!cacheStat || stat.mtime.getTime() > cacheStat.mtime || stat.size !== cacheStat.size) {
      return compileSource(self, filename, source, cache, pipelink);
    }

    // stat has not changed execute query
    // note: this could be moved up however since compileSource can be called by
    // two reasons this is the simplest solution
    memory.inProgress = false;
    emitStat(self, filename, output, stat.mtime);

    // source has not been modified, read from cache
    var cacheStream = fs.createReadStream(cache, { bufferSize: chunkSize });
        cacheStream.pause();
        cacheStream.pipe(pipelink);
  });

  // return relay stream, content will be relayed to this shortly
  return output;
};
Beispiel #2
0
var drapper = require('../module.js');
var test = require('tap').test;

var Logger = require('bunyan');
var request = require('request');
var async = require('async');
var flower = require('flower');
var http = require('http');
var fs = require('fs');

// Create a testable bunyan object
var logStream = flower.relayReadStream();
var log = new Logger({
    name: 'test',
    stream: logStream,
    serializers: {
        req: Logger.stdSerializers.req,
        err: Logger.stdSerializers.err,
        res: Logger.stdSerializers.res
    }
});

test("error handling", function (t) {

    t.test('should add a .error function', function (t) {
        t.plan(7);

        // create a pipe router
        var router = drapper({
            error: function (err) {