// monitors which process is currently running // kills it if need be.... murder import { execFile, spawn } from 'child_process' import interpreters from './interpreters' import modules from './modules' import { kill } from 'tree-kill' import { remote } from './remote' export const state = { current_cpu_task: null, current_gpu_task: null, } export function get_current_cpu_task(){ return state.current_cpu_task } export function get_current_gpu_task(){ return state.current_gpu_task } export function get_current_task(processor) { if (processor === 'cpu') { return state.current_cpu_task } else { return state.current_gpu_task } } export function status () { return state } export function build_params(module, task) { const activity = module.activities[task.activity] const interpreter = interpreters[activity.type] if (typeof activity.params === 'function') { params = activity.params(task) } else { const opt = JSON.parse(task.opt) const opt_params = Object.keys(opt).map(key => { const flag = '--' + key.replace(/-/g, '_') const value = opt[key] if (value === 'true') { return [flag] } return [flag, value] }).reduce((acc, cur) => acc.concat(cur), []) params = [ activity.script ].concat(activity.params || []).concat(opt_params) } return { activity, params } } export function run_system_command(cmd, cb) { console.log('running system command:', cmd) switch(cmd) { case 'nvidia-smi': case 'ps': case 'uptime': case 'w': execFile(cmd, cb) break case 'df': execFile('df', ['-h'], cb) break default: cb({ error: 'no such command' }) break } } export function run_task(task, preempt, watch){ const module = modules[task.module] if (! module) throw new Error("No such module") const { activity, interpreter, params } = build_params(module, task) if (activity.cpu && state.current_cpu_task) { if (preempt) { console.log('preempting currently running GPU task') } else { return { type: 'error', error: 'task already running on cpu' } } } else { if (preempt) { console.log('preempting currently running CPU task') } else { return { type: 'error', error: 'task already running on cpu' } } } console.log('running task', activity.name) console.log(activity.interpreter, activity.script, params) const subprocess = spawn(activity.interpreter, params) if (activity.gpu) { state.current_gpu_task = subprocess } else { state.current_cpu_task = subprocess } subprocess.on('error', (err) => { console.log('process error', subprocess.pid, err) remote.emit('task_res', { type: 'task_error', task, err }) }) subprocess.on('close', () => { console.log('process ended', subprocess.pid) remote.emit('task_res', { type: 'task_finish', task }) }) if (watch) { response.stdout.on('data', data => { remote.emit('task_res', { type: 'stdout', data }) }) response.stderr.on('data', data => { remote.emit('task_res', { type: 'stderr', data }) }) } } export function kill_task(subprocess){ kill(subprocess.pid) }