0.2.1 • Published 8 years ago

process-mux v0.2.1

Weekly downloads
2
License
MIT
Repository
github
Last release
8 years ago

process-mux

a lightweight module to ease control flow and signaling between forked processes and their parents heavily inspired by Redux.

NPM

Install

npm i -S process-mux

How to use

actionTypes.js - If this looks like Redux, thats because I jacked it.

export const START = 'START'
export const STARTED = 'STARTED'
export const PROCESS = 'PROCESS'
export const PROCESSING = 'PROCESSING'
export const PROCESSED = 'PROCESSED'
export const STOP = 'STOP'

scheduler.js

This process schedules child processes via publishing actions.

import processMux, {EXIT} from 'process-mux'

import {START,PROCESS,STOP} from './actionTypes'

const pmux = processMux()


/** fork and subscribe a child process under key processor */
let proc = pmux.fork('processor', 'processor.js')

/** publish START action to all processes. */
pmux.pub({ type: START })

/** get the state of the child processor. */
console.info('post-start', proc.getState())

/** publish PROCESS action to child processor and its subprocesses only. */
proc.pub({ type: PROCESS, { indices: [1, 2, 3] } })

/** get state of all processes, with keys of their process names */
const { processor } = pmux.getState()


/** subscribe to EXIT action from processor */
proc.sub(EXIT, ({ code }) => console.info(`child process exited with code ${code}`))

/** subscribe to EXIT action from any processor */
pmux.sub(EXIT, ({ processKey, code }) => console.info(`child process ${processKey} exited with code ${code}`))

/** Ask processor to stop processing after 10 seconds */
setTimeout(() => proc.pub(STOP), 10000)

processor.js

This process is launched as a fork from its parent and should have no knowledge regarding its parent.

import processMux, {EXIT} from 'process-mux'
import {START,STARTED,PROCESS,PROCESSING,PROCESSED,STOP} from './actionTypes'

const pmux = processMux()

/** DROPPING MIDDLEWARE IN FAVOR OF pmux.sub FOR INITIAL */
/*
pmux.middleware(next => action => {
  const { type, payload } = action
  switch(type) {
    case START:
      start(payload)
    case PROCESS:
      process(payload)
    case STOP:
      stop(payload)
  }
  return next(action)
})
*/

pmux.reducer((state = { status: 'child is dead', lastError: null }, action) => {
  const { type, payload, error } = action
  if(error)
    return { ...state, lastError: payload }
  switch(type) {
    case START:
      return { ...state, status: 'child is starting' }
    case STARTED:
      return { ...state, status: 'child is running' }
    case PROCESS:
      return { ...state, status: `child is about to process indices ${payload.indices.join(', ')}` }
    case PROCESSING:
      return { ...state, status: 'child is processing' }
    case PROCESSED:
      return { ...state, status: 'child finished processing with results ${payload.results.join(', ')}' }
    case STOP:
      return { ...state, status: 'child is stopping' }
    case EXIT:
      return { ...state, status: `child is dead with exit code ${payload.code}` }
  }
  return state
})


const start = () => {
  /** start doing stuff */
  pmux.pub(STARTED)
}

const process = ({ indices }) => {
  /** kick off some processing */
  pmux.pub(PROCESSING)
  setTimeout(() => pmux.dispatch(PROCESSED, { results: indices.map(x => x * 2 + 1) }), 5000)
}

const stop = () => {
  /** pmux.exit triggers a process.exit but ensures the middleware and reducer get run with the exit status first. */
  pmux.exit(0)
}



/** handle special logic when this was run directly from command line (not forked). */
if(pmux.orphan) start()