all: Refactor for new subscription API #72
Merged
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This is mostly in a good place, but there is one major sticking point:
wallet.NewManager
.With the old API, when a call to
cm.AddBlocks
returns, all of the subscribers will have finished processing the new update(s). With the new API, this is not true; the processing happens asynchronously. This broke some tests which expected that, after callingAddBlocks
, they could immediately observe the effects of those blocks in wallet state. Now, they can't, so we need a way for the test to wait until processing has finished. In most of the tests, I worked around this; see thesyncDB
helper I added. But that approach doesn't work when you have a real wallet manager running. For now, I faked the waiting withtime.Sleep
, just to see if that makes the tests pass (it does), but clearly we need a better solution.The whole asynchronous processing thing really bugs me, so much so that I tweaked the new API to release the chain manager's lock before calling the
onReorg
listener functions. This means it's now legal for your listener function to call chain manager methods -- meaning, you can implement subscription "the old fashioned way" and have youronReorg
function directly callUpdatesSince
in a loop until it's caught up. Effectively this brings us back to the same situation as before, except that the manager is no longer locked, so you have a bit more freedom. (And of course, you can still do async processing if you want.)But the other big wrinkle here is the wallet manager's
Subscribe
method. Previously, it unsubscribed from the chain manager, then resubscribed at a lower height. Firstly, it's not clear to me why this would work; won't you end up with duplicate state? But more importantly, we need to nail down how this action ought to interact with the wallet manager's ongoing subscription in the new API. In my PR code, we hold the wallet manager's lock while syncing, soSubscribe
effectively pauses the background subscription until it's finished. Not exactly pretty, but it gets the job done. Is there a better way? That's what I'm not sure about.