bringing hypervisor as a crate in ipc dir (#1565)
* resurrecting hypervisor in ipc namespace * get rid of the quotes * target: hypervisor
This commit is contained in:
parent
2e24348c2d
commit
32a4a060d6
14
Cargo.lock
generated
14
Cargo.lock
generated
@ -13,6 +13,7 @@ dependencies = [
|
|||||||
"ethcore-devtools 1.3.0",
|
"ethcore-devtools 1.3.0",
|
||||||
"ethcore-ipc 1.3.0",
|
"ethcore-ipc 1.3.0",
|
||||||
"ethcore-ipc-codegen 1.3.0",
|
"ethcore-ipc-codegen 1.3.0",
|
||||||
|
"ethcore-ipc-hypervisor 1.2.0",
|
||||||
"ethcore-ipc-nano 1.3.0",
|
"ethcore-ipc-nano 1.3.0",
|
||||||
"ethcore-rpc 1.3.0",
|
"ethcore-rpc 1.3.0",
|
||||||
"ethcore-signer 1.3.0",
|
"ethcore-signer 1.3.0",
|
||||||
@ -315,6 +316,19 @@ dependencies = [
|
|||||||
"syntex_syntax 0.33.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"syntex_syntax 0.33.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ethcore-ipc-hypervisor"
|
||||||
|
version = "1.2.0"
|
||||||
|
dependencies = [
|
||||||
|
"ethcore-ipc 1.3.0",
|
||||||
|
"ethcore-ipc-codegen 1.3.0",
|
||||||
|
"ethcore-ipc-nano 1.3.0",
|
||||||
|
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"nanomsg 0.5.1 (git+https://github.com/ethcore/nanomsg.rs.git)",
|
||||||
|
"semver 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"syntex 0.33.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ethcore-ipc-nano"
|
name = "ethcore-ipc-nano"
|
||||||
version = "1.3.0"
|
version = "1.3.0"
|
||||||
|
@ -33,6 +33,7 @@ ethcore-dapps = { path = "dapps", optional = true }
|
|||||||
semver = "0.2"
|
semver = "0.2"
|
||||||
ethcore-ipc-nano = { path = "ipc/nano" }
|
ethcore-ipc-nano = { path = "ipc/nano" }
|
||||||
ethcore-ipc = { path = "ipc/rpc" }
|
ethcore-ipc = { path = "ipc/rpc" }
|
||||||
|
ethcore-ipc-hypervisor = { path = "ipc/hypervisor" }
|
||||||
json-ipc-server = { git = "https://github.com/ethcore/json-ipc-server.git" }
|
json-ipc-server = { git = "https://github.com/ethcore/json-ipc-server.git" }
|
||||||
ansi_term = "0.7"
|
ansi_term = "0.7"
|
||||||
|
|
||||||
|
24
build.rs
24
build.rs
@ -15,35 +15,11 @@
|
|||||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
extern crate rustc_version;
|
extern crate rustc_version;
|
||||||
extern crate syntex;
|
|
||||||
extern crate ethcore_ipc_codegen as codegen;
|
|
||||||
|
|
||||||
use std::env;
|
|
||||||
use std::path::Path;
|
|
||||||
use rustc_version::{version_meta, Channel};
|
use rustc_version::{version_meta, Channel};
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
if let Channel::Nightly = version_meta().channel {
|
if let Channel::Nightly = version_meta().channel {
|
||||||
println!("cargo:rustc-cfg=nightly");
|
println!("cargo:rustc-cfg=nightly");
|
||||||
}
|
}
|
||||||
|
|
||||||
let out_dir = env::var_os("OUT_DIR").unwrap();
|
|
||||||
|
|
||||||
// ipc pass
|
|
||||||
{
|
|
||||||
let src = Path::new("parity/hypervisor/service.rs.in");
|
|
||||||
let dst = Path::new(&out_dir).join("hypervisor_service_ipc.rs");
|
|
||||||
let mut registry = syntex::Registry::new();
|
|
||||||
codegen::register(&mut registry);
|
|
||||||
registry.expand("", &src, &dst).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
// serialization pass
|
|
||||||
{
|
|
||||||
let src = Path::new(&out_dir).join("hypervisor_service_ipc.rs");
|
|
||||||
let dst = Path::new(&out_dir).join("hypervisor_service_cg.rs");
|
|
||||||
let mut registry = syntex::Registry::new();
|
|
||||||
codegen::register(&mut registry);
|
|
||||||
registry.expand("", &src, &dst).unwrap();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
19
ipc/hypervisor/Cargo.toml
Normal file
19
ipc/hypervisor/Cargo.toml
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
[package]
|
||||||
|
name = "ethcore-ipc-hypervisor"
|
||||||
|
version = "1.2.0"
|
||||||
|
authors = ["Nikolay Volf <nikolay@ethcore.io>"]
|
||||||
|
license = "GPL-3.0"
|
||||||
|
build = "build.rs"
|
||||||
|
|
||||||
|
[features]
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
ethcore-ipc = { path = "../rpc" }
|
||||||
|
nanomsg = { git = "https://github.com/ethcore/nanomsg.rs.git" }
|
||||||
|
ethcore-ipc-nano = { path = "../nano" }
|
||||||
|
semver = "0.2"
|
||||||
|
log = "0.3"
|
||||||
|
|
||||||
|
[build-dependencies]
|
||||||
|
syntex = "*"
|
||||||
|
ethcore-ipc-codegen = { path = "../codegen" }
|
43
ipc/hypervisor/build.rs
Normal file
43
ipc/hypervisor/build.rs
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||||
|
// This file is part of Parity.
|
||||||
|
|
||||||
|
// Parity is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
|
||||||
|
// Parity is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
extern crate syntex;
|
||||||
|
extern crate ethcore_ipc_codegen as codegen;
|
||||||
|
|
||||||
|
use std::env;
|
||||||
|
use std::path::Path;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let out_dir = env::var_os("OUT_DIR").unwrap();
|
||||||
|
|
||||||
|
// ipc pass
|
||||||
|
{
|
||||||
|
let src = Path::new("src/service.rs.in");
|
||||||
|
let dst = Path::new(&out_dir).join("hypervisor_service_ipc.rs");
|
||||||
|
let mut registry = syntex::Registry::new();
|
||||||
|
codegen::register(&mut registry);
|
||||||
|
registry.expand("", &src, &dst).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
// serialization pass
|
||||||
|
{
|
||||||
|
let src = Path::new(&out_dir).join("hypervisor_service_ipc.rs");
|
||||||
|
let dst = Path::new(&out_dir).join("hypervisor_service_cg.rs");
|
||||||
|
let mut registry = syntex::Registry::new();
|
||||||
|
codegen::register(&mut registry);
|
||||||
|
registry.expand("", &src, &dst).unwrap();
|
||||||
|
}
|
||||||
|
}
|
@ -16,57 +16,58 @@
|
|||||||
|
|
||||||
//! Parity interprocess hypervisor module
|
//! Parity interprocess hypervisor module
|
||||||
|
|
||||||
// while not included in binary
|
|
||||||
#![allow(dead_code)]
|
|
||||||
#![cfg_attr(feature="dev", allow(used_underscore_binding))]
|
#![cfg_attr(feature="dev", allow(used_underscore_binding))]
|
||||||
|
|
||||||
use nanoipc;
|
extern crate ethcore_ipc as ipc;
|
||||||
use std::sync::{Arc,RwLock};
|
extern crate ethcore_ipc_nano as nanoipc;
|
||||||
use hypervisor::service::*;
|
extern crate semver;
|
||||||
use std::process::{Command,Child};
|
#[macro_use] extern crate log;
|
||||||
use std::collections::HashMap;
|
|
||||||
|
|
||||||
pub mod service;
|
pub mod service;
|
||||||
|
|
||||||
/// Default value for hypervisor ipc listener
|
/// Default value for hypervisor ipc listener
|
||||||
pub const HYPERVISOR_IPC_URL: &'static str = "ipc:///tmp/parity-internal-hyper-status.ipc";
|
pub const HYPERVISOR_IPC_URL: &'static str = "ipc:///tmp/parity-internal-hyper-status.ipc";
|
||||||
|
|
||||||
|
use std::sync::{Arc,RwLock};
|
||||||
|
use service::{HypervisorService, IpcModuleId};
|
||||||
|
use std::process::{Command,Child};
|
||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
pub use service::{HypervisorServiceClient, CLIENT_MODULE_ID};
|
||||||
|
|
||||||
type BinaryId = &'static str;
|
type BinaryId = &'static str;
|
||||||
const BLOCKCHAIN_DB_BINARY: BinaryId = "blockchain";
|
|
||||||
|
const CLIENT_BINARY: BinaryId = "client";
|
||||||
|
|
||||||
pub struct Hypervisor {
|
pub struct Hypervisor {
|
||||||
ipc_addr: String,
|
ipc_addr: String,
|
||||||
service: Arc<HypervisorService>,
|
service: Arc<HypervisorService>,
|
||||||
ipc_worker: RwLock<nanoipc::Worker<HypervisorService>>,
|
ipc_worker: RwLock<nanoipc::Worker<HypervisorService>>,
|
||||||
processes: RwLock<HashMap<BinaryId, Child>>,
|
processes: RwLock<HashMap<BinaryId, Child>>,
|
||||||
}
|
db_path: String,
|
||||||
|
|
||||||
impl Default for Hypervisor {
|
|
||||||
fn default() -> Self {
|
|
||||||
Hypervisor::new()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Hypervisor {
|
impl Hypervisor {
|
||||||
/// initializes the Hypervisor service with the open ipc socket for incoming clients
|
/// initializes the Hypervisor service with the open ipc socket for incoming clients
|
||||||
pub fn new() -> Hypervisor {
|
pub fn new(db_path: &str) -> Hypervisor {
|
||||||
Hypervisor::with_url(HYPERVISOR_IPC_URL)
|
Hypervisor::with_url(db_path, HYPERVISOR_IPC_URL)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Starts on the specified address for ipc listener
|
/// Starts on the specified address for ipc listener
|
||||||
fn with_url(addr: &str) -> Hypervisor{
|
fn with_url(db_path: &str, addr: &str) -> Hypervisor{
|
||||||
Hypervisor::with_url_and_service(addr, HypervisorService::new())
|
Hypervisor::with_url_and_service(db_path, addr, HypervisorService::new())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Starts with the specified address for the ipc listener and
|
/// Starts with the specified address for the ipc listener and
|
||||||
/// the specified list of modules in form of created service
|
/// the specified list of modules in form of created service
|
||||||
fn with_url_and_service(addr: &str, service: Arc<HypervisorService>) -> Hypervisor {
|
fn with_url_and_service(db_path: &str, addr: &str, service: Arc<HypervisorService>) -> Hypervisor {
|
||||||
let worker = nanoipc::Worker::new(&service);
|
let worker = nanoipc::Worker::new(&service);
|
||||||
Hypervisor{
|
Hypervisor{
|
||||||
ipc_addr: addr.to_owned(),
|
ipc_addr: addr.to_owned(),
|
||||||
service: service,
|
service: service,
|
||||||
ipc_worker: RwLock::new(worker),
|
ipc_worker: RwLock::new(worker),
|
||||||
processes: RwLock::new(HashMap::new()),
|
processes: RwLock::new(HashMap::new()),
|
||||||
|
db_path: db_path.to_owned(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -74,14 +75,14 @@ impl Hypervisor {
|
|||||||
/// we match binaries
|
/// we match binaries
|
||||||
fn match_module(module_id: &IpcModuleId) -> Option<BinaryId> {
|
fn match_module(module_id: &IpcModuleId) -> Option<BinaryId> {
|
||||||
match *module_id {
|
match *module_id {
|
||||||
BLOCKCHAIN_MODULE_ID => Some(BLOCKCHAIN_DB_BINARY),
|
CLIENT_MODULE_ID => Some(CLIENT_BINARY),
|
||||||
// none means the module is inside the main binary
|
// none means the module is inside the main binary
|
||||||
_ => None
|
_ => None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates IPC listener and starts all binaries
|
/// Creates IPC listener and starts all binaries
|
||||||
fn start(&self) {
|
pub fn start(&self) {
|
||||||
let mut worker = self.ipc_worker.write().unwrap();
|
let mut worker = self.ipc_worker.write().unwrap();
|
||||||
worker.add_reqrep(&self.ipc_addr).unwrap_or_else(|e| panic!("Hypervisor ipc worker can not start - critical! ({:?})", e));
|
worker.add_reqrep(&self.ipc_addr).unwrap_or_else(|e| panic!("Hypervisor ipc worker can not start - critical! ({:?})", e));
|
||||||
|
|
||||||
@ -102,8 +103,13 @@ impl Hypervisor {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let child = Command::new(binary_id).spawn().unwrap_or_else(
|
|
||||||
|e| panic!("Hypervisor cannot start binary: {}", e));
|
let mut executable_path = std::env::current_exe().unwrap();
|
||||||
|
executable_path.pop();
|
||||||
|
executable_path.push(binary_id);
|
||||||
|
|
||||||
|
let child = Command::new(&executable_path.to_str().unwrap()).arg(&self.db_path).spawn().unwrap_or_else(
|
||||||
|
|e| panic!("Hypervisor cannot start binary ({:?}): {}", executable_path, e));
|
||||||
processes.insert(binary_id, child);
|
processes.insert(binary_id, child);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -120,6 +126,22 @@ impl Hypervisor {
|
|||||||
worker.poll()
|
worker.poll()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn shutdown(&self, wait_time: Option<std::time::Duration>) {
|
||||||
|
if wait_time.is_some() { std::thread::sleep(wait_time.unwrap()) }
|
||||||
|
|
||||||
|
let mut childs = self.processes.write().unwrap();
|
||||||
|
for (ref mut binary, ref mut child) in childs.iter_mut() {
|
||||||
|
trace!(target: "hypervisor", "HYPERVISOR: Stopping process module: {}", binary);
|
||||||
|
child.kill().unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Drop for Hypervisor {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
self.shutdown(Some(std::time::Duration::new(1, 0)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
@ -135,7 +157,7 @@ mod tests {
|
|||||||
let url = "ipc:///tmp/test-parity-hypervisor-10.ipc";
|
let url = "ipc:///tmp/test-parity-hypervisor-10.ipc";
|
||||||
let test_module_id = 8080u64;
|
let test_module_id = 8080u64;
|
||||||
|
|
||||||
let hypervisor = Hypervisor::with_url_and_service(url, HypervisorService::with_modules(vec![test_module_id]));
|
let hypervisor = Hypervisor::with_url_and_service("", url, HypervisorService::with_modules(vec![test_module_id]));
|
||||||
assert_eq!(false, hypervisor.modules_ready());
|
assert_eq!(false, hypervisor.modules_ready());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -155,7 +177,7 @@ mod tests {
|
|||||||
client.module_ready(test_module_id);
|
client.module_ready(test_module_id);
|
||||||
});
|
});
|
||||||
|
|
||||||
let hypervisor = Hypervisor::with_url_and_service(url, HypervisorService::with_modules(vec![test_module_id]));
|
let hypervisor = Hypervisor::with_url_and_service("", url, HypervisorService::with_modules(vec![test_module_id]));
|
||||||
hypervisor.start();
|
hypervisor.start();
|
||||||
hypervisor_ready_local.store(true, Ordering::Relaxed);
|
hypervisor_ready_local.store(true, Ordering::Relaxed);
|
||||||
hypervisor.wait_for_startup();
|
hypervisor.wait_for_startup();
|
@ -24,7 +24,7 @@ use std::collections::VecDeque;
|
|||||||
pub type IpcModuleId = u64;
|
pub type IpcModuleId = u64;
|
||||||
|
|
||||||
/// Blockhain database module id
|
/// Blockhain database module id
|
||||||
pub const BLOCKCHAIN_MODULE_ID: IpcModuleId = 2000;
|
pub const CLIENT_MODULE_ID: IpcModuleId = 2000;
|
||||||
|
|
||||||
/// IPC service that handles module management
|
/// IPC service that handles module management
|
||||||
pub struct HypervisorService {
|
pub struct HypervisorService {
|
||||||
@ -43,7 +43,7 @@ impl HypervisorService {
|
|||||||
impl HypervisorService {
|
impl HypervisorService {
|
||||||
/// New service with the default list of modules
|
/// New service with the default list of modules
|
||||||
pub fn new() -> Arc<HypervisorService> {
|
pub fn new() -> Arc<HypervisorService> {
|
||||||
HypervisorService::with_modules(vec![])
|
HypervisorService::with_modules(vec![CLIENT_MODULE_ID])
|
||||||
}
|
}
|
||||||
|
|
||||||
/// New service with list of modules that will report for being ready
|
/// New service with list of modules that will report for being ready
|
@ -44,6 +44,8 @@ extern crate ethcore_ipc_nano as nanoipc;
|
|||||||
extern crate hyper; // for price_info.rs
|
extern crate hyper; // for price_info.rs
|
||||||
extern crate json_ipc_server as jsonipc;
|
extern crate json_ipc_server as jsonipc;
|
||||||
|
|
||||||
|
extern crate ethcore_ipc_hypervisor as hypervisor;
|
||||||
|
|
||||||
#[cfg(feature = "rpc")]
|
#[cfg(feature = "rpc")]
|
||||||
extern crate ethcore_rpc;
|
extern crate ethcore_rpc;
|
||||||
|
|
||||||
@ -57,7 +59,6 @@ extern crate ethcore_signer;
|
|||||||
mod die;
|
mod die;
|
||||||
mod price_info;
|
mod price_info;
|
||||||
mod upgrade;
|
mod upgrade;
|
||||||
mod hypervisor;
|
|
||||||
mod setup_log;
|
mod setup_log;
|
||||||
mod rpc;
|
mod rpc;
|
||||||
mod dapps;
|
mod dapps;
|
||||||
|
Loading…
Reference in New Issue
Block a user