From 284dcfdd144bef2accd6d72a6189041c9c63bb16 Mon Sep 17 00:00:00 2001 From: Silas Davis <silas@erisindustries.com> Date: Fri, 9 Sep 2016 15:50:28 +0100 Subject: [PATCH] Fix blocking event subscription in transactAndHold --- erisdb/pipe/transactor.go | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/erisdb/pipe/transactor.go b/erisdb/pipe/transactor.go index c406d9c6..23f6a000 100644 --- a/erisdb/pipe/transactor.go +++ b/erisdb/pipe/transactor.go @@ -177,12 +177,25 @@ func (this *transactor) TransactAndHold(privKey, address, data []byte, gasLimit, } else { addr = address } - wc := make(chan *types.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 *types.EventDataCall, 1) + subId := fmt.Sprintf("%X", rec.TxHash) this.eventEmitter.Subscribe(subId, types.EventStringAccCall(addr), func(evt types.EventData) { event := evt.(types.EventDataCall) if bytes.Equal(event.TxID, rec.TxHash) { - wc <- &event + // 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 receive. + 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 <- &event: + default: + } } }) -- GitLab