diff --git a/ethcore/service/src/service.rs b/ethcore/service/src/service.rs index 5f4679979..f703329d6 100644 --- a/ethcore/service/src/service.rs +++ b/ethcore/service/src/service.rs @@ -29,7 +29,7 @@ use sync::PrivateTxHandler; use ethcore::client::{Client, ClientConfig, ChainNotify, ClientIoMessage}; use ethcore::miner::Miner; use ethcore::snapshot::service::{Service as SnapshotService, ServiceParams as SnapServiceParams}; -use ethcore::snapshot::{RestorationStatus}; +use ethcore::snapshot::{SnapshotService as _SnapshotService, RestorationStatus}; use ethcore::spec::Spec; use ethcore::account_provider::AccountProvider; @@ -168,6 +168,11 @@ impl ClientService { /// Get a handle to the database. pub fn db(&self) -> Arc { self.database.clone() } + + /// Shutdown the Client Service + pub fn shutdown(&self) { + self.snapshot.shutdown(); + } } /// IO interface for the Client handler diff --git a/ethcore/src/snapshot/service.rs b/ethcore/src/snapshot/service.rs index 17c362e04..942015d0f 100644 --- a/ethcore/src/snapshot/service.rs +++ b/ethcore/src/snapshot/service.rs @@ -743,6 +743,10 @@ impl SnapshotService for Service { trace!("Error sending snapshot service message: {:?}", e); } } + + fn shutdown(&self) { + self.abort_restore(); + } } impl Drop for Service { diff --git a/ethcore/src/snapshot/traits.rs b/ethcore/src/snapshot/traits.rs index 2b6ee9df9..d951f4c53 100644 --- a/ethcore/src/snapshot/traits.rs +++ b/ethcore/src/snapshot/traits.rs @@ -54,4 +54,7 @@ pub trait SnapshotService : Sync + Send { /// Feed a raw block chunk to the service to be processed asynchronously. /// no-op if currently restoring. fn restore_block_chunk(&self, hash: H256, chunk: Bytes); + + /// Shutdown the Snapshot Service by aborting any ongoing restore + fn shutdown(&self); } diff --git a/ethcore/sync/src/tests/snapshot.rs b/ethcore/sync/src/tests/snapshot.rs index 864f3d4dc..ffb71d7a7 100644 --- a/ethcore/sync/src/tests/snapshot.rs +++ b/ethcore/sync/src/tests/snapshot.rs @@ -133,6 +133,10 @@ impl SnapshotService for TestSnapshotService { self.block_restoration_chunks.lock().insert(hash, chunk); } } + + fn shutdown(&self) { + self.abort_restore(); + } } #[test] diff --git a/parity/run.rs b/parity/run.rs index fd16085c4..31f8779c0 100644 --- a/parity/run.rs +++ b/parity/run.rs @@ -885,7 +885,8 @@ fn execute_impl(cmd: RunCmd, logger: Arc, on_client_rq: rpc: rpc_direct, informant, client, - keep_alive: Box::new((watcher, service, updater, ws_server, http_server, ipc_server, ui_server, secretstore_key_server, ipfs_server, event_loop)), + client_service: Arc::new(service), + keep_alive: Box::new((watcher, updater, ws_server, http_server, ipc_server, ui_server, secretstore_key_server, ipfs_server, event_loop)), } }) } @@ -909,6 +910,7 @@ enum RunningClientInner { rpc: jsonrpc_core::MetaIoHandler>, informant: Arc>, client: Arc, + client_service: Arc, keep_alive: Box, }, } @@ -946,11 +948,14 @@ impl RunningClient { drop(client); wait_for_drop(weak_client); }, - RunningClientInner::Full { rpc, informant, client, keep_alive } => { + RunningClientInner::Full { rpc, informant, client, client_service, keep_alive } => { info!("Finishing work, please wait..."); // Create a weak reference to the client so that we can wait on shutdown // until it is dropped let weak_client = Arc::downgrade(&client); + // Shutdown and drop the ServiceClient + client_service.shutdown(); + drop(client_service); // drop this stuff as soon as exit detected. drop(rpc); drop(keep_alive); diff --git a/rpc/src/v1/tests/helpers/snapshot_service.rs b/rpc/src/v1/tests/helpers/snapshot_service.rs index 099773ab5..91cd14d73 100644 --- a/rpc/src/v1/tests/helpers/snapshot_service.rs +++ b/rpc/src/v1/tests/helpers/snapshot_service.rs @@ -50,4 +50,5 @@ impl SnapshotService for TestSnapshotService { fn abort_restore(&self) { } fn restore_state_chunk(&self, _hash: H256, _chunk: Bytes) { } fn restore_block_chunk(&self, _hash: H256, _chunk: Bytes) { } + fn shutdown(&self) { } }