From 6c6e66f7b2e776add2bfbfbafa9c991c90bc15f4 Mon Sep 17 00:00:00 2001 From: Silas Davis <silas@erisindustries.com> Date: Fri, 9 Sep 2016 20:17:06 +0100 Subject: [PATCH] Fix blocking event subscription in transactAndHold --- manager/eris-mint/transactor.go | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/manager/eris-mint/transactor.go b/manager/eris-mint/transactor.go index fd920145..23012e4a 100644 --- a/manager/eris-mint/transactor.go +++ b/manager/eris-mint/transactor.go @@ -205,13 +205,24 @@ func (this *transactor) TransactAndHold(privKey, address, data []byte, gasLimit, } else { addr = address } - wc := make(chan *txs.EventDataCall) + // We want non-blocking on the first event received (but buffer the value), + // after which we want to block (and then discard the value - see below) + wc := make(chan *txs.EventDataCall, 1) subId := fmt.Sprintf("%X", rec.TxHash) this.eventEmitter.Subscribe(subId, txs.EventStringAccCall(addr), func(evt txs.EventData) { - event := evt.(txs.EventDataCall) - if bytes.Equal(event.TxID, rec.TxHash) { - wc <- &event + eventDataCall := evt.(txs.EventDataCall) + if bytes.Equal(eventDataCall.TxID, rec.TxHash) { + // Beware the contract of go-events subscribe is that we must not be + // blocking in an event callback when we try to unsubscribe! + // We work around this by using a non-blocking send. + select { + // This is a non-blocking send, but since we are using a buffered + // channel of size 1 we will always grab our first event even if we + // haven't read from the channel at the time we receive the first event. + case wc <- &eventDataCall: + default: + } } }) -- GitLab