github.com/webonyx/up@v0.7.4-0.20180808230834-91b94e551323/internal/shim/index.js (about)

     1  
     2  var child = require('child_process');
     3  var byline = require('./byline');
     4  
     5  /**
     6   * Debug env var.
     7   */
     8  
     9  const debug = process.env.DEBUG_SHIM;
    10  
    11  /**
    12   * A map of string(id) to callback function, used for when
    13   * many concurrent requests are outstanding.
    14   */
    15  
    16  var callbacks = {};
    17  
    18  /**
    19   * The last id attached to a request / callback pair
    20   */
    21  
    22  var lastId = (Date.now() / 1000) | 0;
    23  
    24  /**
    25   * nextId generates ids which will only be repeated every 2^52 times being generated
    26   */
    27  
    28  function nextId(){
    29    // Prevent bugs where integer precision wraps around on floating point numbers
    30    // (usually around 52-53 bits)
    31    var id = (lastId + 1) | 0;
    32    if (id === lastId) {
    33      id = 1;
    34    }
    35    lastId = id;
    36    return String(id);
    37  }
    38  
    39  /**
    40   * Child process for binary I/O.
    41   */
    42  
    43  var proc = child.spawn('./main', { stdio: ['pipe', 'pipe', process.stderr] });
    44  
    45  proc.on('error', function(err){
    46    console.error('[shim] error: %s', err);
    47    process.exit(1);
    48  })
    49  
    50  proc.on('exit', function(code, signal){
    51    console.error('[shim] exit: code=%s signal=%s', code, signal);
    52    process.exit(1);
    53  })
    54  
    55  /**
    56   * Newline-delimited JSON stdout.
    57   */
    58  
    59  var out = byline(proc.stdout)
    60  
    61  out.on('data', function(line){
    62    if (debug) console.log('[shim] parsing: `%s`', line)
    63  
    64    var msg;
    65    try {
    66      msg = JSON.parse(line);
    67    } catch (err) {
    68      console.log('[shim] unexpected non-json line: `%s`', line);
    69      return
    70    }
    71  
    72    if (typeof msg.id !== 'string') {
    73      console.log('[shim] unexpected line - do not use stdout: `%s`', line);
    74      return
    75    }
    76  
    77    const c = callbacks[msg.id];
    78    delete callbacks[msg.id];
    79  
    80    if (!c) {
    81      if (debug) console.log('[shim] unexpected duplicate response: `%s`', line)
    82      return
    83    }
    84  
    85    c(msg.error, msg.value);
    86  });
    87  
    88  
    89  /**
    90   * Handle events.
    91   */
    92  exports.handle = function(event, ctx, cb) {
    93    ctx.callbackWaitsForEmptyEventLoop = false;
    94  
    95    const id = nextId();
    96    callbacks[id] = cb;
    97  
    98    proc.stdin.write(JSON.stringify({
    99      "id": id,
   100      "event": event,
   101      "context": ctx
   102    })+'\n');
   103  }