Skip to content

little-core-labs/nanoprocess

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

53 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

nanoprocess

Maintain a child process as a nanoresource

Installation

$ npm install nanoprocess

Status

Stable

Actions Status

Usage

const nanoprocess = require('nanoprocess')

// spawn a comand
const child = nanoprocess(command, args, opts)

// open process and query for stats
child.open((err) => {
  child.stat((err, stats) => {
    console.log(stats)
  })
})

Example

The following example spawns a node process that spawns a sleep command running for 2 seconds while also doing a lot of work (Array(10e7).fill(crypto.randomBytes(1024));). The example will query for process stats and leverage the progress module to output process memory and CPU usage.

const prettyBytes = require('pretty-bytes')
const nanoprocess = require('nanoprocess')
const prettyTime = require('pretty-ms')
const Progress = require('progress')

const template = [
  '> :name (:pid)',
  'up for :uptime',
  'CPU: :cpu%',
  'MEM: :mem',
  ':pidsCount child process(es)'
].join(' | ')

const sleep = nanoprocess('node', [
  '-e',
  'process.title = "sleep";' +
  'require("cross-spawn")("sleep", [2]);' +
  'Array(10e7).fill(crypto.randomBytes(1024));'
])

const bar = new Progress(template, {
  width: 20,
  total: 1
})

sleep.open((err) => {
  console.log('> opened')

  let timer = 0
  sleep.stat(function onstat(err, stats) {
    if (stats) {
      bar.update(0, {
        pidsCount: stats.pids.length,
        uptime: prettyTime(stats.uptime),
        name: stats.name,
        mem: prettyBytes(stats.memory),
        cpu: Math.floor(stats.cpu),
        pid: stats.pid,
      })
    }

    if (stats && stats.uptime > 2000 && 0 === stats.cpu) {
      bar.update(1, stats)
      sleep.close()
    } else if (!err) {
      clearTimeout(timer)
      timer = setTimeout(() => sleep.stat(onstat), 100)
    }
  })

  sleep.process.on('close', () => {
    console.log('')
    console.log('> closed')
  })
})
$ node example.js
> opened
> sleep (33153) | up for 5.2s | CPU: 99% | MEM: 1.25 GB | 1 child process(es)
> closed

API

const nanoprocess = require('nanoprocess')

The nanoprocess function returns a new Process instance that extends nanoresource.

const child = nanoprocess('sleep', [2])
child.open((err) => {
  // process is opened
})

const child = nanoprocess(command[, args[, options]])

Create a new Process instance from command with optional args and options that are given to cross-spawn when the child process is opened.

const ls = nanoprocess('ls', ['.'])
ls.open((err) => {
  ls.process.stdout.pipe(process.stdout)
})

const { Process } = require('nanoprocess')

The nanoprocess exports the Process class that can be extended.

const { Process } = require('nanoprocess')

class InstallDependencies extends Process {
  constructor(dirname) {
    super('npm', ['install'], { cwd: dirname })
  }
}

const install = new InstallDependencies('path/to/dir')
install.open(() => {
  // stat loop
  install.stat(function onstat(err, stats) {
    console.log(stats) // Stats { cpu: 14.23, ... }
    install.stat(onstat)
  })

  install.process.on('close', (err) => {
    console.log('closed')
  })
})

const child = new Process(command[, args[, options]])

Create a new Process instance from command with optional args and options that are given to cross-spawn when the child process is opened.

child.options

The initial options given to the Process instance constructor which are given to cross-spawn when the child process is opened.

child.command

The command to spawn when the child process is opened.

child.process

When the child process is opened, this will be an instance of child_process.ChildProcess.

child.pid

The child process ID.

child.ppid

The child process parent process ID.

child.stdin

The child process stdin stream. This may be null.

child.stdout

The child process stdout stream. This may be null.

child.stderr

The child process stderr stream. This may be null.

child.channel

The child process channel object. This may be null.

child.connected

The child process connection state.

child.killed

The child process killed state.

child.signal

The child process exit signal. This value can be null. Check this after the child process has closed.

child.code

The child process exit code. This value can be null. Check this after the child process has closed.

child.args

The arguments for the child process command given to cross-spawn when the child process is opened.

child.open(callback)

Opens the child process by spawning a command with optional arguments and options calling callback(err) when opened or if an error occurs during the spawning of the child process.

child.close([allowActive[, callback]])

Closes the child process and all decedent child process in the process tree calling callback(err) when closed or if an error occurs during the closing of the spawned child process. Setting allowActive to false (default) will cause a 'SIGTERM' to be sent to the child process causing it to close. You can call child.kill({ force: true }) prior to calling this method if you want force the processed to be killed. Set allowActive to true to wait for the process to close on its and mark the nanoresource instance inactive.

child.kill([opts], callback)

Kill the child process calling callback when killed or if can error occurs. Set opts.true to force the processed to be killed.

child.stat(callback)

Queries for statistics about the running child process for information like cpu usage and memory consumption calling callback(err, stats) with a stats object or if an error occurs.

child.stat((err, stats) => {
  // handle stats
})

The output of the stats object may look something like:

Stats {
  bin: 'sleep',
  uid: 1000,
  gid: 1000,
  cpu: 138.46153845657875,
  pid: 33792,
  ppid: 33785,
  pids: [ 33810 ],
  name: 'sleep',
  atime: 1572118184405,
  uptime: 680,
  memory: 241070080,
  command: 'node' }

stats.bin

The initial binary used invoke the child process.

stats.uid

The user ID of the child process.

stats.gid

The group ID of the child process.

stats.cpu

The current CPU usage as a percentage of the child process.

stats.pid

The child process ID.

stats.ppid

The parent process ID of the child process.

stats.pids

The child process IDs of the child process

stats.name

The name of process

stats.atime

The time stamp in milliseconds this stat was accessed.

stats.uptime

Time in milliseconds since process spawned

stats.memory

Memory usage in bytes

stats.command

The command used to start the process

stats.isRunning

true if the process or any child process in the pidtree for the root child process is still running.

See Also

License

MIT