Skip to content
This repository has been archived by the owner on Apr 22, 2024. It is now read-only.

Add subscription subprovider to handle websocket pub/sub #207

Merged
merged 6 commits into from
Jan 25, 2018

Conversation

benjamincburns
Copy link
Contributor

Needs a test for the subscription subprovider itself, but otherwise I think this is ready.

@@ -3,6 +3,7 @@ const inherits = require('util').inherits
const ethUtil = require('ethereumjs-util')
const Subprovider = require('./subprovider.js')
const Stoplight = require('../util/stoplight.js')
const EventEmitter = require('events').EventEmitter
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is correct and fine but you can also just do

const EventEmitter = require('events')

method = self.newLogFilter.bind(self, options)
break
case 'newPendingTransactions':
method = self.newPendingTransactionFilter
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this prolly needs bind(self)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure why it would, but I'll add it for symmetry w/ the one above it

self.allResults.push(log)
})
if (validLogs.length > 0) {
self.emit('data', validLogs)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

does this also need the null error event?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no, the only consumer of the event is the SubscriptionSubprovider - would rather emit error in that case.

return
}

method(function(err, id) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i found this part least clear
maybe renaming to createFilter would be better

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

makes sense

}

method(function(err, id) {
if (!err) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

abort early on err

if (err) return cb(err)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good catch - no idea why I wrote it that way :-/


// a cheap crack at multiple inheritance
// I don't really care if `instanceof EventEmitter` passes...
Object.assign(SubscriptionSubprovider.prototype, EventEmitter.prototype)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think instead of SubscriptionSubprovider being an EE, we can just make engine an EE and require that to be passed into the constructor -- and lol directly emit events on it /shrug

Copy link
Contributor Author

@benjamincburns benjamincburns Jan 4, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd rather leave it like it is - I see no reason why this class needs to be tightly coupled to engine like that. Further, in ganache-core I make the provider an EventEmitter (it must be, per web3 requirements), and I proxy the EE methods for the data event directly to the SubscriptionSubprovider. I like it this way over proxying to the engine because it's more explicit that I'm subscribing to pub/sub events.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now that I've thought about it a bit more, I wonder if there shouldn't be an event middleware stack. As pub/sub grows in scope, I could imagine wanting to write middleware that would squelch or mutate notifications.

Maybe that's just YAGNI, though...

SubscriptionSubprovider.prototype._notificationHandler = function (id, subscriptionType, result) {
const self = this
if (subscriptionType === 'newHeads') {
result = {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should break this off as a utility method

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

defo


SubscriptionSubprovider.prototype.unsubscribe = function(connection, payload, cb) {
let subscriptionId = payload.params[0]
if (!this.subscriptions.hasOwnProperty(subscriptionId.toLowerCase())) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this.subscriptions[subscriptionId] should be fine, eh?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the id is a hex string - I wanted it to be case insensitive

Copy link
Contributor Author

@benjamincburns benjamincburns Jan 4, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

but ew, I forgot to write it in that way over in subscribe - I'll fix it there
Edit: and also below the line you commented on here... ugly.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

alternatively I could normalize it so that 0x0001 matches 0x1, etc.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok, forget all that noise - I'm going to do it your way :-D

break
case 'newHeads':
method = self.newBlockFilter
cb(null, id)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wtf? That shouldn't have been there... I definitely need to write some tests in here - have been relying too heavily on ganache integration tests

@kumavis kumavis merged commit 32b5b0c into MetaMask:master Jan 25, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants