From df502827b1161bc918610608c45a1c6291f09913 Mon Sep 17 00:00:00 2001 From: Jonathan Rainville Date: Thu, 2 Aug 2018 12:45:59 -0400 Subject: [PATCH 1/4] conflict in api --- embark-ui/src/api/index.js | 5 +- embark-ui/src/components/Process.js | 59 +++++++++++++++++++ embark-ui/src/constants.json | 4 ++ .../src/containers/ProcessesContainer.js | 5 +- .../src/containers/css/processContainer.css | 23 ++++++++ lib/core/plugin.js | 3 +- .../blockchainProcessLauncher.js | 6 +- lib/modules/blockchain_process/index.js | 3 +- lib/modules/webserver/server.js | 5 ++ 9 files changed, 106 insertions(+), 7 deletions(-) create mode 100644 embark-ui/src/components/Process.js create mode 100644 embark-ui/src/constants.json diff --git a/embark-ui/src/api/index.js b/embark-ui/src/api/index.js index 704e1baa..c878cec2 100644 --- a/embark-ui/src/api/index.js +++ b/embark-ui/src/api/index.js @@ -1,9 +1,10 @@ import axios from "axios"; +import constants from '../constants'; const BASE_URL = 'http://localhost:8000/embark-api'; export function fetchAccounts() { - return axios.get(`${BASE_URL}/blockchain/accounts`); + return axios.get(constants.httpEndpoint + 'blockchain/accounts'); } export function fetchBlocks(from) { @@ -15,5 +16,5 @@ export function fetchTransactions(blockFrom) { } export function fetchProcesses() { - return axios.get(`${BASE_URL}/processes`); + return axios.get(constants.httpEndpoint + 'processes'); } diff --git a/embark-ui/src/components/Process.js b/embark-ui/src/components/Process.js new file mode 100644 index 00000000..a1c914b4 --- /dev/null +++ b/embark-ui/src/components/Process.js @@ -0,0 +1,59 @@ +import React, {Component} from 'react'; +import {Tab} from "tabler-react"; +import constants from '../constants'; +import PropTypes from 'prop-types'; + +class Process extends Component { + constructor(props) { + super(props); + this.state = { + logs: [] + }; + } + + componentDidMount() { + const self = this; + this.ws = new WebSocket(constants.wsEndpoint + 'process-logs/' + self.props.processName); + + this.ws.onmessage = function(evt) { + const log = JSON.parse(evt.data); + const logs = self.state.logs; + logs.push(log); + self.setState({ + logs + }); + }; + + this.ws.onclose = function() { + console.log(self.props.processName + "Log process connection is closed"); + }; + + window.onbeforeunload = function(_event) { + this.ws.close(); + }; + } + + componentWillUnmount() { + this.ws.close(); + this.ws = null; + } + + render() { + return ( +
+ State: {this.props.state} +
+ { + this.state.logs.map((item, i) =>

{item.msg}

) + } +
+
); + } +} + +Process.propTypes = { + processName: PropTypes.string, + state: PropTypes.string +}; + +export default Process; diff --git a/embark-ui/src/constants.json b/embark-ui/src/constants.json new file mode 100644 index 00000000..06f14ec8 --- /dev/null +++ b/embark-ui/src/constants.json @@ -0,0 +1,4 @@ +{ + "httpEndpoint": "http://localhost:8000/embark-api/", + "wsEndpoint": "ws://localhost:8000/embark-api/" +} diff --git a/embark-ui/src/containers/ProcessesContainer.js b/embark-ui/src/containers/ProcessesContainer.js index baa35293..3f21cddd 100644 --- a/embark-ui/src/containers/ProcessesContainer.js +++ b/embark-ui/src/containers/ProcessesContainer.js @@ -7,6 +7,7 @@ import {fetchProcesses} from '../actions'; import Loading from '../components/Loading'; import "./css/processContainer.css"; +import Process from "../components/Process"; class ProcessesContainer extends Component { componentDidMount() { @@ -32,7 +33,9 @@ class ProcessesContainer extends Component {
{processNames.map(processName => { - return (State: {processes.data[processName].state}); + return ( + + ); })}
diff --git a/embark-ui/src/containers/css/processContainer.css b/embark-ui/src/containers/css/processContainer.css index 008d9eeb..1510241f 100644 --- a/embark-ui/src/containers/css/processContainer.css +++ b/embark-ui/src/containers/css/processContainer.css @@ -2,3 +2,26 @@ .processes-container .nav-link { text-transform: capitalize; } + +.processes-container .logs { + margin: 10px 0; + background-color: #333333; + font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; + font-size: 14px; + color: white; + padding: 10px; + border-radius: 8px; +} + +.processes-container .logs .error { + color: #dc3546; +} +.processes-container .logs .warn { + color: #fec107; +} +.processes-container .logs .debug { + color: #b7c1cc; +} +.processes-container .logs .trace { + color: #8f98a2; +} diff --git a/lib/core/plugin.js b/lib/core/plugin.js index e952b150..ed0403d3 100644 --- a/lib/core/plugin.js +++ b/lib/core/plugin.js @@ -212,8 +212,9 @@ Plugin.prototype.registerActionForEvent = function(eventName, cb) { Plugin.prototype.registerAPICall = function(method, endpoint, cb) { console.dir("registerAPICall " + method + " " + endpoint); - this.apiCalls.push({method: method, endpoint: endpoint, cb: cb}); + this.apiCalls.push({method, endpoint, cb}); this.addPluginType('apiCalls'); + this.events.emit('plugins:register:api', {method, endpoint, cb}); }; Plugin.prototype.runFilePipeline = function() { diff --git a/lib/modules/blockchain_process/blockchainProcessLauncher.js b/lib/modules/blockchain_process/blockchainProcessLauncher.js index 2fc7be35..2b10910d 100644 --- a/lib/modules/blockchain_process/blockchainProcessLauncher.js +++ b/lib/modules/blockchain_process/blockchainProcessLauncher.js @@ -11,6 +11,7 @@ class BlockchainProcessLauncher { this.blockchainConfig = options.blockchainConfig; this.locale = options.locale; this.isDev = options.isDev; + this.embark = options.embark; } processEnded(code) { @@ -21,16 +22,17 @@ class BlockchainProcessLauncher { this.logger.info(__('Starting Blockchain node in another process').cyan); this.blockchainProcess = new ProcessLauncher({ + name: 'blockchain', modulePath: utils.joinPath(__dirname, './blockchainProcess.js'), logger: this.logger, events: this.events, + embark: this.embark, silent: this.logger.logLevel !== 'trace', exitCallback: this.processEnded.bind(this) }); this.blockchainProcess.send({ action: constants.blockchain.init, options: { blockchainConfig: this.blockchainConfig, - //client: this.client, // TODO: assume for now it's geth client: 'geth', env: this.env, @@ -45,7 +47,7 @@ class BlockchainProcessLauncher { }); this.blockchainProcess.once('result', constants.blockchain.blockchainExit, () => { - // telle everyone that our blockchain process (ie geth) died + // tell everyone that our blockchain process (ie geth) died this.events.emit(constants.blockchain.blockchainExit); // then kill off the blockchain process diff --git a/lib/modules/blockchain_process/index.js b/lib/modules/blockchain_process/index.js index f2bb352a..3f123c8e 100644 --- a/lib/modules/blockchain_process/index.js +++ b/lib/modules/blockchain_process/index.js @@ -66,7 +66,8 @@ class BlockchainModule { normalizeInput: utils.normalizeInput, blockchainConfig: self.blockchainConfig, locale: self.locale, - isDev: self.isDev + isDev: self.isDev, + embark: this.embark }); blockchainProcess.startBlockchainNode(); diff --git a/lib/modules/webserver/server.js b/lib/modules/webserver/server.js index d04056c7..3c6e6290 100644 --- a/lib/modules/webserver/server.js +++ b/lib/modules/webserver/server.js @@ -48,6 +48,11 @@ class Server { } } + this.events.on('plugins:register:api', (apiCall) => { + console.dir("adding " + apiCall.method + " " + apiCall.endpoint); + app[apiCall.method].apply(app, [apiCall.endpoint, apiCall.cb]); + }); + app.get('/embark/*', function (req, res) { self.logger.trace('webserver> GET ' + req.path); res.sendFile(path.join(__dirname, '../../../embark-ui/build', 'index.html')); From edb14fb44923f132f132d8d7ff8b45e784ba189f Mon Sep 17 00:00:00 2001 From: Jonathan Rainville Date: Thu, 2 Aug 2018 10:56:09 -0400 Subject: [PATCH 2/4] fix spread operator eslint error --- .eslintrc.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.eslintrc.json b/.eslintrc.json index f00aebde..8c759224 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -10,7 +10,7 @@ ], "parserOptions": { "sourceType": "module", - "ecmaVersion": 2017, + "ecmaVersion": 2018, "ecmaFeatures": { "jsx": true } From c29adde0bf0402101c9552c566d992eb366603e2 Mon Sep 17 00:00:00 2001 From: Jonathan Rainville Date: Thu, 2 Aug 2018 12:48:41 -0400 Subject: [PATCH 3/4] conflict in actions and saga --- embark-ui/src/actions/index.js | 31 +++++++++++++++-- embark-ui/src/api/index.js | 8 +++-- embark-ui/src/components/Process.js | 39 ++++++++++++++++++---- embark-ui/src/constants.json | 4 +-- embark-ui/src/reducers/processesReducer.js | 14 ++++++-- embark-ui/src/sagas/index.js | 16 ++++++++- lib/core/processes/processLauncher.js | 16 +++++++-- 7 files changed, 110 insertions(+), 18 deletions(-) diff --git a/embark-ui/src/actions/index.js b/embark-ui/src/actions/index.js index 7104d037..068316da 100644 --- a/embark-ui/src/actions/index.js +++ b/embark-ui/src/actions/index.js @@ -6,6 +6,10 @@ export const RECEIVE_ACCOUNTS_ERROR = 'RECEIVE_ACCOUNTS_ERROR'; export const FETCH_PROCESSES = 'FETCH_PROCESSES'; export const RECEIVE_PROCESSES = 'RECEIVE_PROCESSES'; export const RECEIVE_PROCESSES_ERROR = 'RECEIVE_PROCESSES_ERROR'; +// Process logs +export const FETCH_PROCESS_LOGS = 'FETCH_PROCESS_LOGS'; +export const RECEIVE_PROCESS_LOGS = 'RECEIVE_PROCESS_LOGS'; +export const RECEIVE_PROCESS_LOGS_ERROR = 'RECEIVE_PROCESS_LOGS_ERROR'; // Blocks export const FETCH_BLOCKS = 'FETCH_BLOCKS'; export const RECEIVE_BLOCKS = 'RECEIVE_BLOCKS'; @@ -47,9 +51,32 @@ export function receiveProcesses(processes) { }; } -export function receiveProcessesError() { +export function receiveProcessesError(error) { return { - type: RECEIVE_PROCESSES_ERROR + type: RECEIVE_PROCESSES_ERROR, + error + }; +} + +export function fetchProcessLogs(processName) { + return { + type: FETCH_PROCESS_LOGS, + processName + }; +} + +export function receiveProcessLogs(processName, logs) { + return { + type: RECEIVE_PROCESS_LOGS, + processName, + logs + }; +} + +export function receiveProcessLogsError(error) { + return { + type: RECEIVE_PROCESS_LOGS_ERROR, + error }; } diff --git a/embark-ui/src/api/index.js b/embark-ui/src/api/index.js index c878cec2..4ab0c14d 100644 --- a/embark-ui/src/api/index.js +++ b/embark-ui/src/api/index.js @@ -4,7 +4,7 @@ import constants from '../constants'; const BASE_URL = 'http://localhost:8000/embark-api'; export function fetchAccounts() { - return axios.get(constants.httpEndpoint + 'blockchain/accounts'); + return axios.get(constants.httpEndpoint + '/blockchain/accounts'); } export function fetchBlocks(from) { @@ -16,5 +16,9 @@ export function fetchTransactions(blockFrom) { } export function fetchProcesses() { - return axios.get(constants.httpEndpoint + 'processes'); + return axios.get(constants.httpEndpoint + '/processes'); +} + +export function fetchProcessLogs(processName) { + return axios.get(`${constants.httpEndpoint}/process-logs/${processName}`); } diff --git a/embark-ui/src/components/Process.js b/embark-ui/src/components/Process.js index a1c914b4..18000340 100644 --- a/embark-ui/src/components/Process.js +++ b/embark-ui/src/components/Process.js @@ -1,5 +1,6 @@ import React, {Component} from 'react'; -import {Tab} from "tabler-react"; +import connect from "react-redux/es/connect/connect"; +import {fetchProcessLogs} from "../actions"; import constants from '../constants'; import PropTypes from 'prop-types'; @@ -9,11 +10,15 @@ class Process extends Component { this.state = { logs: [] }; + this.gotOriginalLogs = false; } componentDidMount() { const self = this; - this.ws = new WebSocket(constants.wsEndpoint + 'process-logs/' + self.props.processName); + + this.props.fetchProcessLogs(self.props.processName); + + this.ws = new WebSocket(constants.wsEndpoint + '/process-logs/' + self.props.processName); this.ws.onmessage = function(evt) { const log = JSON.parse(evt.data); @@ -33,6 +38,17 @@ class Process extends Component { }; } + shouldComponentUpdate(nextProps, _nextState) { + if (!this.gotOriginalLogs && nextProps.logs && nextProps.logs[this.props.processName]) { + const logs = nextProps.logs[this.props.processName].concat(this.state.logs); + this.gotOriginalLogs = true; + this.setState({ + logs + }); + } + return true; + } + componentWillUnmount() { this.ws.close(); this.ws = null; @@ -44,7 +60,7 @@ class Process extends Component { State: {this.props.state}
{ - this.state.logs.map((item, i) =>

{item.msg}

) + this.state.logs.map((item, i) =>

{item.msg_clear || item.msg}

) }
); @@ -52,8 +68,19 @@ class Process extends Component { } Process.propTypes = { - processName: PropTypes.string, - state: PropTypes.string + processName: PropTypes.string.isRequired, + state: PropTypes.string.isRequired, + fetchProcessLogs: PropTypes.func, + logs: PropTypes.object }; -export default Process; +function mapStateToProps(state) { + return {logs: state.processes.logs}; +} + +export default connect( + mapStateToProps, + { + fetchProcessLogs + } +)(Process); diff --git a/embark-ui/src/constants.json b/embark-ui/src/constants.json index 06f14ec8..d8fafa6c 100644 --- a/embark-ui/src/constants.json +++ b/embark-ui/src/constants.json @@ -1,4 +1,4 @@ { - "httpEndpoint": "http://localhost:8000/embark-api/", - "wsEndpoint": "ws://localhost:8000/embark-api/" + "httpEndpoint": "http://localhost:8000/embark-api", + "wsEndpoint": "ws://localhost:8000/embark-api" } diff --git a/embark-ui/src/reducers/processesReducer.js b/embark-ui/src/reducers/processesReducer.js index dc189048..a7ddae2e 100644 --- a/embark-ui/src/reducers/processesReducer.js +++ b/embark-ui/src/reducers/processesReducer.js @@ -1,11 +1,21 @@ -import {RECEIVE_PROCESSES, RECEIVE_PROCESSES_ERROR} from "../actions"; +import {RECEIVE_PROCESSES, RECEIVE_PROCESSES_ERROR, RECEIVE_PROCESS_LOGS, RECEIVE_PROCESS_LOGS_ERROR} from "../actions"; export default function processes(state = {}, action) { switch (action.type) { case RECEIVE_PROCESSES: return Object.assign({}, state, {data: action.processes.data}); case RECEIVE_PROCESSES_ERROR: - return Object.assign({}, state, {error: true}); + return Object.assign({}, state, {error: action.error}); + case RECEIVE_PROCESS_LOGS: + return { + ...state, + logs: { + ...state.logs, + [action.processName]: action.logs.data + } + }; + case RECEIVE_PROCESS_LOGS_ERROR: + return Object.assign({}, state, {error: action.error}); default: return state; } diff --git a/embark-ui/src/sagas/index.js b/embark-ui/src/sagas/index.js index c2ad5da7..e242bf3a 100644 --- a/embark-ui/src/sagas/index.js +++ b/embark-ui/src/sagas/index.js @@ -46,7 +46,7 @@ export function *fetchProcesses() { const processes = yield call(api.fetchProcesses); yield put(actions.receiveProcesses(processes)); } catch (e) { - yield put(actions.receiveProcessesError()); + yield put(actions.receiveProcessesError(e)); } } @@ -54,10 +54,24 @@ export function *watchFetchProcesses() { yield takeEvery(actions.FETCH_PROCESSES, fetchProcesses); } +export function *fetchProcessLogs(action) { + try { + const logs = yield call(api.fetchProcessLogs, action.processName); + yield put(actions.receiveProcessLogs(action.processName, logs)); + } catch (e) { + yield put(actions.receiveProcessLogsError(e)); + } +} + +export function *watchFetchProcessLogs() { + yield takeEvery(actions.FETCH_PROCESS_LOGS, fetchProcessLogs); +} + export default function *root() { yield all([ fork(watchFetchAccounts), fork(watchFetchProcesses), + fork(watchFetchProcessLogs), fork(watchFetchBlocks), fork(watchFetchTransactions) ]); diff --git a/lib/core/processes/processLauncher.js b/lib/core/processes/processLauncher.js index d470ca92..ef3b105f 100644 --- a/lib/core/processes/processLauncher.js +++ b/lib/core/processes/processLauncher.js @@ -21,6 +21,7 @@ class ProcessLauncher { this.silent = options.silent; this.exitCallback = options.exitCallback; this.embark = options.embark; + this.logs = []; this.subscriptions = {}; this._subscribeToMessages(); @@ -54,20 +55,29 @@ class ProcessLauncher { _registerAsPlugin() { const self = this; + const apiRoute = '/embark-api/process-logs/' + self.name; self.embark.registerAPICall( 'ws', - '/embark-api/process-logs/' + self.name, + apiRoute, (ws, _req) => { - self.events.on('log-' + self.name, function(logLevel, msg) { + self.events.on('process-log-' + self.name, function(logLevel, msg) { ws.send(JSON.stringify({msg, msg_clear: msg.stripColors, logLevel}), () => {}); }); } ); + self.embark.registerAPICall( + 'get', + apiRoute, + (req, res) => { + res.send(JSON.stringify(self.logs)); + } + ); } // Translates logs from the child process to the logger _handleLog(msg) { - this.events.emit('log-' + this.name, msg.type, msg.message); + this.events.emit('process-log-' + this.name, msg.type, msg.message); + this.logs.push({msg: msg.message, msg_clear: msg.message.stripColors, logLevel: msg.logLevel}); if (this.silent && msg.type !== 'error') { return; } From 131593067a178e49323e1f0da0050007b539b3ae Mon Sep 17 00:00:00 2001 From: Jonathan Rainville Date: Thu, 2 Aug 2018 12:04:34 -0400 Subject: [PATCH 4/4] fix errors and add swarm --- embark-ui/src/containers/ProcessesContainer.js | 17 +++++++---------- lib/modules/swarm/index.js | 9 +++++++-- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/embark-ui/src/containers/ProcessesContainer.js b/embark-ui/src/containers/ProcessesContainer.js index 3f21cddd..c98bc026 100644 --- a/embark-ui/src/containers/ProcessesContainer.js +++ b/embark-ui/src/containers/ProcessesContainer.js @@ -20,24 +20,21 @@ class ProcessesContainer extends Component { return ; } - if (processes.error) { - return ( -

- Error loading processes: {processes.error.message || processes.error} -

- ); - } - const processNames = Object.keys(processes.data); return (
- + {processes.error &&

+ Error: {processes.error.message || processes.error} +

} + + {processNames && processNames.length && {processNames.map(processName => { return ( ); })} - +
} +
); } diff --git a/lib/modules/swarm/index.js b/lib/modules/swarm/index.js index c479a100..26df159a 100644 --- a/lib/modules/swarm/index.js +++ b/lib/modules/swarm/index.js @@ -27,11 +27,15 @@ class Swarm { return; } + this.events.request('processes:register', 'swarm', (cb) => { + self.startProcess(cb); + }); + this.bzz = new Web3Bzz(this.providerUrl); this.setServiceCheck(); this.addProviderToEmbarkJS(); - this.startProcess(() => {}); + this.events.request("processes:launch", "swarm", () => {}); this.registerUploadCommand(); this._checkService((err) => { @@ -88,7 +92,8 @@ class Swarm { events: self.events, storageConfig: self.storageConfig, webServerConfig: self.webServerConfig, - blockchainConfig: self.blockchainConfig + blockchainConfig: self.blockchainConfig, + embark: self.embark }); self.logger.trace(`Storage module: Launching swarm process...`); return storageProcessesLauncher.launchProcess('swarm', callback);