Replace tokio_core with tokio (ring -> 0.13) (#9657)

* Replace `tokio_core` with `tokio`.

* Remove `tokio-core` and replace with `tokio` in

    - `ethcore/stratum`

    - `secret_store`

    - `util/fetch`

    - `util/reactor`

* Bump hyper to 0.12 in

    - `miner`

    - `util/fake-fetch`

    - `util/fetch`

    - `secret_store`

* Bump `jsonrpc-***` to 0.9 in

    - `parity`

    - `ethcore/stratum`

    - `ipfs`

    - `rpc`

    - `rpc_client`

    - `whisper`

* Bump `ring` to 0.13

* Use a more graceful shutdown process in `secret_store` tests.

* Convert some mutexes to rwlocks in `secret_store`.

* Consolidate Tokio Runtime use, remove `CpuPool`.

* Rename and move the `tokio_reactor` crate (`util/reactor`) to
  `tokio_runtime` (`util/runtime`).

* Rename `EventLoop` to `Runtime`.

    - Rename `EventLoop::spawn` to `Runtime::with_default_thread_count`.

    - Add the `Runtime::with_thread_count` method.

    - Rename `Remote` to `Executor`.

* Remove uses of `CpuPool` and spawn all tasks via the `Runtime` executor
  instead.

* Other changes related to `CpuPool` removal:

    - Remove `Reservations::with_pool`. `::new` now takes an `Executor` as an argument.

    - Remove `SenderReservations::with_pool`. `::new` now takes an `Executor` as an argument.
This commit is contained in:
Nick Sanders
2018-10-22 00:40:50 -07:00
committed by Afri Schoedon
parent b8da38f4e4
commit 68ca8df22f
75 changed files with 2027 additions and 1671 deletions

View File

@@ -42,13 +42,13 @@ impl<M, T> http::MetaExtractor<M> for MetaExtractor<T> where
T: HttpMetaExtractor<Metadata = M>,
M: jsonrpc_core::Metadata,
{
fn read_metadata(&self, req: &hyper::server::Request) -> M {
let as_string = |header: Option<&hyper::header::Raw>| header
.and_then(|raw| raw.one())
.map(|raw| String::from_utf8_lossy(raw).into_owned());
fn read_metadata(&self, req: &hyper::Request<hyper::Body>) -> M {
let as_string = |header: Option<&hyper::header::HeaderValue>| {
header.and_then(|val| val.to_str().ok().map(|s| s.to_owned()))
};
let origin = as_string(req.headers().get_raw("origin"));
let user_agent = as_string(req.headers().get_raw("user-agent"));
let origin = as_string(req.headers().get("origin"));
let user_agent = as_string(req.headers().get("user-agent"));
self.extractor.read_metadata(origin, user_agent)
}
}

View File

@@ -23,7 +23,6 @@ extern crate futures;
extern crate ansi_term;
extern crate cid;
extern crate futures_cpupool;
extern crate itertools;
extern crate multihash;
extern crate order_stat;
@@ -60,7 +59,7 @@ extern crate ethkey;
extern crate ethstore;
extern crate fetch;
extern crate keccak_hash as hash;
extern crate parity_reactor;
extern crate parity_runtime;
extern crate parity_updater as updater;
extern crate parity_version as version;
extern crate patricia_trie as trie;
@@ -124,7 +123,6 @@ pub use authcodes::{AuthCodes, TimeProvider};
pub use http_common::HttpMetaExtractor;
use std::net::SocketAddr;
use http::tokio_core;
/// RPC HTTP Server instance
pub type HttpServer = http::Server;
@@ -135,7 +133,6 @@ pub fn start_http<M, S, H, T>(
cors_domains: http::DomainsValidation<http::AccessControlAllowOrigin>,
allowed_hosts: http::DomainsValidation<http::Host>,
handler: H,
remote: tokio_core::reactor::Remote,
extractor: T,
threads: usize,
max_payload: usize,
@@ -148,7 +145,6 @@ pub fn start_http<M, S, H, T>(
let extractor = http_common::MetaExtractor::new(extractor);
Ok(http::ServerBuilder::with_meta_extractor(handler, extractor)
.threads(threads)
.event_loop_remote(remote)
.cors(cors_domains.into())
.allowed_hosts(allowed_hosts.into())
.max_request_body_size(max_payload * 1024 * 1024)
@@ -162,7 +158,6 @@ pub fn start_http_with_middleware<M, S, H, T, R>(
cors_domains: http::DomainsValidation<http::AccessControlAllowOrigin>,
allowed_hosts: http::DomainsValidation<http::Host>,
handler: H,
remote: tokio_core::reactor::Remote,
extractor: T,
middleware: R,
threads: usize,
@@ -177,7 +172,6 @@ pub fn start_http_with_middleware<M, S, H, T, R>(
let extractor = http_common::MetaExtractor::new(extractor);
Ok(http::ServerBuilder::with_meta_extractor(handler, extractor)
.threads(threads)
.event_loop_remote(remote)
.cors(cors_domains.into())
.allowed_hosts(allowed_hosts.into())
.max_request_body_size(max_payload * 1024 * 1024)
@@ -189,7 +183,6 @@ pub fn start_http_with_middleware<M, S, H, T, R>(
pub fn start_ipc<M, S, H, T>(
addr: &str,
handler: H,
remote: tokio_core::reactor::Remote,
extractor: T,
) -> ::std::io::Result<ipc::Server> where
M: jsonrpc_core::Metadata,
@@ -198,7 +191,6 @@ pub fn start_ipc<M, S, H, T>(
T: IpcMetaExtractor<M>,
{
ipc::ServerBuilder::with_meta_extractor(handler, extractor)
.event_loop_remote(remote)
.start(addr)
}
@@ -206,7 +198,6 @@ pub fn start_ipc<M, S, H, T>(
pub fn start_ws<M, S, H, T, U, V>(
addr: &SocketAddr,
handler: H,
remote: tokio_core::reactor::Remote,
allowed_origins: ws::DomainsValidation<ws::Origin>,
allowed_hosts: ws::DomainsValidation<ws::Host>,
max_connections: usize,
@@ -222,7 +213,6 @@ pub fn start_ws<M, S, H, T, U, V>(
V: ws::RequestMiddleware,
{
ws::ServerBuilder::with_meta_extractor(handler, extractor)
.event_loop_remote(remote)
.request_middleware(middleware)
.allowed_origins(allowed_origins)
.allowed_hosts(allowed_hosts)

View File

@@ -18,7 +18,7 @@ use std::ops::{Deref, DerefMut};
use std::path::PathBuf;
use tempdir::TempDir;
use parity_reactor::{EventLoop, TokioRemote};
use parity_runtime::{Runtime, TaskExecutor};
use authcodes::AuthCodes;
@@ -27,15 +27,15 @@ pub struct Server<T> {
/// Server
pub server: T,
/// RPC Event Loop
pub event_loop: EventLoop,
pub event_loop: Runtime,
}
impl<T> Server<T> {
pub fn new<F>(f: F) -> Server<T> where
F: FnOnce(TokioRemote) -> T,
F: FnOnce(TaskExecutor) -> T,
{
let event_loop = EventLoop::spawn();
let remote = event_loop.raw_remote();
let event_loop = Runtime::with_thread_count(1);
let remote = event_loop.raw_executor();
Server {
server: f(remote),

View File

@@ -26,14 +26,13 @@ fn serve(handler: Option<MetaIoHandler<Metadata>>) -> Server<HttpServer> {
let address = "127.0.0.1:0".parse().unwrap();
let handler = handler.unwrap_or_default();
Server::new(|remote| ::start_http_with_middleware(
Server::new(|_remote| ::start_http_with_middleware(
&address,
http::DomainsValidation::Disabled,
http::DomainsValidation::Disabled,
handler,
remote,
extractors::RpcExtractor,
|request: hyper::Request| {
|request: hyper::Request<hyper::Body>| {
http::RequestMiddlewareAction::Proceed {
should_continue_on_invalid_cors: false,
request,
@@ -50,7 +49,7 @@ fn request(server: Server<HttpServer>, request: &str) -> http_client::Response {
}
#[cfg(test)]
mod testsing {
mod tests {
use jsonrpc_core::{MetaIoHandler, Value};
use v1::Metadata;
use super::{request, Server};
@@ -73,7 +72,7 @@ mod testsing {
// when
let req = r#"{"method":"hello","params":[],"jsonrpc":"2.0","id":1}"#;
let expected = "4B\n{\"jsonrpc\":\"2.0\",\"result\":\"unknown origin / unknown agent via RPC\",\"id\":1}\n\n0\n\n";
let expected = "{\"jsonrpc\":\"2.0\",\"result\":\"unknown origin / unknown agent via RPC\",\"id\":1}\n";
let res = request(server,
&format!("\
POST / HTTP/1.1\r\n\
@@ -98,7 +97,7 @@ mod testsing {
// when
let req = r#"{"method":"hello","params":[],"jsonrpc":"2.0","id":1}"#;
let expected = "49\n{\"jsonrpc\":\"2.0\",\"result\":\"unknown origin / curl/7.16.3 via RPC\",\"id\":1}\n\n0\n\n";
let expected = "{\"jsonrpc\":\"2.0\",\"result\":\"unknown origin / curl/7.16.3 via RPC\",\"id\":1}\n";
let res = request(server,
&format!("\
POST / HTTP/1.1\r\n\

View File

@@ -34,10 +34,9 @@ pub fn serve() -> (Server<ws::Server>, usize, GuardedAuthCodes) {
let authcodes = GuardedAuthCodes::new();
let stats = Arc::new(informant::RpcStats::default());
let res = Server::new(|remote| ::start_ws(
let res = Server::new(|_| ::start_ws(
&address,
io,
remote,
ws::DomainsValidation::Disabled,
ws::DomainsValidation::Disabled,
5,

View File

@@ -23,6 +23,7 @@ use authcodes;
use http_common::HttpMetaExtractor;
use ipc;
use jsonrpc_core as core;
use jsonrpc_core::futures::future::Either;
use jsonrpc_pubsub::Session;
use ws;
use ethereum_types::H256;
@@ -216,26 +217,26 @@ impl<M: core::Middleware<Metadata>> WsDispatcher<M> {
}
impl<M: core::Middleware<Metadata>> core::Middleware<Metadata> for WsDispatcher<M> {
type Future = core::futures::future::Either<
M::Future,
type Future = Either<
core::FutureRpcResult<M::Future>,
core::FutureResponse,
>;
fn on_request<F, X>(&self, request: core::Request, meta: Metadata, process: F) -> Self::Future where
fn on_request<F, X>(&self, request: core::Request, meta: Metadata, process: F)
-> Either<Self::Future, X>
where
F: FnOnce(core::Request, Metadata) -> X,
X: core::futures::Future<Item=Option<core::Response>, Error=()> + Send + 'static,
{
use self::core::futures::future::Either::{A, B};
let use_full = match &meta.origin {
&Origin::Signer { .. } => true,
_ => false,
};
if use_full {
A(self.full_handler.handle_rpc_request(request, meta))
Either::A(Either::A(self.full_handler.handle_rpc_request(request, meta)))
} else {
B(Box::new(process(request, meta)))
Either::B(process(request, meta))
}
}
}

View File

@@ -23,31 +23,25 @@ use ethereum_types::{U256, Address};
use futures::{Future, future, Poll, Async};
use futures::future::Either;
use futures::sync::oneshot;
use futures_cpupool::CpuPool;
use parity_runtime::Executor;
/// Manages currently reserved and prospective nonces
/// for multiple senders.
#[derive(Debug)]
pub struct Reservations {
nonces: HashMap<Address, SenderReservations>,
pool: CpuPool,
executor: Executor,
}
impl Reservations {
/// A maximal number of reserved nonces in the hashmap
/// before we start clearing the unused ones.
const CLEAN_AT: usize = 512;
/// Create new nonces manager and spawn a single-threaded cpu pool
/// for progressing execution of dropped nonces.
pub fn new() -> Self {
Self::with_pool(CpuPool::new(1))
}
/// Create new nonces manager with given cpupool.
pub fn with_pool(pool: CpuPool) -> Self {
/// Create new nonces manager with given executor.
pub fn new(executor: Executor) -> Self {
Reservations {
nonces: Default::default(),
pool,
executor,
}
}
@@ -59,9 +53,9 @@ impl Reservations {
self.nonces.retain(|_, v| !v.is_empty());
}
let pool = &self.pool;
let executor = &self.executor;
self.nonces.entry(sender)
.or_insert_with(move || SenderReservations::with_pool(pool.clone()))
.or_insert_with(move || SenderReservations::new(executor.clone()))
.reserve_nonce(minimal)
}
}
@@ -71,25 +65,18 @@ impl Reservations {
pub struct SenderReservations {
previous: Option<oneshot::Receiver<U256>>,
previous_ready: Arc<AtomicBool>,
pool: CpuPool,
executor: Executor,
prospective_value: U256,
dropped: Arc<AtomicUsize>,
}
impl SenderReservations {
/// Create new nonces manager and spawn a single-threaded cpu pool
/// for progressing execution of dropped nonces.
#[cfg(test)]
pub fn new() -> Self {
Self::with_pool(CpuPool::new(1))
}
/// Create new nonces manager with given cpu pool.
pub fn with_pool(pool: CpuPool) -> Self {
/// Create new nonces manager with given executor.
pub fn new(executor: Executor) -> Self {
SenderReservations {
previous: None,
previous_ready: Arc::new(AtomicBool::new(true)),
pool,
executor,
prospective_value: Default::default(),
dropped: Default::default(),
}
@@ -110,7 +97,7 @@ impl SenderReservations {
let (next, rx) = oneshot::channel();
let next = Some(next);
let next_sent = Arc::new(AtomicBool::default());
let pool = self.pool.clone();
let executor = self.executor.clone();
let dropped = self.dropped.clone();
self.previous_ready = next_sent.clone();
match mem::replace(&mut self.previous, Some(rx)) {
@@ -120,7 +107,7 @@ impl SenderReservations {
next_sent,
minimal,
prospective_value,
pool,
executor,
dropped,
},
None => Reserved {
@@ -129,7 +116,7 @@ impl SenderReservations {
next_sent,
minimal,
prospective_value,
pool,
executor,
dropped,
},
}
@@ -152,7 +139,7 @@ pub struct Reserved {
next_sent: Arc<AtomicBool>,
minimal: U256,
prospective_value: U256,
pool: CpuPool,
executor: Executor,
dropped: Arc<AtomicUsize>,
}
@@ -196,10 +183,14 @@ impl Drop for Reserved {
self.dropped.fetch_add(1, atomic::Ordering::SeqCst);
// If Reserved is dropped just pipe previous and next together.
let previous = mem::replace(&mut self.previous, Either::B(future::ok(U256::default())));
self.pool.spawn(previous.map(move |nonce| {
next_sent.store(true, atomic::Ordering::SeqCst);
next.send(nonce).expect(Ready::RECV_PROOF)
})).forget()
self.executor.spawn(
previous
.map(move |nonce| {
next_sent.store(true, atomic::Ordering::SeqCst);
next.send(nonce).expect(Ready::RECV_PROOF)
})
.map_err(|err| error!("Error dropping `Reserved`: {:?}", err))
);
}
}
}
@@ -253,10 +244,12 @@ impl Drop for Ready {
#[cfg(test)]
mod tests {
use super::*;
use parity_runtime::Runtime;
#[test]
fn should_reserve_a_set_of_nonces_and_resolve_them() {
let mut nonces = SenderReservations::new();
let runtime = Runtime::with_thread_count(1);
let mut nonces = SenderReservations::new(runtime.executor());
assert!(nonces.is_empty());
let n1 = nonces.reserve_nonce(5.into());
@@ -303,7 +296,8 @@ mod tests {
#[test]
fn should_return_prospective_nonce() {
let mut nonces = SenderReservations::new();
let runtime = Runtime::with_thread_count(1);
let mut nonces = SenderReservations::new(runtime.executor());
let n1 = nonces.reserve_nonce(5.into());
let n2 = nonces.reserve_nonce(5.into());

View File

@@ -95,7 +95,7 @@ impl<S: core::Middleware<Metadata>> GenericPollManager<S> {
jsonrpc: Some(core::Version::V2),
id: core::Id::Str(id.as_string()),
method: subscription.method.clone(),
params: Some(subscription.params.clone()),
params: subscription.params.clone(),
};
trace!(target: "pubsub", "Polling method: {:?}", call);
let result = self.rpc.handle_call(call.into(), subscription.metadata.clone());
@@ -141,7 +141,7 @@ mod tests {
use jsonrpc_core::{MetaIoHandler, NoopMiddleware, Value, Params};
use jsonrpc_core::futures::{Future, Stream};
use jsonrpc_pubsub::SubscriptionId;
use http::tokio_core::reactor;
use http::tokio::runtime::Runtime;
use super::GenericPollManager;
@@ -162,25 +162,25 @@ mod tests {
#[test]
fn should_poll_subscribed_method() {
// given
let mut el = reactor::Core::new().unwrap();
let mut el = Runtime::new().unwrap();
let mut poll_manager = poll_manager();
let (id, rx) = poll_manager.subscribe(Default::default(), "hello".into(), Params::None);
assert_eq!(id, SubscriptionId::String("0x416d77337e24399d".into()));
// then
poll_manager.tick().wait().unwrap();
let (res, rx) = el.run(rx.into_future()).unwrap();
let (res, rx) = el.block_on(rx.into_future()).unwrap();
assert_eq!(res, Some(Ok(Value::String("hello".into()))));
// retrieve second item
poll_manager.tick().wait().unwrap();
let (res, rx) = el.run(rx.into_future()).unwrap();
let (res, rx) = el.block_on(rx.into_future()).unwrap();
assert_eq!(res, Some(Ok(Value::String("world".into()))));
// and no more notifications
poll_manager.tick().wait().unwrap();
// we need to unsubscribe otherwise the future will never finish.
poll_manager.unsubscribe(&id);
assert_eq!(el.run(rx.into_future()).unwrap().0, None);
assert_eq!(el.block_on(rx.into_future()).unwrap().0, None);
}
}

View File

@@ -39,7 +39,7 @@ use sync::LightSync;
use light::cache::Cache;
use light::on_demand::OnDemand;
use light::client::{LightChainClient, LightChainNotify};
use parity_reactor::Remote;
use parity_runtime::Executor;
use ethereum_types::H256;
use bytes::Bytes;
use parking_lot::{RwLock, Mutex};
@@ -56,7 +56,7 @@ pub struct EthPubSubClient<C> {
impl<C> EthPubSubClient<C> {
/// Creates new `EthPubSubClient`.
pub fn new(client: Arc<C>, remote: Remote) -> Self {
pub fn new(client: Arc<C>, executor: Executor) -> Self {
let heads_subscribers = Arc::new(RwLock::new(Subscribers::default()));
let logs_subscribers = Arc::new(RwLock::new(Subscribers::default()));
let transactions_subscribers = Arc::new(RwLock::new(Subscribers::default()));
@@ -64,7 +64,7 @@ impl<C> EthPubSubClient<C> {
EthPubSubClient {
handler: Arc::new(ChainNotificationHandler {
client,
remote,
executor,
heads_subscribers: heads_subscribers.clone(),
logs_subscribers: logs_subscribers.clone(),
transactions_subscribers: transactions_subscribers.clone(),
@@ -77,8 +77,8 @@ impl<C> EthPubSubClient<C> {
/// Creates new `EthPubSubCient` with deterministic subscription ids.
#[cfg(test)]
pub fn new_test(client: Arc<C>, remote: Remote) -> Self {
let client = Self::new(client, remote);
pub fn new_test(client: Arc<C>, executor: Executor) -> Self {
let client = Self::new(client, executor);
*client.heads_subscribers.write() = Subscribers::new_test();
*client.logs_subscribers.write() = Subscribers::new_test();
*client.transactions_subscribers.write() = Subscribers::new_test();
@@ -98,7 +98,7 @@ impl EthPubSubClient<LightFetch> {
on_demand: Arc<OnDemand>,
sync: Arc<LightSync>,
cache: Arc<Mutex<Cache>>,
remote: Remote,
executor: Executor,
gas_price_percentile: usize,
) -> Self {
let fetch = LightFetch {
@@ -108,22 +108,22 @@ impl EthPubSubClient<LightFetch> {
cache,
gas_price_percentile,
};
EthPubSubClient::new(Arc::new(fetch), remote)
EthPubSubClient::new(Arc::new(fetch), executor)
}
}
/// PubSub Notification handler.
pub struct ChainNotificationHandler<C> {
client: Arc<C>,
remote: Remote,
executor: Executor,
heads_subscribers: Arc<RwLock<Subscribers<Client>>>,
logs_subscribers: Arc<RwLock<Subscribers<(Client, EthFilter)>>>,
transactions_subscribers: Arc<RwLock<Subscribers<Client>>>,
}
impl<C> ChainNotificationHandler<C> {
fn notify(remote: &Remote, subscriber: &Client, result: pubsub::Result) {
remote.spawn(subscriber
fn notify(executor: &Executor, subscriber: &Client, result: pubsub::Result) {
executor.spawn(subscriber
.notify(Ok(result))
.map(|_| ())
.map_err(|e| warn!(target: "rpc", "Unable to send notification: {}", e))
@@ -133,7 +133,7 @@ impl<C> ChainNotificationHandler<C> {
fn notify_heads(&self, headers: &[(encoded::Header, BTreeMap<String, String>)]) {
for subscriber in self.heads_subscribers.read().values() {
for &(ref header, ref extra_info) in headers {
Self::notify(&self.remote, subscriber, pubsub::Result::Header(RichHeader {
Self::notify(&self.executor, subscriber, pubsub::Result::Header(RichHeader {
inner: header.into(),
extra_info: extra_info.clone(),
}));
@@ -159,14 +159,14 @@ impl<C> ChainNotificationHandler<C> {
.collect::<Vec<_>>()
);
let limit = filter.limit;
let remote = self.remote.clone();
let executor = self.executor.clone();
let subscriber = subscriber.clone();
self.remote.spawn(logs
self.executor.spawn(logs
.map(move |logs| {
let logs = logs.into_iter().flat_map(|log| log).collect();
for log in limit_logs(logs, limit) {
Self::notify(&remote, &subscriber, pubsub::Result::Log(log))
Self::notify(&executor, &subscriber, pubsub::Result::Log(log))
}
})
.map_err(|e| warn!("Unable to fetch latest logs: {:?}", e))
@@ -178,7 +178,7 @@ impl<C> ChainNotificationHandler<C> {
pub fn notify_new_transactions(&self, hashes: &[H256]) {
for subscriber in self.transactions_subscribers.read().values() {
for hash in hashes {
Self::notify(&self.remote, subscriber, pubsub::Result::TransactionHash((*hash).into()));
Self::notify(&self.executor, subscriber, pubsub::Result::TransactionHash((*hash).into()));
}
}
}

View File

@@ -22,7 +22,6 @@ use std::sync::Arc;
use sync::ManageNetwork;
use fetch::{self, Fetch};
use futures_cpupool::CpuPool;
use hash::keccak_buffer;
use jsonrpc_core::{Result, BoxFuture};
@@ -35,16 +34,14 @@ use v1::types::{Bytes, H160, H256, U256, ReleaseInfo, Transaction};
pub struct ParitySetClient<F> {
net: Arc<ManageNetwork>,
fetch: F,
pool: CpuPool,
}
impl<F: Fetch> ParitySetClient<F> {
/// Creates new `ParitySetClient` with given `Fetch`.
pub fn new(net: Arc<ManageNetwork>, fetch: F, p: CpuPool) -> Self {
pub fn new(net: Arc<ManageNetwork>, fetch: F) -> Self {
ParitySetClient {
net: net,
fetch: fetch,
pool: p,
}
}
}
@@ -134,7 +131,7 @@ impl<F: Fetch> ParitySet for ParitySetClient<F> {
})
.map(Into::into)
});
Box::new(self.pool.spawn(future))
Box::new(future)
}
fn upgrade_ready(&self) -> Result<Option<ReleaseInfo>> {

View File

@@ -23,7 +23,6 @@ use ethcore::client::{BlockChainClient, Mode};
use ethcore::miner::MinerService;
use sync::ManageNetwork;
use fetch::{self, Fetch};
use futures_cpupool::CpuPool;
use hash::keccak_buffer;
use updater::{Service as UpdateService};
@@ -40,7 +39,6 @@ pub struct ParitySetClient<C, M, U, F = fetch::Client> {
updater: Arc<U>,
net: Arc<ManageNetwork>,
fetch: F,
pool: CpuPool,
}
impl<C, M, U, F> ParitySetClient<C, M, U, F>
@@ -53,7 +51,6 @@ impl<C, M, U, F> ParitySetClient<C, M, U, F>
updater: &Arc<U>,
net: &Arc<ManageNetwork>,
fetch: F,
pool: CpuPool,
) -> Self {
ParitySetClient {
client: client.clone(),
@@ -61,7 +58,6 @@ impl<C, M, U, F> ParitySetClient<C, M, U, F>
updater: updater.clone(),
net: net.clone(),
fetch: fetch,
pool: pool,
}
}
}
@@ -177,7 +173,7 @@ impl<C, M, U, F> ParitySet for ParitySetClient<C, M, U, F> where
})
.map(Into::into)
});
Box::new(self.pool.spawn(future))
Box::new(future)
}
fn upgrade_ready(&self) -> Result<Option<ReleaseInfo>> {

View File

@@ -27,7 +27,7 @@ use jsonrpc_macros::pubsub::Subscriber;
use jsonrpc_pubsub::SubscriptionId;
use tokio_timer;
use parity_reactor::Remote;
use parity_runtime::Executor;
use v1::helpers::GenericPollManager;
use v1::metadata::Metadata;
use v1::traits::PubSub;
@@ -35,12 +35,12 @@ use v1::traits::PubSub;
/// Parity PubSub implementation.
pub struct PubSubClient<S: core::Middleware<Metadata>> {
poll_manager: Arc<RwLock<GenericPollManager<S>>>,
remote: Remote,
executor: Executor,
}
impl<S: core::Middleware<Metadata>> PubSubClient<S> {
/// Creates new `PubSubClient`.
pub fn new(rpc: MetaIoHandler<Metadata, S>, remote: Remote) -> Self {
pub fn new(rpc: MetaIoHandler<Metadata, S>, executor: Executor) -> Self {
let poll_manager = Arc::new(RwLock::new(GenericPollManager::new(rpc)));
let pm2 = poll_manager.clone();
@@ -50,14 +50,14 @@ impl<S: core::Middleware<Metadata>> PubSubClient<S> {
// Start ticking
let interval = timer.interval(Duration::from_millis(1000));
remote.spawn(interval
executor.spawn(interval
.map_err(|e| warn!("Polling timer error: {:?}", e))
.for_each(move |_| pm2.read().tick())
);
PubSubClient {
poll_manager,
remote,
executor,
}
}
}
@@ -65,8 +65,8 @@ impl<S: core::Middleware<Metadata>> PubSubClient<S> {
impl PubSubClient<core::NoopMiddleware> {
/// Creates new `PubSubClient` with deterministic ids.
#[cfg(test)]
pub fn new_test(rpc: MetaIoHandler<Metadata, core::NoopMiddleware>, remote: Remote) -> Self {
let client = Self::new(MetaIoHandler::with_middleware(Default::default()), remote);
pub fn new_test(rpc: MetaIoHandler<Metadata, core::NoopMiddleware>, executor: Executor) -> Self {
let client = Self::new(MetaIoHandler::with_middleware(Default::default()), executor);
*client.poll_manager.write() = GenericPollManager::new_test(rpc);
client
}
@@ -84,7 +84,7 @@ impl<S: core::Middleware<Metadata>> PubSub for PubSubClient<S> {
let (id, receiver) = poll_manager.subscribe(meta, method, params);
match subscriber.assign_id(id.clone()) {
Ok(sink) => {
self.remote.spawn(receiver.forward(sink.sink_map_err(|e| {
self.executor.spawn(receiver.forward(sink.sink_map_err(|e| {
warn!("Cannot send notification: {:?}", e);
})).map(|_| ()));
},

View File

@@ -20,7 +20,7 @@ use std::sync::Arc;
use ethcore::account_provider::AccountProvider;
use ethkey;
use parity_reactor::Remote;
use parity_runtime::Executor;
use parking_lot::Mutex;
use rlp::Rlp;
use transaction::{SignedTransaction, PendingTransaction};
@@ -50,7 +50,7 @@ impl<D: Dispatcher + 'static> SignerClient<D> {
store: &Arc<AccountProvider>,
dispatcher: D,
signer: &Arc<SignerService>,
remote: Remote,
executor: Executor,
) -> Self {
let subscribers = Arc::new(Mutex::new(Subscribers::default()));
let subs = Arc::downgrade(&subscribers);
@@ -60,7 +60,7 @@ impl<D: Dispatcher + 'static> SignerClient<D> {
let requests = s.requests().into_iter().map(Into::into).collect::<Vec<ConfirmationRequest>>();
for subscription in subs.lock().values() {
let subscription: &Sink<_> = subscription;
remote.spawn(subscription
executor.spawn(subscription
.notify(Ok(requests.clone()))
.map(|_| ())
.map_err(|e| warn!(target: "rpc", "Unable to send notification: {}", e))

View File

@@ -44,7 +44,7 @@ use v1::types::{
Origin,
};
use parity_reactor::Remote;
use parity_runtime::Executor;
/// After 60s entries that are not queried with `check_request` will get garbage collected.
const MAX_PENDING_DURATION_SEC: u32 = 60;
@@ -67,7 +67,7 @@ impl Future for DispatchResult {
}
}
fn schedule(remote: Remote,
fn schedule(executor: Executor,
confirmations: Arc<Mutex<TransientHashMap<U256, Option<RpcConfirmationResult>>>>,
id: U256,
future: RpcConfirmationReceiver) {
@@ -83,7 +83,7 @@ fn schedule(remote: Remote,
confirmations.insert(id, Some(result));
Ok(())
});
remote.spawn(future);
executor.spawn(future);
}
/// Implementation of functions that require signing when no trusted signer is used.
@@ -91,19 +91,19 @@ pub struct SigningQueueClient<D> {
signer: Arc<SignerService>,
accounts: Arc<AccountProvider>,
dispatcher: D,
remote: Remote,
executor: Executor,
// None here means that the request hasn't yet been confirmed
confirmations: Arc<Mutex<TransientHashMap<U256, Option<RpcConfirmationResult>>>>,
}
impl<D: Dispatcher + 'static> SigningQueueClient<D> {
/// Creates a new signing queue client given shared signing queue.
pub fn new(signer: &Arc<SignerService>, dispatcher: D, remote: Remote, accounts: &Arc<AccountProvider>) -> Self {
pub fn new(signer: &Arc<SignerService>, dispatcher: D, executor: Executor, accounts: &Arc<AccountProvider>) -> Self {
SigningQueueClient {
signer: signer.clone(),
accounts: accounts.clone(),
dispatcher,
remote,
executor,
confirmations: Arc::new(Mutex::new(TransientHashMap::new(MAX_PENDING_DURATION_SEC))),
}
}
@@ -143,7 +143,7 @@ impl<D: Dispatcher + 'static> ParitySigning for SigningQueueClient<D> {
}
fn post_sign(&self, meta: Metadata, address: RpcH160, data: RpcBytes) -> BoxFuture<RpcEither<RpcU256, RpcConfirmationResponse>> {
let remote = self.remote.clone();
let executor = self.executor.clone();
let confirmations = self.confirmations.clone();
Box::new(self.dispatch(
@@ -153,21 +153,21 @@ impl<D: Dispatcher + 'static> ParitySigning for SigningQueueClient<D> {
).map(move |result| match result {
DispatchResult::Value(v) => RpcEither::Or(v),
DispatchResult::Future(id, future) => {
schedule(remote, confirmations, id, future);
schedule(executor, confirmations, id, future);
RpcEither::Either(id.into())
},
}))
}
fn post_transaction(&self, meta: Metadata, request: RpcTransactionRequest) -> BoxFuture<RpcEither<RpcU256, RpcConfirmationResponse>> {
let remote = self.remote.clone();
let executor = self.executor.clone();
let confirmations = self.confirmations.clone();
Box::new(self.dispatch(RpcConfirmationPayload::SendTransaction(request), DefaultAccount::Provided(self.accounts.default_account().ok().unwrap_or_default()), meta.origin)
.map(|result| match result {
DispatchResult::Value(v) => RpcEither::Or(v),
DispatchResult::Future(id, future) => {
schedule(remote, confirmations, id, future);
schedule(executor, confirmations, id, future);
RpcEither::Either(id.into())
},
}))

View File

@@ -20,12 +20,13 @@ use std::fmt;
use std::sync::Arc;
use std::sync::atomic::{self, AtomicUsize};
use std::time;
use futures_cpupool as pool;
use jsonrpc_core as rpc;
use parity_runtime;
use jsonrpc_core as core;
use jsonrpc_core::futures::future::Either;
use order_stat;
use parking_lot::RwLock;
pub use self::pool::CpuPool;
pub use self::parity_runtime::Executor;
const RATE_SECONDS: usize = 10;
const STATS_SAMPLES: usize = 60;
@@ -186,16 +187,14 @@ pub trait ActivityNotifier: Send + Sync + 'static {
pub struct Middleware<T: ActivityNotifier = ClientNotifier> {
stats: Arc<RpcStats>,
notifier: T,
pool: Option<CpuPool>,
}
impl<T: ActivityNotifier> Middleware<T> {
/// Create new Middleware with stats counter and activity notifier.
pub fn new(stats: Arc<RpcStats>, notifier: T, pool: Option<CpuPool>) -> Self {
pub fn new(stats: Arc<RpcStats>, notifier: T) -> Self {
Middleware {
stats,
notifier,
pool,
}
}
@@ -204,28 +203,24 @@ impl<T: ActivityNotifier> Middleware<T> {
}
}
impl<M: rpc::Metadata, T: ActivityNotifier> rpc::Middleware<M> for Middleware<T> {
type Future = rpc::futures::future::Either<
pool::CpuFuture<Option<rpc::Response>, ()>,
rpc::FutureResponse,
>;
impl<M: core::Metadata, T: ActivityNotifier> core::Middleware<M> for Middleware<T> {
type Future = core::FutureResponse;
fn on_request<F, X>(&self, request: rpc::Request, meta: M, process: F) -> Self::Future where
F: FnOnce(rpc::Request, M) -> X,
X: rpc::futures::Future<Item=Option<rpc::Response>, Error=()> + Send + 'static,
fn on_request<F, X>(&self, request: core::Request, meta: M, process: F) -> Either<Self::Future, X> where
F: FnOnce(core::Request, M) -> X,
X: core::futures::Future<Item=Option<core::Response>, Error=()> + Send + 'static,
{
use self::rpc::futures::future::Either::{A, B};
let start = time::Instant::now();
self.notifier.active();
self.stats.count_request();
let id = match request {
rpc::Request::Single(rpc::Call::MethodCall(ref call)) => Some(call.id.clone()),
core::Request::Single(core::Call::MethodCall(ref call)) => Some(call.id.clone()),
_ => None,
};
let stats = self.stats.clone();
let future = process(request, meta).map(move |res| {
let time = Self::as_micro(start.elapsed());
if time > 10_000 {
@@ -235,10 +230,7 @@ impl<M: rpc::Metadata, T: ActivityNotifier> rpc::Middleware<M> for Middleware<T>
res
});
match self.pool {
Some(ref pool) => A(pool.spawn(future)),
None => B(Box::new(future)),
}
Either::A(Box::new(future))
}
}

View File

@@ -32,6 +32,7 @@ use ethjson::spec::ForkSpec;
use io::IoChannel;
use miner::external::ExternalMiner;
use parking_lot::Mutex;
use parity_runtime::Runtime;
use jsonrpc_core::IoHandler;
use v1::helpers::dispatch::FullDispatcher;
@@ -73,6 +74,7 @@ fn make_spec(chain: &BlockChain) -> Spec {
}
struct EthTester {
_runtime: Runtime,
client: Arc<Client>,
_miner: Arc<Miner>,
_snapshot: Arc<TestSnapshotService>,
@@ -99,6 +101,7 @@ impl EthTester {
}
fn from_spec(spec: Spec) -> Self {
let runtime = Runtime::with_thread_count(1);
let account_provider = account_provider();
let opt_account_provider = account_provider.clone();
let miner_service = miner_service(&spec, account_provider.clone());
@@ -124,7 +127,7 @@ impl EthTester {
Default::default(),
);
let reservations = Arc::new(Mutex::new(nonce::Reservations::new()));
let reservations = Arc::new(Mutex::new(nonce::Reservations::new(runtime.executor())));
let dispatcher = FullDispatcher::new(client.clone(), miner_service.clone(), reservations, 50);
let eth_sign = SigningUnsafeClient::new(
@@ -137,6 +140,7 @@ impl EthTester {
handler.extend_with(eth_sign.to_delegate());
EthTester {
_runtime: runtime,
_miner: miner_service,
_snapshot: snapshot_service,
client: client,

View File

@@ -32,6 +32,7 @@ use miner::external::ExternalMiner;
use rlp;
use rustc_hex::{FromHex, ToHex};
use transaction::{Transaction, Action};
use parity_runtime::Runtime;
use jsonrpc_core::IoHandler;
use v1::{Eth, EthClient, EthClientOptions, EthFilter, EthFilterClient, EthSigning, SigningUnsafeClient};
@@ -65,6 +66,7 @@ fn snapshot_service() -> Arc<TestSnapshotService> {
}
struct EthTester {
pub runtime: Runtime,
pub client: Arc<TestBlockChainClient>,
pub sync: Arc<TestSyncProvider>,
pub accounts_provider: Arc<AccountProvider>,
@@ -82,6 +84,7 @@ impl Default for EthTester {
impl EthTester {
pub fn new_with_options(options: EthClientOptions) -> Self {
let runtime = Runtime::with_thread_count(1);
let client = blockchain_client();
let sync = sync_provider();
let ap = accounts_provider();
@@ -94,7 +97,7 @@ impl EthTester {
let poll_lifetime = options.poll_lifetime;
let eth = EthClient::new(&client, &snapshot, &sync, &opt_ap, &miner, &external_miner, options).to_delegate();
let filter = EthFilterClient::new(client.clone(), miner.clone(), poll_lifetime).to_delegate();
let reservations = Arc::new(Mutex::new(nonce::Reservations::new()));
let reservations = Arc::new(Mutex::new(nonce::Reservations::new(runtime.executor())));
let dispatcher = FullDispatcher::new(client.clone(), miner.clone(), reservations, gas_price_percentile);
let sign = SigningUnsafeClient::new(&opt_ap, dispatcher).to_delegate();
@@ -104,6 +107,7 @@ impl EthTester {
io.extend_with(filter);
EthTester {
runtime,
client: client,
sync: sync,
accounts_provider: ap,

View File

@@ -25,14 +25,14 @@ use std::time::Duration;
use v1::{EthPubSub, EthPubSubClient, Metadata};
use ethcore::client::{TestBlockChainClient, EachBlockWith, ChainNotify, ChainRoute, ChainRouteType};
use parity_reactor::EventLoop;
use parity_runtime::Runtime;
const DURATION_ZERO: Duration = Duration::from_millis(0);
#[test]
fn should_subscribe_to_new_heads() {
// given
let el = EventLoop::spawn();
let el = Runtime::with_thread_count(1);
let mut client = TestBlockChainClient::new();
// Insert some blocks
client.add_blocks(3, EachBlockWith::Nothing);
@@ -40,7 +40,7 @@ fn should_subscribe_to_new_heads() {
let h2 = client.block_hash_delta_minus(2);
let h1 = client.block_hash_delta_minus(3);
let pubsub = EthPubSubClient::new_test(Arc::new(client), el.remote());
let pubsub = EthPubSubClient::new_test(Arc::new(client), el.executor());
let handler = pubsub.handler().upgrade().unwrap();
let pubsub = pubsub.to_delegate();
@@ -89,7 +89,7 @@ fn should_subscribe_to_logs() {
use ethcore::client::BlockInfo;
// given
let el = EventLoop::spawn();
let el = Runtime::with_thread_count(1);
let mut client = TestBlockChainClient::new();
// Insert some blocks
client.add_blocks(1, EachBlockWith::Transaction);
@@ -112,7 +112,7 @@ fn should_subscribe_to_logs() {
}
]);
let pubsub = EthPubSubClient::new_test(Arc::new(client), el.remote());
let pubsub = EthPubSubClient::new_test(Arc::new(client), el.executor());
let handler = pubsub.handler().upgrade().unwrap();
let pubsub = pubsub.to_delegate();
@@ -156,10 +156,10 @@ fn should_subscribe_to_logs() {
#[test]
fn should_subscribe_to_pending_transactions() {
// given
let el = EventLoop::spawn();
let el = Runtime::with_thread_count(1);
let client = TestBlockChainClient::new();
let pubsub = EthPubSubClient::new_test(Arc::new(client), el.remote());
let pubsub = EthPubSubClient::new_test(Arc::new(client), el.executor());
let handler = pubsub.handler().upgrade().unwrap();
let pubsub = pubsub.to_delegate();
@@ -203,9 +203,9 @@ fn should_subscribe_to_pending_transactions() {
#[test]
fn should_return_unimplemented() {
// given
let el = EventLoop::spawn();
let el = Runtime::with_thread_count(1);
let client = TestBlockChainClient::new();
let pubsub = EthPubSubClient::new_test(Arc::new(client), el.remote());
let pubsub = EthPubSubClient::new_test(Arc::new(client), el.executor());
let pubsub = pubsub.to_delegate();
let mut io = MetaIoHandler::default();

View File

@@ -22,7 +22,6 @@ use ethereum_types::{U256, Address};
use ethcore::miner::MinerService;
use ethcore::client::TestBlockChainClient;
use sync::ManageNetwork;
use futures_cpupool::CpuPool;
use jsonrpc_core::IoHandler;
use v1::{ParitySet, ParitySetClient};
@@ -55,8 +54,7 @@ fn parity_set_client(
updater: &Arc<TestUpdater>,
net: &Arc<TestManageNetwork>,
) -> TestParitySetClient {
let pool = CpuPool::new(1);
ParitySetClient::new(client, miner, updater, &(net.clone() as Arc<ManageNetwork>), FakeFetch::new(Some(1)), pool)
ParitySetClient::new(client, miner, updater, &(net.clone() as Arc<ManageNetwork>), FakeFetch::new(Some(1)))
}
#[test]

View File

@@ -24,6 +24,7 @@ use ethcore::client::TestBlockChainClient;
use jsonrpc_core::IoHandler;
use parking_lot::Mutex;
use transaction::{Action, Transaction};
use parity_runtime::Runtime;
use v1::{PersonalClient, Personal, Metadata};
use v1::helpers::nonce;
@@ -32,6 +33,7 @@ use v1::tests::helpers::TestMinerService;
use v1::types::H520;
struct PersonalTester {
_runtime: Runtime,
accounts: Arc<AccountProvider>,
io: IoHandler<Metadata>,
miner: Arc<TestMinerService>,
@@ -51,10 +53,11 @@ fn miner_service() -> Arc<TestMinerService> {
}
fn setup() -> PersonalTester {
let runtime = Runtime::with_thread_count(1);
let accounts = accounts_provider();
let client = blockchain_client();
let miner = miner_service();
let reservations = Arc::new(Mutex::new(nonce::Reservations::new()));
let reservations = Arc::new(Mutex::new(nonce::Reservations::new(runtime.executor())));
let dispatcher = FullDispatcher::new(client, miner.clone(), reservations, 50);
let personal = PersonalClient::new(&accounts, dispatcher, false);
@@ -63,6 +66,7 @@ fn setup() -> PersonalTester {
io.extend_with(personal.to_delegate());
let tester = PersonalTester {
_runtime: runtime,
accounts: accounts,
io: io,
miner: miner,

View File

@@ -20,7 +20,7 @@ use jsonrpc_core::{self as core, MetaIoHandler};
use jsonrpc_core::futures::{self, Stream, Future};
use jsonrpc_pubsub::Session;
use parity_reactor::EventLoop;
use parity_runtime::Runtime;
use v1::{PubSub, PubSubClient, Metadata};
fn rpc() -> MetaIoHandler<Metadata, core::NoopMiddleware> {
@@ -40,9 +40,9 @@ fn rpc() -> MetaIoHandler<Metadata, core::NoopMiddleware> {
#[test]
fn should_subscribe_to_a_method() {
// given
let el = EventLoop::spawn();
let el = Runtime::with_thread_count(1);
let rpc = rpc();
let pubsub = PubSubClient::new_test(rpc, el.remote()).to_delegate();
let pubsub = PubSubClient::new_test(rpc, el.executor()).to_delegate();
let mut io = MetaIoHandler::default();
io.extend_with(pubsub);

View File

@@ -21,7 +21,7 @@ use bytes::ToPretty;
use ethcore::account_provider::AccountProvider;
use ethcore::client::TestBlockChainClient;
use parity_reactor::EventLoop;
use parity_runtime::Runtime;
use parking_lot::Mutex;
use rlp::encode;
use transaction::{Transaction, Action, SignedTransaction};
@@ -36,6 +36,7 @@ use v1::helpers::{nonce, SigningQueue, SignerService, FilledTransactionRequest,
use v1::helpers::dispatch::{FullDispatcher, eth_data_hash};
struct SignerTester {
_runtime: Runtime,
signer: Arc<SignerService>,
accounts: Arc<AccountProvider>,
io: IoHandler<Metadata>,
@@ -56,18 +57,19 @@ fn miner_service() -> Arc<TestMinerService> {
}
fn signer_tester() -> SignerTester {
let runtime = Runtime::with_thread_count(1);
let signer = Arc::new(SignerService::new_test(false));
let accounts = accounts_provider();
let client = blockchain_client();
let miner = miner_service();
let reservations = Arc::new(Mutex::new(nonce::Reservations::new()));
let event_loop = EventLoop::spawn();
let reservations = Arc::new(Mutex::new(nonce::Reservations::new(runtime.executor())));
let dispatcher = FullDispatcher::new(client, miner.clone(), reservations, 50);
let mut io = IoHandler::default();
io.extend_with(SignerClient::new(&accounts, dispatcher, &signer, event_loop.remote()).to_delegate());
io.extend_with(SignerClient::new(&accounts, dispatcher, &signer, runtime.executor()).to_delegate());
SignerTester {
_runtime: runtime,
signer: signer,
accounts: accounts,
io: io,

View File

@@ -39,10 +39,10 @@ use ethstore::ethkey::{Generator, Random};
use parking_lot::Mutex;
use serde_json;
use transaction::{Transaction, Action, SignedTransaction};
use parity_reactor::Remote;
use parity_runtime::{Runtime, Executor};
struct SigningTester {
pub runtime: Runtime,
pub signer: Arc<SignerService>,
pub client: Arc<TestBlockChainClient>,
pub miner: Arc<TestMinerService>,
@@ -52,23 +52,25 @@ struct SigningTester {
impl Default for SigningTester {
fn default() -> Self {
let runtime = Runtime::with_thread_count(1);
let signer = Arc::new(SignerService::new_test(false));
let client = Arc::new(TestBlockChainClient::default());
let miner = Arc::new(TestMinerService::default());
let accounts = Arc::new(AccountProvider::transient_provider());
let reservations = Arc::new(Mutex::new(nonce::Reservations::new()));
let reservations = Arc::new(Mutex::new(nonce::Reservations::new(runtime.executor())));
let mut io = IoHandler::default();
let dispatcher = FullDispatcher::new(client.clone(), miner.clone(), reservations, 50);
let remote = Remote::new_thread_per_future();
let executor = Executor::new_thread_per_future();
let rpc = SigningQueueClient::new(&signer, dispatcher.clone(), remote.clone(), &accounts);
let rpc = SigningQueueClient::new(&signer, dispatcher.clone(), executor.clone(), &accounts);
io.extend_with(EthSigning::to_delegate(rpc));
let rpc = SigningQueueClient::new(&signer, dispatcher, remote, &accounts);
let rpc = SigningQueueClient::new(&signer, dispatcher, executor, &accounts);
io.extend_with(ParitySigning::to_delegate(rpc));
SigningTester {
runtime,
signer: signer,
client: client,
miner: miner,