Browse Source

Merge pull request #527 from gre/run-networking-in-renderer-debug-mode

implement a executeHttpQueryOnRenderer
master
Meriadec Pillet 7 years ago
committed by GitHub
parent
commit
921d57ef0f
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 14
      src/api/network.js
  2. 8
      src/helpers/ipc.js
  3. 45
      src/internals/index.js
  4. 2
      src/main/app.js
  5. 27
      src/main/bridge.js
  6. 12
      src/renderer/events.js

14
src/api/network.js

@ -4,19 +4,23 @@ import { GET_CALLS_RETRY, GET_CALLS_TIMEOUT } from 'config/constants'
import { userFriendlyError } from 'api/Ledger'
import { retry } from 'helpers/promise'
const doRequest = axios // TODO later introduce a way to run it in renderer based on a env, we will diverge this implementation
export default (arg: Object) => {
let implementation = (arg: Object) => {
let promise
if (arg.method === 'GET') {
if (!('timeout' in arg)) {
arg.timeout = GET_CALLS_TIMEOUT
}
promise = retry(() => doRequest(arg), {
promise = retry(() => axios(arg), {
maxRetry: GET_CALLS_RETRY,
})
} else {
promise = doRequest(arg)
promise = axios(arg)
}
return userFriendlyError(promise)
}
export const setImplementation = (impl: *) => {
implementation = impl
}
export default (arg: Object) => implementation(arg)

8
src/helpers/ipc.js

@ -28,7 +28,7 @@ export class Command<In, A> {
}
type Msg<A> = {
type: 'NEXT' | 'COMPLETE' | 'ERROR',
type: 'cmd.NEXT' | 'cmd.COMPLETE' | 'cmd.ERROR',
requestId: string,
data?: A,
}
@ -48,20 +48,20 @@ function ipcRendererSendCommand<In, A>(id: string, data: In): Observable<A> {
function handleCommandEvent(e, msg: Msg<A>) {
if (requestId !== msg.requestId) return
switch (msg.type) {
case 'NEXT':
case 'cmd.NEXT':
logger.log(`● CMD ${id}`, msg.data)
if (msg.data) {
o.next(msg.data)
}
break
case 'COMPLETE':
case 'cmd.COMPLETE':
logger.log(`✔ CMD ${id} finished in ${(Date.now() - startTime).toFixed(0)}ms`)
o.complete()
ipcRenderer.removeListener('command-event', handleCommandEvent)
break
case 'ERROR':
case 'cmd.ERROR':
logger.warn(`✖ CMD ${id} error`, msg.data)
o.error(msg.data)
ipcRenderer.removeListener('command-event', handleCommandEvent)

45
src/internals/index.js

@ -1,12 +1,39 @@
// @flow
import commands from 'commands'
import logger from 'logger'
import uuid from 'uuid/v4'
import { setImplementation } from 'api/network'
require('../env')
require('../init-sentry')
process.title = 'Internal'
const defers = {}
if (process.env.DEBUG_NETWORK) {
setImplementation(networkArg => {
const id = uuid()
return new Promise((resolve, reject) => {
process.send({
type: 'executeHttpQueryOnRenderer',
networkArg,
id,
})
defers[id] = {
resolve: r => {
resolve(r)
delete defers[id]
},
reject: e => {
reject(e)
delete defers[id]
},
}
})
})
}
const subscriptions = {}
process.on('message', m => {
@ -20,7 +47,7 @@ process.on('message', m => {
subscriptions[requestId] = cmd.impl(data).subscribe({
next: data => {
process.send({
type: 'NEXT',
type: 'cmd.NEXT',
requestId,
data,
})
@ -28,7 +55,7 @@ process.on('message', m => {
complete: () => {
delete subscriptions[requestId]
process.send({
type: 'COMPLETE',
type: 'cmd.COMPLETE',
requestId,
})
},
@ -36,7 +63,7 @@ process.on('message', m => {
logger.warn('Command error:', error)
delete subscriptions[requestId]
process.send({
type: 'ERROR',
type: 'cmd.ERROR',
requestId,
data: {
...error,
@ -53,6 +80,18 @@ process.on('message', m => {
sub.unsubscribe()
delete subscriptions[requestId]
}
} else if (m.type === 'executeHttpQueryPayload') {
const { payload } = m
const defer = defers[payload.id]
if (!defer) {
logger.warn('executeHttpQueryPayload: no defer found')
return
}
if (payload.type === 'success') {
defer.resolve(payload.result)
} else {
defer.reject(payload.error)
}
}
})

2
src/main/app.js

@ -9,6 +9,8 @@ import db from 'helpers/db'
// necessary to prevent win from being garbage collected
let mainWindow = null
export const getMainWindow = () => mainWindow
let forceClose = false
const { UPGRADE_EXTENSIONS, ELECTRON_WEBPACK_WDS_PORT, DEV_TOOLS, DEV_TOOLS_MODE } = process.env

27
src/main/bridge.js

@ -10,6 +10,8 @@ import logger from 'logger'
import setupAutoUpdater, { quitAndInstall } from './autoUpdate'
import { getMainWindow } from './app'
// sqlite files will be located in the app local data folder
const LEDGER_LIVE_SQLITE_PATH = path.resolve(app.getPath('userData'), 'sqlite')
@ -30,6 +32,7 @@ const bootInternalProcess = () => {
internalProcess = fork(forkBundlePath, {
env: { ...process.env, LEDGER_LIVE_SQLITE_PATH },
})
internalProcess.on('message', handleGlobalInternalMessage)
internalProcess.on('exit', code => {
logger.warn(`Internal process ended with code ${code}`)
internalProcess = null
@ -58,7 +61,7 @@ ipcMainListenReceiveCommands({
p.removeListener('message', handleMessage)
p.removeListener('exit', handleExit)
notifyCommandEvent({
type: 'ERROR',
type: 'cmd.ERROR',
requestId: command.requestId,
data: { message: `Internal process error (${code})`, name: 'InternalError' },
})
@ -67,7 +70,7 @@ ipcMainListenReceiveCommands({
const handleMessage = payload => {
if (payload.requestId !== command.requestId) return
notifyCommandEvent(payload)
if (payload.type === 'ERROR' || payload.type === 'COMPLETE') {
if (payload.type === 'cmd.ERROR' || payload.type === 'cmd.COMPLETE') {
p.removeListener('message', handleMessage)
p.removeListener('exit', handleExit)
}
@ -79,6 +82,26 @@ ipcMainListenReceiveCommands({
},
})
function handleGlobalInternalMessage(payload) {
if (payload.type === 'executeHttpQueryOnRenderer') {
const win = getMainWindow && getMainWindow()
if (!win) {
logger.warn("can't executeHttpQueryOnRenderer because no renderer")
return
}
win.webContents.send('executeHttpQuery', {
id: payload.id,
networkArg: payload.networkArg,
})
}
}
ipcMain.on('executeHttpQueryPayload', (event, payload) => {
const p = internalProcess
if (!p) return
p.send({ type: 'executeHttpQueryPayload', payload })
})
// TODO move this to "command" pattern
ipcMain.on('updater', (event, { type, data }) => {
const handler = {

12
src/renderer/events.js

@ -10,6 +10,7 @@
import 'commands'
import logger from 'logger'
import network from 'api/network'
import { ipcRenderer } from 'electron'
import debug from 'debug'
@ -79,6 +80,17 @@ export default ({ store }: { store: Object, locked: boolean }) => {
syncDevices()
ipcRenderer.on('executeHttpQuery', (event: any, { networkArg, id }) => {
network(networkArg).then(
result => {
ipcRenderer.send('executeHttpQueryPayload', { type: 'success', id, result })
},
error => {
ipcRenderer.send('executeHttpQueryPayload', { type: 'error', id, error })
},
)
})
if (__PROD__) {
// TODO move this to "command" pattern
const updaterHandlers = {

Loading…
Cancel
Save