Skip to content

Commit

Permalink
fix(grpc): ensure full disconnect on window close
Browse files Browse the repository at this point in the history
Do not try to send incoming data from GRPC streams to the main window
after the window has been closed.

Fix LN-Zap#677
  • Loading branch information
mrfelton committed Aug 16, 2018
1 parent 8457549 commit 114151f
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 26 deletions.
9 changes: 5 additions & 4 deletions app/lib/lnd/lightning.js
Original file line number Diff line number Diff line change
Expand Up @@ -89,22 +89,23 @@ class Lightning {
*/
subscribe(mainWindow) {
this.mainWindow = mainWindow
this.subscriptions.channelGraph = subscribeToChannelGraph(this.mainWindow, this.lnd, mainLog)
this.subscriptions.invoices = subscribeToInvoices(this.mainWindow, this.lnd, mainLog)
this.subscriptions.transactions = subscribeToTransactions(this.mainWindow, this.lnd, mainLog)

this.subscriptions.channelGraph = subscribeToChannelGraph.call(this)
this.subscriptions.invoices = subscribeToInvoices.call(this)
this.subscriptions.transactions = subscribeToTransactions.call(this)
}

/**
* Unsubscribe from all bi-directional streams.
*/
unsubscribe() {
this.mainWindow = null
Object.keys(this.subscriptions).forEach(subscription => {
if (this.subscriptions[subscription]) {
this.subscriptions[subscription].cancel()
this.subscriptions[subscription] = null
}
})
this.mainWindow = null
}
}

Expand Down
23 changes: 15 additions & 8 deletions app/lib/lnd/subscribe/channelgraph.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,21 @@
import { status } from 'grpc'
import { mainLog } from '../../utils/log'

export default function subscribeToChannelGraph(mainWindow, lnd, log) {
const call = lnd.subscribeChannelGraph({})
export default function subscribeToChannelGraph() {
const call = this.lnd.subscribeChannelGraph({})

call.on('data', channelGraphData => mainWindow.send('channelGraphData', { channelGraphData }))
call.on('end', () => log.info('end'))
call.on('error', error => error.code !== status.CANCELLED && log.error(error))
call.on('status', channelGraphStatus =>
mainWindow.send('channelGraphStatus', { channelGraphStatus })
)
call.on('data', channelGraphData => {
if (this.mainWindow) {
this.mainWindow.send('channelGraphData', { channelGraphData })
}
})
call.on('end', () => mainLog.info('end'))
call.on('error', error => error.code !== status.CANCELLED && mainLog.error(error))
call.on('status', channelGraphStatus => {
if (this.mainWindow) {
this.mainWindow.send('channelGraphStatus', { channelGraphStatus })
}
})

return call
}
17 changes: 10 additions & 7 deletions app/lib/lnd/subscribe/invoices.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
import { status } from 'grpc'
import { mainLog } from '../../utils/log'

export default function subscribeToInvoices(mainWindow, lnd, log) {
const call = lnd.subscribeInvoices({})
export default function subscribeToInvoices() {
const call = this.lnd.subscribeInvoices({})

call.on('data', invoice => {
log.info('INVOICE:', invoice)
mainWindow.send('invoiceUpdate', { invoice })
mainLog.info('INVOICE:', invoice)
if (this.mainWindow) {
this.mainWindow.send('invoiceUpdate', { invoice })
}
})
call.on('end', () => log.info('end'))
call.on('error', error => error.code !== status.CANCELLED && log.error(error))
call.on('status', status => log.info('INVOICE STATUS:', status))
call.on('end', () => mainLog.info('end'))
call.on('error', error => error.code !== status.CANCELLED && mainLog.error(error))
call.on('status', status => mainLog.info('INVOICE STATUS:', status))

return call
}
17 changes: 10 additions & 7 deletions app/lib/lnd/subscribe/transactions.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
import { status } from 'grpc'
import { mainLog } from '../../utils/log'

export default function subscribeToTransactions(mainWindow, lnd, log) {
const call = lnd.subscribeTransactions({})
export default function subscribeToTransactions() {
const call = this.lnd.subscribeTransactions({})

call.on('data', transaction => {
log.info('TRANSACTION:', transaction)
mainWindow.send('newTransaction', { transaction })
mainLog.info('TRANSACTION:', transaction)
if (this.mainWindow) {
this.mainWindow.send('newTransaction', { transaction })
}
})
call.on('end', () => log.info('end'))
call.on('error', error => error.code !== status.CANCELLED && log.error(error))
call.on('status', status => log.info('TRANSACTION STATUS: ', status))
call.on('end', () => mainLog.info('end'))
call.on('error', error => error.code !== status.CANCELLED && mainLog.error(error))
call.on('status', status => mainLog.info('TRANSACTION STATUS: ', status))

return call
}

0 comments on commit 114151f

Please sign in to comment.