Skip to content
This repository has been archived by the owner on Nov 6, 2020. It is now read-only.

Generic PubSub implementation #5456

Merged
merged 9 commits into from May 6, 2017
Merged

Generic PubSub implementation #5456

merged 9 commits into from May 6, 2017

Conversation

tomusdrw
Copy link
Collaborator

This allows to subscribe to any RPC method. Parity does the polling internally (every 1second).

In future we can optimize it, most of the cases can be polled for instance when new block arrives.

@ngotchac Maybe UI can switch for that, might be much better especially for hosted environments.

@tomusdrw tomusdrw added A0-pleasereview 🤓 Pull request needs code review. M6-rpcapi 📣 RPC API. labels Apr 14, 2017
@tomusdrw tomusdrw changed the title Generic PubSub impleentation Generic PubSub implementation Apr 19, 2017
#[pubsub(name = "parity_subscription")] {
/// Subscribe to changes of any RPC method in Parity.
#[rpc(name = "parity_subscribe")]
fn parity_subscribe(&self, Self::Metadata, Subscriber<Value>, String, Params);
Copy link
Contributor

Choose a reason for hiding this comment

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

Shouldn't SubscriptionId be returned somewhere?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

The way it works is through Subscriber::assign_id method. Two reasons for that:

  1. You can do it asynchronously (that's a shitty argument, cause it could just return Future)
  2. Only after you assign ID you can start sending notification and it's enforced by the signature:
    fn assign_id(self, id: SubscriptionId) -> Sink<T>

Dropping Subscriber rejects the subscription as does Subscriber::reject(self, Reason) method.

return false;
}

true
Copy link
Contributor

Choose a reason for hiding this comment

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

self.session's value doesn't have to be equal?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Actually ParitalEq implementation is not needed at all. Thanks for spotting!

}

// impl cmp::PartialEq for Metadata {
// fn eq(&self, other: &Metadata) -> bool {
Copy link
Contributor

Choose a reason for hiding this comment

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

if it can be removed, better to remove it outright rather than comment it out

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Obviously, sorry!

let pm2 = poll_manager.clone();

let timer = tokio_timer::wheel()
.tick_duration(Duration::from_millis(500))
Copy link
Contributor

Choose a reason for hiding this comment

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

Any reason to set the tick duration to 500ms when the only timer spawned has a granularity of 1 second?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

In worst case it would cause 1 second delay before first poll is triggered, I thought that 500ms is a bit better tradeoff.

meta.session = None;

let mut poll_manager = self.poll_manager.write();
let (id, receiver) = poll_manager.subscribe(meta, method, params);
Copy link
Contributor

Choose a reason for hiding this comment

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

Any protection against subscribing to parity_subscribe?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

@rphmeier rphmeier added A8-looksgood 🦄 Pull request is reviewed well. and removed A0-pleasereview 🤓 Pull request needs code review. labels May 4, 2017
@rphmeier
Copy link
Contributor

rphmeier commented May 4, 2017

I have a couple questions about how we can improve pub-sub in future PRs:

  • Being able to subscribe to any method is great. But the periodic polling mechanism isn't optimal for certain subscriptions (new block, new logs, getWork) -- how can we generalize over methods which can be updated immediately upon certain external events and are only updated in that case?
  • Are there plans to add configurable polling times per subscription or at least overall?

@tomusdrw
Copy link
Collaborator Author

tomusdrw commented May 4, 2017

I've made a list of all RPC methods we support, and groupped them by possible cause of change:
https://gist.github.com/tomusdrw/5d727863c7eb90ce2b64dcea3fe0310d

We can later on optimize polling if following events are exposed by Parity:

  • New block (header)
  • Change in accounts (new/remove/setName/etc)
  • Sync events (peers, syncing, listening)
  • Pending Transactions (added/removed from the queue/pending block)

This will cover most of the cases, for the rest we can still rely on polling, maybe polling time could be configured depending on the methods, but I don't really want to expose polling timeout to RPC user.

To implement proper poll-on-event system we can start with a list of string method names, and later maybe allow some metadata in RPC method definition (like: #[rpc(name="parity_upgradeReady", meta="event:upgrade")])?

@gavofyork gavofyork merged commit 1617264 into master May 6, 2017
@gavofyork gavofyork deleted the pubsub2 branch May 6, 2017 11:24
@tomusdrw tomusdrw mentioned this pull request May 10, 2017
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
A8-looksgood 🦄 Pull request is reviewed well. M6-rpcapi 📣 RPC API.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants