From be3b2bd56550b71a2ffb7eb1604c1b8c1d2dd4a2 Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Sat, 26 May 2018 21:33:26 +0200 Subject: refactor some task stuff --- app/client/common/button.component.js | 2 +- app/client/common/param.component.js | 6 +- app/client/common/paramGroup.component.js | 2 +- app/client/common/select.component.js | 2 +- app/client/common/slider.component.js | 2 +- app/client/dashboard/actions.js | 1 - app/client/dashboard/dashboard.actions.js | 1 + app/client/dashboard/dashboard.component.js | 10 +- app/client/dashboard/dashboard.reducer.js | 21 +++ app/client/dashboard/dashboardHeader.component.js | 5 +- app/client/dashboard/tasklist.component.js | 2 +- app/client/index.jsx | 2 +- app/client/live/actions.js | 53 ------- app/client/live/live.actions.js | 53 +++++++ app/client/live/live.reducer.js | 129 +++++++++++++++++ app/client/live/reducer.js | 129 ----------------- app/client/pix2pix/live.component.js | 4 +- app/client/socket.js | 163 ---------------------- app/client/socket/index.js | 27 ++++ app/client/socket/socket.connection.js | 15 ++ app/client/socket/socket.live.js | 107 ++++++++++++++ app/client/socket/socket.system.js | 33 +++++ app/client/socket/socket.task.js | 28 ++++ app/client/store.js | 6 +- app/client/system/system.actions.js | 2 +- app/client/system/system.component.js | 79 +++++++---- app/client/system/system.reducer.js | 90 ------------ app/client/task/task.actions.js | 10 ++ app/client/task/task.reducer.js | 80 +++++++++++ app/client/types.js | 4 + app/relay/index.js | 36 ++++- app/relay/interpreters.js | 2 +- app/relay/modules/test.js | 16 +-- app/relay/runner.js | 22 +-- app/server/index.js | 11 +- 35 files changed, 649 insertions(+), 506 deletions(-) delete mode 100644 app/client/dashboard/actions.js create mode 100644 app/client/dashboard/dashboard.actions.js delete mode 100644 app/client/live/actions.js create mode 100644 app/client/live/live.actions.js create mode 100644 app/client/live/live.reducer.js delete mode 100644 app/client/live/reducer.js delete mode 100644 app/client/socket.js create mode 100644 app/client/socket/index.js create mode 100644 app/client/socket/socket.connection.js create mode 100644 app/client/socket/socket.live.js create mode 100644 app/client/socket/socket.system.js create mode 100644 app/client/socket/socket.task.js create mode 100644 app/client/task/task.actions.js create mode 100644 app/client/task/task.reducer.js (limited to 'app') diff --git a/app/client/common/button.component.js b/app/client/common/button.component.js index 746a3f6..21aa5b6 100644 --- a/app/client/common/button.component.js +++ b/app/client/common/button.component.js @@ -1,7 +1,7 @@ import { h, Component } from 'preact' import { connect } from 'react-redux' import { bindActionCreators } from 'redux' -import * as liveActions from '../live/actions' +import * as liveActions from '../live/live.actions' class Button extends Component { constructor(props){ diff --git a/app/client/common/param.component.js b/app/client/common/param.component.js index e788118..b2aefd3 100644 --- a/app/client/common/param.component.js +++ b/app/client/common/param.component.js @@ -8,10 +8,8 @@ export default class Param extends Component { render() { return (
- + {this.props.title} + {this.props.children}
) } diff --git a/app/client/common/paramGroup.component.js b/app/client/common/paramGroup.component.js index 6dd45f6..13b46a5 100644 --- a/app/client/common/paramGroup.component.js +++ b/app/client/common/paramGroup.component.js @@ -1,7 +1,7 @@ import { h, Component } from 'preact' import { connect } from 'react-redux' import { bindActionCreators } from 'redux' -import * as liveActions from '../live/actions' +import * as liveActions from '../live/live.actions' class ParamGroup extends Component { constructor(props){ diff --git a/app/client/common/select.component.js b/app/client/common/select.component.js index cfe4ebf..90bc6dc 100644 --- a/app/client/common/select.component.js +++ b/app/client/common/select.component.js @@ -1,7 +1,7 @@ import { h, Component } from 'preact' import { connect } from 'react-redux' import { bindActionCreators } from 'redux' -import * as liveActions from '../live/actions' +import * as liveActions from '../live/live.actions' class Select extends Component { constructor(props){ diff --git a/app/client/common/slider.component.js b/app/client/common/slider.component.js index 174877d..942640a 100644 --- a/app/client/common/slider.component.js +++ b/app/client/common/slider.component.js @@ -1,7 +1,7 @@ import { h, Component } from 'preact' import { connect } from 'react-redux' import { bindActionCreators } from 'redux' -import * as liveActions from '../live/actions' +import * as liveActions from '../live/live.actions' const SLIDER_THROTTLE_TIME = 100 diff --git a/app/client/dashboard/actions.js b/app/client/dashboard/actions.js deleted file mode 100644 index 01c0a96..0000000 --- a/app/client/dashboard/actions.js +++ /dev/null @@ -1 +0,0 @@ -import types from '../types' diff --git a/app/client/dashboard/dashboard.actions.js b/app/client/dashboard/dashboard.actions.js new file mode 100644 index 0000000..01c0a96 --- /dev/null +++ b/app/client/dashboard/dashboard.actions.js @@ -0,0 +1 @@ +import types from '../types' diff --git a/app/client/dashboard/dashboard.component.js b/app/client/dashboard/dashboard.component.js index 6db42ae..3d3d168 100644 --- a/app/client/dashboard/dashboard.component.js +++ b/app/client/dashboard/dashboard.component.js @@ -13,7 +13,7 @@ import TaskList from './tasklist.component' import FileList from './filelist.component' import Gallery from './gallery.component' -import * as liveActions from './actions' +import * as dashboardActions from './dashboard.actions' class Dashboard extends Component { constructor(props){ @@ -59,13 +59,13 @@ class Dashboard extends Component { } const mapStateToProps = state => ({ site: state.system.site, - images: state.system.images, - tasks: state.system.tasks, - files: state.system.files + images: state.dashboard.images, + files: state.dashboard.files, + tasks: state.task.tasks, }) const mapDispatchToProps = (dispatch, ownProps) => ({ - actions: bindActionCreators(liveActions, dispatch) + actions: bindActionCreators(dashboardActions, dispatch) }) export default connect(mapStateToProps, mapDispatchToProps)(Dashboard) diff --git a/app/client/dashboard/dashboard.reducer.js b/app/client/dashboard/dashboard.reducer.js index c5b3d4a..b3ee05e 100644 --- a/app/client/dashboard/dashboard.reducer.js +++ b/app/client/dashboard/dashboard.reducer.js @@ -4,6 +4,27 @@ let FileSaver = require('file-saver') const dashboardInitialState = { loading: false, error: null, + + images: [ + { + url: 'https://s3.amazonaws.com/i.asdf.us/bucky/data/4282/woodscaled_4_true_20180521_2125.png', + }, + { + url: 'https://s3.amazonaws.com/i.asdf.us/bucky/data/4282/woodscaled_4_true_20180521_2146%20(1).png', + }, + { + url: 'https://s3.amazonaws.com/i.asdf.us/bucky/data/4282/woodscaled_4_true_20180521_2149.png', + }, + { + url: 'https://s3.amazonaws.com/i.asdf.us/bucky/data/4282/woodscaled_4_true_20180521_2150.png', + }, + { + url: 'https://s3.amazonaws.com/i.asdf.us/bucky/data/4282/woodscaled_4_true_20180521_2146%20(1).png', + }, + ], + files: [ + { id: 2, module: 'samplernn', checkpoint: 'jwcglassbeat', dataset: 'jwcglassbeat', epoch: 18, duration: 30, batch_size: 5, filename: 'jwcglassbeat-ep18.mp3', size: 3 * 1024 * 1024, date: Date.now(), opt: "{}", } + ] } const dashboardReducer = (state = dashboardInitialState, action) => { diff --git a/app/client/dashboard/dashboardHeader.component.js b/app/client/dashboard/dashboardHeader.component.js index 492dfd8..2e53088 100644 --- a/app/client/dashboard/dashboardHeader.component.js +++ b/app/client/dashboard/dashboardHeader.component.js @@ -1,7 +1,6 @@ import { h, Component } from 'preact' import { connect } from 'react-redux' import { bindActionCreators } from 'redux' -import * as liveActions from '../live/actions' import * as util from '../util' @@ -19,7 +18,7 @@ class DashboardHeader extends Component { return (

{site.name}

- Currently {util.gerund(currentTask.activity)} {currentTask.library} on {currentTask.dataset}
+ Currently {util.gerund(currentTask.activity)} {currentTask.module} on {currentTask.dataset}
Epoch: {currentTask.epoch} / {currentTask.epochs}, ETA {eta}

Want to play live? @@ -29,7 +28,7 @@ class DashboardHeader extends Component { } const mapStateToProps = state => ({ - currentTask: state.system.currentTask, + currentTask: state.task.currentTask, site: state.system.site, }) diff --git a/app/client/dashboard/tasklist.component.js b/app/client/dashboard/tasklist.component.js index fa002de..e5b1171 100644 --- a/app/client/dashboard/tasklist.component.js +++ b/app/client/dashboard/tasklist.component.js @@ -20,7 +20,7 @@ class TaskList extends Component { } return (
-
{task.activity} {task.library} {dataset_type}
+
{task.activity} {task.module} {dataset_type}
{dataset_name}
{task.epochs} ep.
{eta}
diff --git a/app/client/index.jsx b/app/client/index.jsx index fba38df..ae09534 100644 --- a/app/client/index.jsx +++ b/app/client/index.jsx @@ -4,7 +4,7 @@ import { BrowserRouter, Route } from 'react-router-dom' // import client from './client' import { store, history } from './store' -import socket from './socket' +import * as socket from './socket' import Header from './common/header.component' import Dashboard from './dashboard/dashboard.component' diff --git a/app/client/live/actions.js b/app/client/live/actions.js deleted file mode 100644 index e63854e..0000000 --- a/app/client/live/actions.js +++ /dev/null @@ -1,53 +0,0 @@ -import * as socket from '../socket' -import types from '../types' - -export const get_params = () => { - socket.get_params() - return { type: types.player.get_params, } -} - -export const set_param = (key, value) => { - console.log('set param', key, value) - socket.set_param(key, value) - return { type: types.player.set_param, key, value, } -} - -export const list_checkpoints = () => { - socket.list_checkpoints() - return { type: types.player.loading_checkpoints, } -} - -export const list_epochs = (path) => { - socket.list_epochs(path) - return { type: types.player.loading_epochs, } -} - -export const list_sequences = () => { - socket.list_sequences() - return { type: types.player.loading_sequences } -} - -export const load_sequence = (sequence) => { - socket.load_sequence(sequence) - return { type: types.player.loading_sequence, } -} - -export const load_epoch = (checkpoint, epoch) => { - socket.load_epoch(checkpoint, epoch) - return { type: types.player.loading_checkpoint, } -} - -export const seek = (frame) => { - socket.seek(frame) - return { type: types.player.seeking, } -} - -export const pause = (frame) => { - socket.pause(pause) - return { type: types.player.pausing, } -} - -export const play = (frame) => { - socket.play() - return { type: types.player.playing, } -} diff --git a/app/client/live/live.actions.js b/app/client/live/live.actions.js new file mode 100644 index 0000000..e63854e --- /dev/null +++ b/app/client/live/live.actions.js @@ -0,0 +1,53 @@ +import * as socket from '../socket' +import types from '../types' + +export const get_params = () => { + socket.get_params() + return { type: types.player.get_params, } +} + +export const set_param = (key, value) => { + console.log('set param', key, value) + socket.set_param(key, value) + return { type: types.player.set_param, key, value, } +} + +export const list_checkpoints = () => { + socket.list_checkpoints() + return { type: types.player.loading_checkpoints, } +} + +export const list_epochs = (path) => { + socket.list_epochs(path) + return { type: types.player.loading_epochs, } +} + +export const list_sequences = () => { + socket.list_sequences() + return { type: types.player.loading_sequences } +} + +export const load_sequence = (sequence) => { + socket.load_sequence(sequence) + return { type: types.player.loading_sequence, } +} + +export const load_epoch = (checkpoint, epoch) => { + socket.load_epoch(checkpoint, epoch) + return { type: types.player.loading_checkpoint, } +} + +export const seek = (frame) => { + socket.seek(frame) + return { type: types.player.seeking, } +} + +export const pause = (frame) => { + socket.pause(pause) + return { type: types.player.pausing, } +} + +export const play = (frame) => { + socket.play() + return { type: types.player.playing, } +} diff --git a/app/client/live/live.reducer.js b/app/client/live/live.reducer.js new file mode 100644 index 0000000..60bcb41 --- /dev/null +++ b/app/client/live/live.reducer.js @@ -0,0 +1,129 @@ +import moment from 'moment' +import FileSaver from 'file-saver' +import types from '../types' + +const liveInitialState = { + loading: false, + error: null, + opt: {}, + checkpoints: [], + epochs: ['latest'], + sequences: [], + fps: 0, + frame: { i: 0, sequence_i: 0, sequence_len: '1' } +} + +const liveReducer = (state = liveInitialState, action) => { + let results; + + switch(action.type) { + case types.player.load_params: + if (! action.opt || ! Object.keys(action.opt).length) { + return state + } + return { + ...state, + loading: false, + error: null, + opt: action.opt, + } + + case types.player.set_param: + return { + ...state, + opt: { + ...state.opt, + [action.key]: action.value, + } + } + + case types.player.list_checkpoints: + return { + ...state, + checkpoints: action.checkpoints, + epochs: [], + } + + case types.player.list_epochs: + return { + ...state, + epochs: (action.epochs || []).map(a => [ a == 'latest' ? Infinity : a, a ]) + .sort((a,b) => a[0] - b[0]) + .map(a => a[1]) + } + + case types.player.list_sequences: + return { + ...state, + sequences: action.sequences, + } + + case types.player.set_fps: + return { + ...state, + fps: action.fps, + } + + case types.player.current_frame: + return action.meta ? { + ...state, + frame: action.meta + } : state + + case types.player.start_recording: + return { + ...state, + opt: { + ...state.opt, + recording: true, + } + } + case types.player.add_record_frame: + return { + ...state, + opt: { + ...state.opt, + recordFrames: (state.opt.recordFrames || 0) + 1, + } + } + + case types.player.save_frame: + FileSaver.saveAs( + action.blob, + state.opt.checkpoint_name + "_" + + state.opt.sequence + "_" + + moment().format("YYYYMMDD_HHmm") + ".png" + ) + return state + + case types.player.saving_video: + return { + ...state, + opt: { + ...state.opt, + savingVideo: true, + } + } + case types.player.save_video: + FileSaver.saveAs( + action.blob, + state.opt.checkpoint_name + "_" + + state.opt.sequence + "_" + + moment().format("YYYYMMDD_HHmm") + ".webm" + ) + return { + ...state, + opt: { + ...state.opt, + recording: false, + savingVideo: false, + recordFrames: 0, + } + } + + default: + return state + } +} + +export default liveReducer diff --git a/app/client/live/reducer.js b/app/client/live/reducer.js deleted file mode 100644 index 60bcb41..0000000 --- a/app/client/live/reducer.js +++ /dev/null @@ -1,129 +0,0 @@ -import moment from 'moment' -import FileSaver from 'file-saver' -import types from '../types' - -const liveInitialState = { - loading: false, - error: null, - opt: {}, - checkpoints: [], - epochs: ['latest'], - sequences: [], - fps: 0, - frame: { i: 0, sequence_i: 0, sequence_len: '1' } -} - -const liveReducer = (state = liveInitialState, action) => { - let results; - - switch(action.type) { - case types.player.load_params: - if (! action.opt || ! Object.keys(action.opt).length) { - return state - } - return { - ...state, - loading: false, - error: null, - opt: action.opt, - } - - case types.player.set_param: - return { - ...state, - opt: { - ...state.opt, - [action.key]: action.value, - } - } - - case types.player.list_checkpoints: - return { - ...state, - checkpoints: action.checkpoints, - epochs: [], - } - - case types.player.list_epochs: - return { - ...state, - epochs: (action.epochs || []).map(a => [ a == 'latest' ? Infinity : a, a ]) - .sort((a,b) => a[0] - b[0]) - .map(a => a[1]) - } - - case types.player.list_sequences: - return { - ...state, - sequences: action.sequences, - } - - case types.player.set_fps: - return { - ...state, - fps: action.fps, - } - - case types.player.current_frame: - return action.meta ? { - ...state, - frame: action.meta - } : state - - case types.player.start_recording: - return { - ...state, - opt: { - ...state.opt, - recording: true, - } - } - case types.player.add_record_frame: - return { - ...state, - opt: { - ...state.opt, - recordFrames: (state.opt.recordFrames || 0) + 1, - } - } - - case types.player.save_frame: - FileSaver.saveAs( - action.blob, - state.opt.checkpoint_name + "_" + - state.opt.sequence + "_" + - moment().format("YYYYMMDD_HHmm") + ".png" - ) - return state - - case types.player.saving_video: - return { - ...state, - opt: { - ...state.opt, - savingVideo: true, - } - } - case types.player.save_video: - FileSaver.saveAs( - action.blob, - state.opt.checkpoint_name + "_" + - state.opt.sequence + "_" + - moment().format("YYYYMMDD_HHmm") + ".webm" - ) - return { - ...state, - opt: { - ...state.opt, - recording: false, - savingVideo: false, - recordFrames: 0, - } - } - - default: - return state - } -} - -export default liveReducer diff --git a/app/client/pix2pix/live.component.js b/app/client/pix2pix/live.component.js index 9d41fbc..9792dbd 100644 --- a/app/client/pix2pix/live.component.js +++ b/app/client/pix2pix/live.component.js @@ -10,7 +10,7 @@ import Button from '../common/button.component' import { startRecording, stopRecording, saveFrame } from '../live/player' -import * as liveActions from '../live/actions' +import * as liveActions from '../live/live.actions' class LivePix2Pix extends Component { constructor(props){ @@ -63,7 +63,7 @@ class LivePix2Pix extends Component { return (
-
+
store.dispatch({ type: types.socket.connect })) -socket.on('connect_error', (error) => store.dispatch({ type: types.socket.connect_error, error })) -socket.on('reconnect', (attempt) => store.dispatch({ type: types.socket.reconnect, attempt })) -socket.on('reconnecting', () => store.dispatch({ type: types.socket.reconnecting })) -socket.on('reconnect_error', (error) => store.dispatch({ type: types.socket.reconnect_error, error })) -socket.on('reconnect_failed', (error) => store.dispatch({ type: types.socket.reconnect_failed, error })) -socket.on('disconnect', () => store.dispatch({ type: types.socket.disconnect })) -socket.on('error', (error) => store.dispatch({ type: types.socket.error, error })) - -socket.on('res', (data) => { - console.log(data.cmd) - switch (data.cmd) { - case 'get_last_frame': - if (data.res !== 'working') { - socket.emit('cmd', { - cmd: 'get_last_frame', - }) - } - break - case 'get_params': - store.dispatch({ - type: types.socket.load_params, - opt: data.res, - }) - break - case 'list_checkpoints': - store.dispatch({ - type: types.socket.list_checkpoints, - checkpoints: data.res, - }) - break - case 'list_sequences': - store.dispatch({ - type: types.socket.list_sequences, - sequences: data.res, - }) - break - case 'list_epochs': - store.dispatch({ - type: types.socket.list_epochs, - epochs: data.res, - }) - break - default: - break - } - console.log(data) -}) - -socket.on('system_res', (data) => { - console.log('system response', data) - switch (data.type) { - case 'relay_connected': - return store.dispatch({ type: types.system.relay_connected }) - case 'relay_disconnected': - return store.dispatch({ type: types.system.relay_disconnected }) - case 'rpc_connected': - return store.dispatch({ type: types.system.rpc_connected, runner: data.runner }) - case 'rpc_disconnected': - return store.dispatch({ type: types.system.rpc_disconnected }) - case 'relay_status': - return store.dispatch({ type: data.rpc_connected ? types.system.rpc_connected : types.system.rpc_disconnected, runner: data.runner }) - case 'command_output': - store.dispatch({ - type: types.system.command_output, - data: data, - }) - break - } -}) - -socket.on('frame', player.onFrame) - -socket.on('status', (data) => { - console.log('got status', data.key, data.value) - store.dispatch({ type: types.socket.status }) - switch (data.key) { - case 'processing': - store.dispatch({ - type: 'SET_PARAM', - ...data, - }) - break - default: - break - } -}) - -export function list_checkpoints() { - socket.emit('cmd', { - cmd: 'list_checkpoints', - }) -} -export function list_epochs(checkpoint_name) { - socket.emit('cmd', { - cmd: 'list_epochs', - payload: checkpoint_name, - }) -} -export function list_sequences() { - socket.emit('cmd', { - cmd: 'list_sequences', - }) -} -export function load_epoch(checkpoint_name, epoch) { - console.log(">> SWITCH CHECKPOINT", checkpoint_name, epoch) - socket.emit('cmd', { - cmd: 'load_epoch', - payload: checkpoint_name + ':' + epoch, - }) -} -export function load_sequence(sequence) { - socket.emit('cmd', { - cmd: 'load_sequence', - payload: sequence, - }) -} -export function seek(frame) { - socket.emit('cmd', { - cmd: 'seek', - payload: frame, - }) -} -export function pause(frame) { - socket.emit('cmd', { - cmd: 'pause', - }) -} -export function play(frame) { - socket.emit('cmd', { - cmd: 'play', - }) -} -export function get_params() { - socket.emit('cmd', { - cmd: 'get_params', - }) -} -export function set_param(key, value) { - socket.emit('cmd', { - cmd: 'set_param', - payload: { - 'key': key, - 'value': value, - } - }) -} -export function run_system_command(cmd) { - socket.emit('system', { - cmd: 'run_system_command', - payload: cmd, - }) -} - -export { socket } diff --git a/app/client/socket/index.js b/app/client/socket/index.js new file mode 100644 index 0000000..c0fed61 --- /dev/null +++ b/app/client/socket/index.js @@ -0,0 +1,27 @@ +import { store } from '../store' +import types from '../types' + +import { socket } from './socket.connection' +import * as system from './socket.system' +import * as live from './socket.live' + +export default { + socket, + system, + live, +} + +socket.on('status', (data) => { + console.log('got status', data.key, data.value) + store.dispatch({ type: types.socket.status }) + switch (data.key) { + case 'processing': + store.dispatch({ + type: 'SET_PARAM', + ...data, + }) + break + default: + break + } +}) diff --git a/app/client/socket/socket.connection.js b/app/client/socket/socket.connection.js new file mode 100644 index 0000000..4aa039c --- /dev/null +++ b/app/client/socket/socket.connection.js @@ -0,0 +1,15 @@ +import { store } from '../store' +import types from '../types' + +export const socket = io.connect('/client') + +// SOCKET ACTIONS + +socket.on('connect', () => store.dispatch({ type: types.socket.connect })) +socket.on('connect_error', (error) => store.dispatch({ type: types.socket.connect_error, error })) +socket.on('reconnect', (attempt) => store.dispatch({ type: types.socket.reconnect, attempt })) +socket.on('reconnecting', () => store.dispatch({ type: types.socket.reconnecting })) +socket.on('reconnect_error', (error) => store.dispatch({ type: types.socket.reconnect_error, error })) +socket.on('reconnect_failed', (error) => store.dispatch({ type: types.socket.reconnect_failed, error })) +socket.on('disconnect', () => store.dispatch({ type: types.socket.disconnect })) +socket.on('error', (error) => store.dispatch({ type: types.socket.error, error })) diff --git a/app/client/socket/socket.live.js b/app/client/socket/socket.live.js new file mode 100644 index 0000000..c55695f --- /dev/null +++ b/app/client/socket/socket.live.js @@ -0,0 +1,107 @@ +import { dispatch } from '../store' +import types from '../types' +import * as player from '../live/player' + +import { socket } from './socket.connection' + +socket.on('res', (data) => { + console.log(data.cmd) + switch (data.cmd) { + case 'get_last_frame': + if (data.res !== 'working') { + socket.emit('cmd', { + cmd: 'get_last_frame', + }) + } + break + case 'get_params': + store.dispatch({ + type: types.socket.load_params, + opt: data.res, + }) + break + case 'list_checkpoints': + store.dispatch({ + type: types.socket.list_checkpoints, + checkpoints: data.res, + }) + break + case 'list_sequences': + store.dispatch({ + type: types.socket.list_sequences, + sequences: data.res, + }) + break + case 'list_epochs': + store.dispatch({ + type: types.socket.list_epochs, + epochs: data.res, + }) + break + default: + break + } + console.log(data) +}) + +socket.on('frame', player.onFrame) + +export function list_checkpoints() { + socket.emit('cmd', { + cmd: 'list_checkpoints', + }) +} +export function list_epochs(checkpoint_name) { + socket.emit('cmd', { + cmd: 'list_epochs', + payload: checkpoint_name, + }) +} +export function list_sequences() { + socket.emit('cmd', { + cmd: 'list_sequences', + }) +} +export function load_epoch(checkpoint_name, epoch) { + console.log(">> SWITCH CHECKPOINT", checkpoint_name, epoch) + socket.emit('cmd', { + cmd: 'load_epoch', + payload: checkpoint_name + ':' + epoch, + }) +} +export function load_sequence(sequence) { + socket.emit('cmd', { + cmd: 'load_sequence', + payload: sequence, + }) +} +export function seek(frame) { + socket.emit('cmd', { + cmd: 'seek', + payload: frame, + }) +} +export function pause(frame) { + socket.emit('cmd', { + cmd: 'pause', + }) +} +export function play(frame) { + socket.emit('cmd', { + cmd: 'play', + }) +} +export function get_params() { + socket.emit('cmd', { + cmd: 'get_params', + }) +} +export function set_param(key, value) { + socket.emit('cmd', { + cmd: 'set_param', + payload: { + 'key': key, + 'value': value, + } + }) +} \ No newline at end of file diff --git a/app/client/socket/socket.system.js b/app/client/socket/socket.system.js new file mode 100644 index 0000000..0cdc625 --- /dev/null +++ b/app/client/socket/socket.system.js @@ -0,0 +1,33 @@ +import { dispatch } from '../store' +import types from '../types' + +import { socket } from './socket.connection' + +socket.on('system_res', (data) => { + console.log('system response', data) + switch (data.type) { + case 'relay_connected': + return dispatch({ type: types.system.relay_connected }) + case 'relay_disconnected': + return dispatch({ type: types.system.relay_disconnected }) + case 'rpc_connected': + return dispatch({ type: types.system.rpc_connected, runner: data.runner }) + case 'rpc_disconnected': + return dispatch({ type: types.system.rpc_disconnected }) + case 'relay_status': + return dispatch({ type: data.rpc_connected ? types.system.rpc_connected : types.system.rpc_disconnected, runner: data.runner }) + case 'command_output': + return dispatch({ + type: types.system.command_output, + data: data, + }) + break + } +}) + +export function run_system_command(cmd) { + socket.emit('system', { + cmd: 'run_system_command', + payload: cmd, + }) +} diff --git a/app/client/socket/socket.task.js b/app/client/socket/socket.task.js new file mode 100644 index 0000000..936d2bc --- /dev/null +++ b/app/client/socket/socket.task.js @@ -0,0 +1,28 @@ +import { dispatch } from '../store' +import types from '../types' + +import { socket } from './socket.connection' + +socket.on('task_res', (data) => { + console.log('system response', data) + switch (data.type) { + // case 'rpc_connected': + // return dispatch({ type: types.system.rpc_connected, runner: data.runner }) + default: + return console.log('no such task command', data.type) + } +}) + +export function start_task(task) { + socket.emit('task', { + cmd: 'start_task', + task, + }) +} + +export function stop_task(task) { + socket.emit('task', { + cmd: 'stop_task', + task, + }) +} diff --git a/app/client/store.js b/app/client/store.js index 600e53c..f7eb566 100644 --- a/app/client/store.js +++ b/app/client/store.js @@ -8,12 +8,14 @@ import { routerReducer } from 'react-router-redux' // import navReducer from './nav.reducer' import systemReducer from './system/system.reducer' import dashboardReducer from './dashboard/dashboard.reducer' -import liveReducer from './live/reducer' +import liveReducer from './live/live.reducer' +import taskReducer from './task/task.reducer' const appReducer = combineReducers({ system: systemReducer, dashboard: dashboardReducer, live: liveReducer, + task: taskReducer, router: routerReducer, }) @@ -28,3 +30,5 @@ export const store = createStore( ) ) ) + +export const dispatch = store.dispatch diff --git a/app/client/system/system.actions.js b/app/client/system/system.actions.js index 1732179..ff32fd6 100644 --- a/app/client/system/system.actions.js +++ b/app/client/system/system.actions.js @@ -2,6 +2,6 @@ import * as socket from '../socket' import types from '../types' export const run = (cmd) => { - socket.run_system_command(cmd) + socket.system.run_system_command(cmd) return { type: types.system.running_command, cmd } } diff --git a/app/client/system/system.component.js b/app/client/system/system.component.js index 7428c22..00c5395 100644 --- a/app/client/system/system.component.js +++ b/app/client/system/system.component.js @@ -6,6 +6,19 @@ import Group from '../common/group.component' import Param from '../common/param.component' import * as systemActions from './system.actions' +import * as taskActions from '../task/task.actions' + +const cpu_test_task = { + id: 1073, + activity: 'train', + library: 'test', + dataset: 'test', + epochs: 1, + opt: {} +} +const gpu_test_task = { + +} class System extends Component { constructor(props){ @@ -20,30 +33,45 @@ class System extends Component {
- - {server.status} - {server.error && - {server.error.message} - } - {relay.status} - {rpc.status} - {rpc.cpu_cmd} - {rpc.gpu_cmd} - train samplernn - - - - - - - - - - - - +
+ + {server.status} + {server.error && + {server.error.message} + } + {relay.status} + {rpc.status} + {rpc.cpu_cmd} + {rpc.gpu_cmd} + train samplernn + + + + + + + + + + + + + + + + + + + + + + + + + +
+ {this.renderCommandOutput()}
- {this.renderCommandOutput()}
) } @@ -76,7 +104,10 @@ const mapStateToProps = state => ({ }) const mapDispatchToProps = (dispatch, ownProps) => ({ - actions: bindActionCreators(systemActions, dispatch) + actions: { + system: bindActionCreators(systemActions, dispatch), + task: bindActionCreators(taskActions, dispatch), + }, }) export default connect(mapStateToProps, mapDispatchToProps)(System) diff --git a/app/client/system/system.reducer.js b/app/client/system/system.reducer.js index a21966d..ac7b20e 100644 --- a/app/client/system/system.reducer.js +++ b/app/client/system/system.reducer.js @@ -34,96 +34,6 @@ const systemInitialState = { stdout: null, stderr: null, }, - - currentTask: { - id: 1072, - activity: 'train', - library: 'pix2pix', - dataset: 'video/woods_final', - epoch: 87, - epochs: 100, - }, - images: [ - { - url: 'https://s3.amazonaws.com/i.asdf.us/bucky/data/4282/woodscaled_4_true_20180521_2125.png', - }, - { - url: 'https://s3.amazonaws.com/i.asdf.us/bucky/data/4282/woodscaled_4_true_20180521_2146%20(1).png', - }, - { - url: 'https://s3.amazonaws.com/i.asdf.us/bucky/data/4282/woodscaled_4_true_20180521_2149.png', - }, - { - url: 'https://s3.amazonaws.com/i.asdf.us/bucky/data/4282/woodscaled_4_true_20180521_2150.png', - }, - { - url: 'https://s3.amazonaws.com/i.asdf.us/bucky/data/4282/woodscaled_4_true_20180521_2146%20(1).png', - }, - ], - tasks: [ - { - id: 1073, - activity: 'train', - library: 'pix2pix', - dataset: 'video/woods_green', - epochs: 100, - }, - { - id: 1073, - activity: 'train', - library: 'samplernn', - dataset: 'bobby_brown_-_every_little_step', - epochs: 6, - }, - { - id: 1073, - activity: 'train', - library: 'pix2pix', - checkpoint: 'lyra_voice_layers', - dataset: 'audio/lyra_improv', - epochs: 30, - }, - { - id: 1073, - activity: 'train', - library: 'pix2pix', - checkpoint: 'lyra_melody_lines', - dataset: 'audio/lyra_improv', - epochs: 30, - }, - { - id: 1073, - activity: 'train', - library: 'pix2pix', - checkpoint: 'ensemble_chords', - dataset: 'audio/lyra_improv', - epochs: 30, - }, - { - id: 1073, - activity: 'generate', - library: 'samplernn', - dataset: 'coccoglass3', - opt: { time: 5, count: 6 }, - }, - { - id: 1073, - activity: 'train', - library: 'pix2pix', - dataset: 'video/woods_green', - epochs: 100, - }, - { - id: 1073, - activity: 'train', - library: 'samplernn', - dataset: 'bobby_brown_-_every_little_step', - epochs: 6, - }, - ], - files: [ - { id: 2, library: 'samplernn', checkpoint: 'jwcglassbeat', dataset: 'jwcglassbeat', epoch: 18, duration: 30, batch_size: 5, filename: 'jwcglassbeat-ep18.mp3', size: 3 * 1024 * 1024, date: Date.now(), opt: "{}", } - ] } const systemReducer = (state = systemInitialState, action) => { diff --git a/app/client/task/task.actions.js b/app/client/task/task.actions.js new file mode 100644 index 0000000..466b8d7 --- /dev/null +++ b/app/client/task/task.actions.js @@ -0,0 +1,10 @@ +import socket from '../socket' + +export const start_task = (task) => { + socket.task.start_task(task) + return { type: types.task.starting_task, task } +} +export const stop_task = (task) => { + socket.task.stop_task(task) + return { type: types.task.stopping_task, task } +} diff --git a/app/client/task/task.reducer.js b/app/client/task/task.reducer.js new file mode 100644 index 0000000..12e5184 --- /dev/null +++ b/app/client/task/task.reducer.js @@ -0,0 +1,80 @@ +import types from '../types' +import moment from 'moment' +let FileSaver = require('file-saver') + +const taskInitialState = { + loading: false, + error: null, + + currentTask: { + id: 1072, + activity: 'train', + module: 'pix2pix', + dataset: 'video/woods_final', + epoch: 87, + epochs: 100, + }, + tasks: [ + { + id: 1073, + activity: 'train', + module: 'samplernn', + dataset: 'bobby_brown_-_every_little_step', + epochs: 6, + }, + { + id: 1073, + activity: 'train', + module: 'pix2pix', + checkpoint: 'lyra_voice_layers', + dataset: 'audio/lyra_improv', + epochs: 30, + }, + { + id: 1073, + activity: 'train', + module: 'pix2pix', + checkpoint: 'lyra_melody_lines', + dataset: 'audio/lyra_improv', + epochs: 30, + }, + { + id: 1073, + activity: 'train', + module: 'pix2pix', + checkpoint: 'ensemble_chords', + dataset: 'audio/lyra_improv', + epochs: 30, + }, + { + id: 1073, + activity: 'generate', + module: 'samplernn', + dataset: 'coccoglass3', + opt: { time: 5, count: 6 }, + }, + { + id: 1073, + activity: 'train', + module: 'pix2pix', + dataset: 'video/woods_green', + epochs: 100, + }, + { + id: 1073, + activity: 'train', + module: 'samplernn', + dataset: 'bobby_brown_-_every_little_step', + epochs: 6, + }, + ], +} + +const taskReducer = (state = taskInitialState, action) => { + switch(action.type) { + default: + return state + } +} + +export default taskReducer diff --git a/app/client/types.js b/app/client/types.js index 1401ac6..f78265f 100644 --- a/app/client/types.js +++ b/app/client/types.js @@ -7,6 +7,10 @@ export default { rpc_connected: 'SYSTEM_RPC_CONNECTED', rpc_disconnected: 'SYSTEM_RPC_DISCONNECTED', }, + task: { + starting_task: 'TASK_STARTING_TASK', + stopping_task: 'TASK_STOPPING_TASK', + }, socket: { connect: 'SOCKET_CONNECT', connect_error: 'SOCKET_CONNECT_ERROR', diff --git a/app/relay/index.js b/app/relay/index.js index 6bb9179..ed59c44 100644 --- a/app/relay/index.js +++ b/app/relay/index.js @@ -41,6 +41,40 @@ remote.on('cmd', (data) => { } }) +remote.on('task', (data) => { + console.log('task:', data.task) + switch(data.cmd) { + case 'start': + break + case 'stop': + break + case 'kill': + break + case 'add': + break + case 'remove': + break + case 'start_queue': + break + case 'stop_queue': + break + case 'list': + break + case 'set_priority': + break + // case 'get_status': + // remote.emit('system_res', { + // type: 'relay_status', + // rpc_connected: rpc_connected, + // runner: runner.status(), + // }) + // break + default: + remote.emit('system_res', { cmd: 'error', error: 'unknown task command' }) + break + } +}) + remote.on('system', (data) => { console.log('system:', data.cmd) switch(data.cmd) { @@ -61,7 +95,7 @@ remote.on('system', (data) => { }) break default: - remote.emit('system_res', { error: 'unknown system command' }) + remote.emit('system_res', { cmd: 'error', error: 'unknown system command' }) break } }) diff --git a/app/relay/interpreters.js b/app/relay/interpreters.js index c276f94..63a2c25 100644 --- a/app/relay/interpreters.js +++ b/app/relay/interpreters.js @@ -8,7 +8,7 @@ export default { gpu: false, }, python: { - cmd: process.env.PYTHON_BIN, + cmd: process.env.PYTHON_BIN || '/usr/bin/python3', gpu: false, }, pytorch: { diff --git a/app/relay/modules/test.js b/app/relay/modules/test.js index bfac514..6c94a0c 100644 --- a/app/relay/modules/test.js +++ b/app/relay/modules/test.js @@ -3,26 +3,18 @@ import path from 'path' const name = 'test' const cwd = process.env.TEST_CWD || './test/module/' -const dataset = { +const cpu = { type: 'perl', script: 'test.pl', params: (task) => { } } -const train = { - type: 'perl', +const gpu = { + type: 'python', script: 'test.pl', params: (task) => { } } -const generate = { - type: 'perl', - script: 'test.pl', -} -const render = { - type: 'perl', - script: 'test.pl', -} const live = { type: 'pytorch', script: 'test.py', @@ -31,6 +23,6 @@ const live = { export default { name, cwd, activities: { - dataset, train, generate, render, live, + cpu, gpu, live, } } diff --git a/app/relay/runner.js b/app/relay/runner.js index c9f4052..9fc2a38 100644 --- a/app/relay/runner.js +++ b/app/relay/runner.js @@ -56,18 +56,21 @@ export function run_system_command(cmd, cb) { case 'w': execFile(cmd, cb) break + case 'df': + execFile('df', ['-h'], cb) + break default: cb({ error: 'no such command' }) break } } -export function run_task(module_name, task){ - const module = modules['module_name'] +export function run_task(task){ + const module = modules[task.module] if (! module) throw new Error("No such module") const { activity, interpreter, params } = build_params(module, task) console.log('running task', activity.name) - console.log(activity.interpreter, params) + console.log(activity.interpreter, activity.script, params) const subprocess = spawn(activity.interpreter, params) if (activity.gpu) { state.current_gpu_task = subprocess @@ -75,18 +78,19 @@ export function run_task(module_name, task){ else { state.current_cpu_task = subprocess } - subprocess.stdout.on('data', data => { - console.log('stdout', subprocess.pid, data) - }) - subprocess.stderr.on('data', data => { - console.log('stderr', subprocess.pid, data) - }) subprocess.on('error', (err) => { console.log('process error', subprocess.pid, err) }) subprocess.on('close', () => { console.log('process ended', subprocess.pid) }) + subprocess.stdout.on('data', data => { + console.log('stdout', subprocess.pid, data) + }) + subprocess.stderr.on('data', data => { + console.log('stderr', subprocess.pid, data) + }) + return subprocess } export function kill_task(subprocess){ diff --git a/app/server/index.js b/app/server/index.js index adc8759..b81ed57 100644 --- a/app/server/index.js +++ b/app/server/index.js @@ -55,10 +55,14 @@ function bind_relay(socket) { }) socket.on('system_res', data => { - console.log('System responded', data.cmd) + console.log('System responded', data.type) client.emit('system_res', data) }) + socket.on('task_res', data => { + client.emit('task_res', data) + }) + socket.on('frame', (data) => { client.volatile.emit('frame', data) }) @@ -89,6 +93,11 @@ function bind_client(socket){ relay.emit('system', data) }) + socket.on('task', data => { + console.log('Client sent task command', data) + relay.emit('task', data) + }) + socket.on('disconnect', () => { console.log('Client disconnected') }) -- cgit v1.2.3-70-g09d2