Browse Source

debounce the device add/remove + better logs

master
Gaëtan Renaudeau 7 years ago
parent
commit
34a1621c0a
  1. 51
      src/commands/listenDevices.js
  2. 9
      src/helpers/ipc.js

51
src/commands/listenDevices.js

@ -4,6 +4,55 @@ import { createCommand } from 'helpers/ipc'
import { Observable } from 'rxjs'
import CommNodeHid from '@ledgerhq/hw-transport-node-hid'
const cmd = createCommand('listenDevices', () => Observable.create(CommNodeHid.listen))
const DEBOUNCE_REMOVE_DEVICE_EVENT = 500
const cmd = createCommand('listenDevices', () =>
Observable.create(o => {
const pendingRemovePerPath = {}
const sub = CommNodeHid.listen({
next: e => {
// debounce the add/remove in case we see quick `remove,add` events on same path.
switch (e.type) {
case 'add': {
const pendingRemove = pendingRemovePerPath[e.descriptor]
if (pendingRemove) {
console.warn(`Skipping remove/add usb event for ${e.descriptor}`)
// there where a recent "remove" event, we don't emit add because we didn't emit "remove" yet.
clearTimeout(pendingRemove)
delete pendingRemovePerPath[e.descriptor]
} else {
// if there were no recent "remove", we just emit the "add"
o.next(e)
}
break
}
case 'remove': {
// we we always debounce the "remove" event. emit it a bit later in case a "add" of same descriptor happen soon.
if (pendingRemovePerPath[e.descriptor]) {
clearTimeout(pendingRemovePerPath[e.descriptor])
}
pendingRemovePerPath[e.descriptor] = setTimeout(() => {
delete pendingRemovePerPath[e.descriptor]
o.next(e)
}, DEBOUNCE_REMOVE_DEVICE_EVENT)
break
}
default:
o.next(e)
}
},
complete: () => {
o.complete()
},
error: err => {
o.error(err)
},
})
return () => {
Object.keys(pendingRemovePerPath).map(k => clearTimeout(pendingRemovePerPath[k]))
sub.unsubscribe()
}
}),
)
export default cmd

9
src/helpers/ipc.js

@ -37,6 +37,7 @@ function ipcRendererSendCommand<In, A>(id: string, data: In): Observable<A> {
const { ipcRenderer } = require('electron')
return Observable.create(o => {
const requestId: string = uuidv4()
const startTime = Date.now()
const unsubscribe = () => {
ipcRenderer.send('command-unsubscribe', { requestId })
@ -47,20 +48,20 @@ function ipcRendererSendCommand<In, A>(id: string, data: In): Observable<A> {
if (requestId !== msg.requestId) return
switch (msg.type) {
case 'NEXT':
console.log('<= COMMAND next', msg)
console.log(`● CMD ${id}`, msg.data)
if (msg.data) {
o.next(msg.data)
}
break
case 'COMPLETE':
console.log('<= COMMAND complete', msg)
console.log(`✔ CMD ${id} finished in ${(Date.now() - startTime).toFixed(0)}ms`)
o.complete()
ipcRenderer.removeListener('command-event', handleCommandEvent)
break
case 'ERROR':
console.warn('<= COMMAND error', msg)
console.warn(`✖ CMD ${id} error`, msg.data)
o.error(msg.data)
ipcRenderer.removeListener('command-event', handleCommandEvent)
break
@ -73,7 +74,7 @@ function ipcRendererSendCommand<In, A>(id: string, data: In): Observable<A> {
ipcRenderer.send('command', { id, data, requestId })
console.log('=> COMMAND', { id, data, requestId })
console.log(`CMD ${id}.send(`, data, ')')
return unsubscribe
})

Loading…
Cancel
Save