mirror of
https://github.com/embarklabs/embark.git
synced 2025-01-11 14:24:24 +00:00
Use process log ids
This commit is contained in:
parent
5d29ab1d42
commit
de009db74f
@ -1,3 +1,5 @@
|
|||||||
|
import {EMBARK_PROCESS_NAME} from '../constants';
|
||||||
|
|
||||||
export const REQUEST = 'REQUEST';
|
export const REQUEST = 'REQUEST';
|
||||||
export const SUCCESS = 'SUCCESS';
|
export const SUCCESS = 'SUCCESS';
|
||||||
export const FAILURE = 'FAILURE';
|
export const FAILURE = 'FAILURE';
|
||||||
@ -92,28 +94,21 @@ export const processes = {
|
|||||||
|
|
||||||
export const COMMANDS = createRequestTypes('COMMANDS');
|
export const COMMANDS = createRequestTypes('COMMANDS');
|
||||||
export const commands = {
|
export const commands = {
|
||||||
post: (command) => action(COMMANDS[REQUEST], {command, noLoading: true}),
|
post: (command) => action(COMMANDS[REQUEST], {command}),
|
||||||
success: (command) => action(COMMANDS[SUCCESS], {commands: [{timestamp: new Date().getTime(), ...command}]}),
|
success: (command, payload) => {
|
||||||
|
return action(COMMANDS[SUCCESS], {processLogs: [{
|
||||||
|
timestamp: new Date().getTime(),
|
||||||
|
name: EMBARK_PROCESS_NAME,
|
||||||
|
msg: `${payload.command} > ${command.result}`
|
||||||
|
}]})
|
||||||
|
},
|
||||||
failure: (error) => action(COMMANDS[FAILURE], {error})
|
failure: (error) => action(COMMANDS[FAILURE], {error})
|
||||||
};
|
};
|
||||||
|
|
||||||
export const PROCESS_LOGS = createRequestTypes('PROCESS_LOGS');
|
export const PROCESS_LOGS = createRequestTypes('PROCESS_LOGS');
|
||||||
export const processLogs = {
|
export const processLogs = {
|
||||||
request: (processName, limit) => action(PROCESS_LOGS[REQUEST], {processName, limit}),
|
request: (processName) => action(PROCESS_LOGS[REQUEST], {processName}),
|
||||||
success: (processLogs, payload) => {
|
success: (processLogs) => action(PROCESS_LOGS[SUCCESS], {processLogs}),
|
||||||
return action(PROCESS_LOGS[SUCCESS],
|
|
||||||
{
|
|
||||||
ws: !!payload.ws,
|
|
||||||
processLogs: [
|
|
||||||
{
|
|
||||||
process: payload.processName,
|
|
||||||
timestamp: new Date().getTime(),
|
|
||||||
logs: processLogs
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
);
|
|
||||||
},
|
|
||||||
failure: (error) => action(PROCESS_LOGS[FAILURE], {error})
|
failure: (error) => action(PROCESS_LOGS[FAILURE], {error})
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -154,7 +149,7 @@ export const contractFile = {
|
|||||||
|
|
||||||
export const CONTRACT_FUNCTION = createRequestTypes('CONTRACT_FUNCTION');
|
export const CONTRACT_FUNCTION = createRequestTypes('CONTRACT_FUNCTION');
|
||||||
export const contractFunction = {
|
export const contractFunction = {
|
||||||
post: (contractName, method, inputs, gasPrice) => action(CONTRACT_FUNCTION[REQUEST], {contractName, method, inputs, gasPrice, noLoading: true}),
|
post: (contractName, method, inputs, gasPrice) => action(CONTRACT_FUNCTION[REQUEST], {contractName, method, inputs, gasPrice}),
|
||||||
success: (result, payload) => action(CONTRACT_FUNCTION[SUCCESS], {contractFunctions: [{...result, ...payload}]}),
|
success: (result, payload) => action(CONTRACT_FUNCTION[SUCCESS], {contractFunctions: [{...result, ...payload}]}),
|
||||||
failure: (error) => action(CONTRACT_FUNCTION[FAILURE], {error})
|
failure: (error) => action(CONTRACT_FUNCTION[FAILURE], {error})
|
||||||
};
|
};
|
||||||
|
@ -6,14 +6,6 @@ import Convert from 'ansi-to-html';
|
|||||||
|
|
||||||
const convert = new Convert();
|
const convert = new Convert();
|
||||||
|
|
||||||
const CommandResult = ({result}) => (
|
|
||||||
<p className="text__new-line">{result}</p>
|
|
||||||
);
|
|
||||||
|
|
||||||
CommandResult.propTypes = {
|
|
||||||
result: PropTypes.string
|
|
||||||
};
|
|
||||||
|
|
||||||
class Console extends Component {
|
class Console extends Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
@ -31,41 +23,15 @@ class Console extends Component {
|
|||||||
this.setState({value: event.target.value});
|
this.setState({value: event.target.value});
|
||||||
}
|
}
|
||||||
|
|
||||||
getProcessLogs(processName){
|
|
||||||
const log = this.props.processLogs
|
|
||||||
.reverse()
|
|
||||||
.filter(item => item.process === processName);
|
|
||||||
|
|
||||||
if(!log.length) return [];
|
|
||||||
// the selector should have reduced `processLogs` down to one
|
|
||||||
// record per process, and therefore after filtering, the array
|
|
||||||
// should have only one item
|
|
||||||
return log[0].logs;
|
|
||||||
}
|
|
||||||
|
|
||||||
renderCommandsResult(){
|
|
||||||
const {commands} = this.props;
|
|
||||||
return (
|
|
||||||
this.props.isEmbark() &&
|
|
||||||
commands.map((command, index) => {
|
|
||||||
return <CommandResult key={index} result={command.result}/>;
|
|
||||||
})
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
renderTabs() {
|
renderTabs() {
|
||||||
const {processes} = this.props;
|
const {processLogs, processes} = this.props;
|
||||||
return processes
|
return processes.map(process => (
|
||||||
.sort((a, b) => { // ensure the "Embark" tab is displayed first
|
<Tab title={process.name} key={process.name}>
|
||||||
if (a.name === 'embark') return -1;
|
|
||||||
if (b.name === 'embark') return 1;
|
|
||||||
return 0;
|
|
||||||
})
|
|
||||||
.map(process => (
|
|
||||||
<Tab title={process.name} key={process.name} onClick={(e, x) => this.clickTab(e, x)}>
|
|
||||||
<Logs>
|
<Logs>
|
||||||
{
|
{
|
||||||
this.getProcessLogs(process.name)
|
processLogs
|
||||||
|
.filter((item) => item.name === process.name)
|
||||||
|
.reverse()
|
||||||
.map((item, i) => <p key={i} className={item.logLevel}
|
.map((item, i) => <p key={i} className={item.logLevel}
|
||||||
dangerouslySetInnerHTML={{__html: convert.toHtml(item.msg)}}></p>)
|
dangerouslySetInnerHTML={{__html: convert.toHtml(item.msg)}}></p>)
|
||||||
}
|
}
|
||||||
@ -76,7 +42,6 @@ class Console extends Component {
|
|||||||
|
|
||||||
render() {
|
render() {
|
||||||
const tabs = this.renderTabs();
|
const tabs = this.renderTabs();
|
||||||
const commandsResult = this.renderCommandsResult();
|
|
||||||
const {value} = this.state;
|
const {value} = this.state;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -93,7 +58,6 @@ class Console extends Component {
|
|||||||
</TabbedHeader>
|
</TabbedHeader>
|
||||||
<TabbedContainer selectedTitle={this.props.activeProcess}>
|
<TabbedContainer selectedTitle={this.props.activeProcess}>
|
||||||
{tabs}
|
{tabs}
|
||||||
{commandsResult}
|
|
||||||
</TabbedContainer>
|
</TabbedContainer>
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
</Card.Body>
|
</Card.Body>
|
||||||
@ -115,7 +79,6 @@ class Console extends Component {
|
|||||||
Console.propTypes = {
|
Console.propTypes = {
|
||||||
postCommand: PropTypes.func,
|
postCommand: PropTypes.func,
|
||||||
isEmbark: PropTypes.func,
|
isEmbark: PropTypes.func,
|
||||||
commands: PropTypes.arrayOf(PropTypes.object).isRequired,
|
|
||||||
processes: PropTypes.arrayOf(PropTypes.object).isRequired,
|
processes: PropTypes.arrayOf(PropTypes.object).isRequired,
|
||||||
processLogs: PropTypes.arrayOf(PropTypes.object).isRequired,
|
processLogs: PropTypes.arrayOf(PropTypes.object).isRequired,
|
||||||
updateTab: PropTypes.func
|
updateTab: PropTypes.func
|
||||||
|
1
embark-ui/src/constants.js
Normal file
1
embark-ui/src/constants.js
Normal file
@ -0,0 +1 @@
|
|||||||
|
export const EMBARK_PROCESS_NAME = 'embark';
|
@ -7,10 +7,8 @@ import {commands as commandsAction, listenToProcessLogs, processLogs as processL
|
|||||||
import DataWrapper from "../components/DataWrapper";
|
import DataWrapper from "../components/DataWrapper";
|
||||||
import Processes from '../components/Processes';
|
import Processes from '../components/Processes';
|
||||||
import Console from '../components/Console';
|
import Console from '../components/Console';
|
||||||
import {getProcesses, getCommands, getProcessLogs} from "../reducers/selectors";
|
import {getProcesses, getProcessLogs} from "../reducers/selectors";
|
||||||
|
import {EMBARK_PROCESS_NAME} from '../constants';
|
||||||
const EMBARK_PROCESS_NAME = 'embark';
|
|
||||||
const LOG_LIMIT = 50;
|
|
||||||
|
|
||||||
class HomeContainer extends Component {
|
class HomeContainer extends Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
@ -31,8 +29,12 @@ class HomeContainer extends Component {
|
|||||||
this.props.stopProcessLogs(this.state.activeProcess)
|
this.props.stopProcessLogs(this.state.activeProcess)
|
||||||
}
|
}
|
||||||
|
|
||||||
this.props.fetchProcessLogs(processName, LOG_LIMIT);
|
if (processName === EMBARK_PROCESS_NAME) {
|
||||||
if (processName !== EMBARK_PROCESS_NAME) {
|
if (this.props.processes.length === 0) {
|
||||||
|
this.props.fetchProcessLogs(processName);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.props.fetchProcessLogs(processName);
|
||||||
this.props.listenToProcessLogs(processName);
|
this.props.listenToProcessLogs(processName);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -50,7 +52,6 @@ class HomeContainer extends Component {
|
|||||||
<DataWrapper shouldRender={this.props.processes.length > 0 } {...this.props} render={({processes, postCommand, processLogs}) => (
|
<DataWrapper shouldRender={this.props.processes.length > 0 } {...this.props} render={({processes, postCommand, processLogs}) => (
|
||||||
<Console activeProcess={this.state.activeProcess}
|
<Console activeProcess={this.state.activeProcess}
|
||||||
postCommand={postCommand}
|
postCommand={postCommand}
|
||||||
commands={this.props.commands}
|
|
||||||
processes={processes}
|
processes={processes}
|
||||||
processLogs={processLogs}
|
processLogs={processLogs}
|
||||||
isEmbark={() => this.isEmbark}
|
isEmbark={() => this.isEmbark}
|
||||||
@ -64,7 +65,6 @@ class HomeContainer extends Component {
|
|||||||
HomeContainer.propTypes = {
|
HomeContainer.propTypes = {
|
||||||
processes: PropTypes.arrayOf(PropTypes.object),
|
processes: PropTypes.arrayOf(PropTypes.object),
|
||||||
postCommand: PropTypes.func,
|
postCommand: PropTypes.func,
|
||||||
commands: PropTypes.arrayOf(PropTypes.object),
|
|
||||||
error: PropTypes.string,
|
error: PropTypes.string,
|
||||||
loading: PropTypes.bool
|
loading: PropTypes.bool
|
||||||
};
|
};
|
||||||
@ -72,7 +72,6 @@ HomeContainer.propTypes = {
|
|||||||
function mapStateToProps(state) {
|
function mapStateToProps(state) {
|
||||||
return {
|
return {
|
||||||
processes: getProcesses(state),
|
processes: getProcesses(state),
|
||||||
commands: getCommands(state),
|
|
||||||
error: state.errorMessage,
|
error: state.errorMessage,
|
||||||
processLogs: getProcessLogs(state),
|
processLogs: getProcessLogs(state),
|
||||||
loading: state.loading
|
loading: state.loading
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import {combineReducers} from 'redux';
|
import {combineReducers} from 'redux';
|
||||||
import {REQUEST, SUCCESS, FAILURE, CONTRACT_COMPILE, FILES, LOGOUT, AUTHENTICATE,
|
import {REQUEST, SUCCESS, FAILURE, CONTRACT_COMPILE, FILES, LOGOUT, AUTHENTICATE,
|
||||||
FETCH_CREDENTIALS, UPDATE_BASE_ETHER, PROCESS_LOGS} from "../actions";
|
FETCH_CREDENTIALS, UPDATE_BASE_ETHER} from "../actions";
|
||||||
|
import {EMBARK_PROCESS_NAME} from '../constants';
|
||||||
|
|
||||||
const BN_FACTOR = 10000;
|
const BN_FACTOR = 10000;
|
||||||
const VOID_ADDRESS = '0x0000000000000000000000000000000000000000';
|
const VOID_ADDRESS = '0x0000000000000000000000000000000000000000';
|
||||||
@ -19,7 +20,6 @@ const entitiesDefaultState = {
|
|||||||
contractDeploys: [],
|
contractDeploys: [],
|
||||||
contractCompiles: [],
|
contractCompiles: [],
|
||||||
contractLogs: [],
|
contractLogs: [],
|
||||||
commands: [],
|
|
||||||
messages: [],
|
messages: [],
|
||||||
messageChannels: [],
|
messageChannels: [],
|
||||||
versions: [],
|
versions: [],
|
||||||
@ -37,7 +37,22 @@ const sorter = {
|
|||||||
transactions: function(a, b) {
|
transactions: function(a, b) {
|
||||||
return ((BN_FACTOR * b.blockNumber) + b.transactionIndex) - ((BN_FACTOR * a.blockNumber) + a.transactionIndex);
|
return ((BN_FACTOR * b.blockNumber) + b.transactionIndex) - ((BN_FACTOR * a.blockNumber) + a.transactionIndex);
|
||||||
},
|
},
|
||||||
|
processes: function(a, b) {
|
||||||
|
if (a.name === EMBARK_PROCESS_NAME) return -1;
|
||||||
|
if (b.name === EMBARK_PROCESS_NAME) return 1;
|
||||||
|
return 0;
|
||||||
|
},
|
||||||
processLogs: function(a, b) {
|
processLogs: function(a, b) {
|
||||||
|
if (a.name !== b.name) {
|
||||||
|
if(a.name < b.name) return -1;
|
||||||
|
if(a.name > b.name) return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (a.id === undefined && b.id === undefined) {
|
||||||
|
return b.timestamp - a.timestamp;
|
||||||
|
}
|
||||||
|
|
||||||
return b.id - a.id;
|
return b.id - a.id;
|
||||||
},
|
},
|
||||||
contractLogs: function(a, b) {
|
contractLogs: function(a, b) {
|
||||||
@ -46,9 +61,6 @@ const sorter = {
|
|||||||
messages: function(a, b) {
|
messages: function(a, b) {
|
||||||
return a.time - b.time;
|
return a.time - b.time;
|
||||||
},
|
},
|
||||||
commands: function(a, b) {
|
|
||||||
return a.timestamp - b.timestamp;
|
|
||||||
},
|
|
||||||
files: function(a, b) {
|
files: function(a, b) {
|
||||||
if (a.name < b.name) return -1;
|
if (a.name < b.name) return -1;
|
||||||
if (a.name > b.name) return 1;
|
if (a.name > b.name) return 1;
|
||||||
@ -61,7 +73,10 @@ const filtrer = {
|
|||||||
return index === self.findIndex((t) => t.name === process.name);
|
return index === self.findIndex((t) => t.name === process.name);
|
||||||
},
|
},
|
||||||
processLogs: function(processLog, index, self) {
|
processLogs: function(processLog, index, self) {
|
||||||
|
if (processLog.id !== undefined) {
|
||||||
return index === self.findIndex((p) => p.id === processLog.id) && index <= MAX_ELEMENTS
|
return index === self.findIndex((p) => p.id === processLog.id) && index <= MAX_ELEMENTS
|
||||||
|
}
|
||||||
|
return true;
|
||||||
},
|
},
|
||||||
contracts: function(contract, index, self) {
|
contracts: function(contract, index, self) {
|
||||||
return index === self.findIndex((t) => t.className === contract.className);
|
return index === self.findIndex((t) => t.className === contract.className);
|
||||||
@ -103,12 +118,6 @@ const filtrer = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
function entities(state = entitiesDefaultState, action) {
|
function entities(state = entitiesDefaultState, action) {
|
||||||
if (action.type === PROCESS_LOGS[SUCCESS] && action.ws === true){
|
|
||||||
const process = action.processLogs[0].process;
|
|
||||||
let processLogs = state.processLogs.filter(logs => logs.process === process).sort((a, b) => b.timestamp - a.timestamp)[0];
|
|
||||||
processLogs.logs.push(action.processLogs[0].logs[0]);
|
|
||||||
return {...state};
|
|
||||||
}
|
|
||||||
if (action.type === FILES[SUCCESS]) {
|
if (action.type === FILES[SUCCESS]) {
|
||||||
return {...state, files: action.files};
|
return {...state, files: action.files};
|
||||||
}
|
}
|
||||||
@ -155,7 +164,7 @@ function errorEntities(state = {}, action) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function loading(_state = false, action) {
|
function loading(_state = false, action) {
|
||||||
return action.type.endsWith(REQUEST) && !action.noLoading;
|
return action.type.endsWith(REQUEST);
|
||||||
}
|
}
|
||||||
|
|
||||||
function compilingContract(state = false, action) {
|
function compilingContract(state = false, action) {
|
||||||
|
@ -44,23 +44,12 @@ export function getBlock(state, number) {
|
|||||||
return state.entities.blocks.find((block) => block.number.toString() === number);
|
return state.entities.blocks.find((block) => block.number.toString() === number);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getCommands(state) {
|
|
||||||
return state.entities.commands;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function getProcesses(state) {
|
export function getProcesses(state) {
|
||||||
return state.entities.processes;
|
return state.entities.processes;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getProcessLogs(state) {
|
export function getProcessLogs(state) {
|
||||||
const processLogsObj = state.entities.processLogs.reduce((processLogs, processLog) => {
|
return state.entities.processLogs;
|
||||||
const existingProcessLog = processLogs[processLog.process];
|
|
||||||
if(!existingProcessLog || processLog.timestamp > existingProcessLog.timestamp){
|
|
||||||
processLogs[processLog.process] = processLog;
|
|
||||||
}
|
|
||||||
return processLogs;
|
|
||||||
}, {});
|
|
||||||
return Object.values(processLogsObj);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getContractLogsByContract(state, contractName) {
|
export function getContractLogsByContract(state, contractName) {
|
||||||
|
@ -241,7 +241,7 @@ export function *listenToProcessLogs(action) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
yield put(actions.processLogs.success([processLog], {processName: action.processName, ws: true}));
|
yield put(actions.processLogs.success([processLog]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,7 +56,7 @@ export function fetchProcesses() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function fetchProcessLogs(payload) {
|
export function fetchProcessLogs(payload) {
|
||||||
return get(`/process-logs/${payload.processName}`, {params: payload, processName: payload.processName, credentials: payload.credentials});
|
return get(`/process-logs/${payload.processName}`, ...arguments);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function fetchContractLogs() {
|
export function fetchContractLogs() {
|
||||||
|
@ -84,7 +84,7 @@ class ProcessLauncher {
|
|||||||
self.embark.registerAPICall(
|
self.embark.registerAPICall(
|
||||||
'get',
|
'get',
|
||||||
apiRoute,
|
apiRoute,
|
||||||
(req, res) => {
|
(_req, res) => {
|
||||||
const result = self.logs.map((log, id) => Object.assign(log, {id})).slice(-50);
|
const result = self.logs.map((log, id) => Object.assign(log, {id})).slice(-50);
|
||||||
res.send(JSON.stringify(result));
|
res.send(JSON.stringify(result));
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user