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

Commit

Permalink
bringing hypervisor as a crate in ipc dir (#1565)
Browse files Browse the repository at this point in the history
* resurrecting hypervisor in ipc namespace

* get rid of the quotes

* target: hypervisor
  • Loading branch information
NikVolf authored and gavofyork committed Jul 9, 2016
1 parent 2e24348 commit 32a4a06
Show file tree
Hide file tree
Showing 9 changed files with 129 additions and 53 deletions.
14 changes: 14 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ ethcore-dapps = { path = "dapps", optional = true }
semver = "0.2"
ethcore-ipc-nano = { path = "ipc/nano" }
ethcore-ipc = { path = "ipc/rpc" }
ethcore-ipc-hypervisor = { path = "ipc/hypervisor" }
json-ipc-server = { git = "https://github.com/ethcore/json-ipc-server.git" }
ansi_term = "0.7"

Expand Down
24 changes: 0 additions & 24 deletions build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,35 +15,11 @@
// along with Parity. If not, see <http://www.gnu.org/licenses/>.

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};

fn main() {
if let Channel::Nightly = version_meta().channel {
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 changes: 19 additions & 0 deletions ipc/hypervisor/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
[package]
name = "ethcore-ipc-hypervisor"
version = "1.2.0"
authors = ["Nikolay Volf <[email protected]>"]
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 changes: 43 additions & 0 deletions ipc/hypervisor/build.rs
Original file line number Diff line number Diff line change
@@ -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();
}
}
72 changes: 47 additions & 25 deletions parity/hypervisor/mod.rs → ipc/hypervisor/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,72 +16,73 @@

//! Parity interprocess hypervisor module
// while not included in binary
#![allow(dead_code)]
#![cfg_attr(feature="dev", allow(used_underscore_binding))]

use nanoipc;
use std::sync::{Arc,RwLock};
use hypervisor::service::*;
use std::process::{Command,Child};
use std::collections::HashMap;
extern crate ethcore_ipc as ipc;
extern crate ethcore_ipc_nano as nanoipc;
extern crate semver;
#[macro_use] extern crate log;

pub mod service;

/// Default value for hypervisor ipc listener
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;
const BLOCKCHAIN_DB_BINARY: BinaryId = "blockchain";

const CLIENT_BINARY: BinaryId = "client";

pub struct Hypervisor {
ipc_addr: String,
service: Arc<HypervisorService>,
ipc_worker: RwLock<nanoipc::Worker<HypervisorService>>,
processes: RwLock<HashMap<BinaryId, Child>>,
}

impl Default for Hypervisor {
fn default() -> Self {
Hypervisor::new()
}
db_path: String,
}

impl Hypervisor {
/// initializes the Hypervisor service with the open ipc socket for incoming clients
pub fn new() -> Hypervisor {
Hypervisor::with_url(HYPERVISOR_IPC_URL)
pub fn new(db_path: &str) -> Hypervisor {
Hypervisor::with_url(db_path, HYPERVISOR_IPC_URL)
}

/// Starts on the specified address for ipc listener
fn with_url(addr: &str) -> Hypervisor{
Hypervisor::with_url_and_service(addr, HypervisorService::new())
fn with_url(db_path: &str, addr: &str) -> Hypervisor{
Hypervisor::with_url_and_service(db_path, addr, HypervisorService::new())
}

/// Starts with the specified address for the ipc listener and
/// 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);
Hypervisor{
ipc_addr: addr.to_owned(),
service: service,
ipc_worker: RwLock::new(worker),
processes: RwLock::new(HashMap::new()),
db_path: db_path.to_owned(),
}
}

/// Since one binary can host multiple modules
/// we match binaries
fn match_module(module_id: &IpcModuleId) -> Option<BinaryId> {
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
}
}

/// Creates IPC listener and starts all binaries
fn start(&self) {
pub fn start(&self) {
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));

Expand All @@ -102,8 +103,13 @@ impl Hypervisor {
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);
});
}
Expand All @@ -120,6 +126,22 @@ impl Hypervisor {
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)]
Expand All @@ -135,7 +157,7 @@ mod tests {
let url = "ipc:///tmp/test-parity-hypervisor-10.ipc";
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());
}

Expand All @@ -155,7 +177,7 @@ mod tests {
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_ready_local.store(true, Ordering::Relaxed);
hypervisor.wait_for_startup();
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ use std::collections::VecDeque;
pub type IpcModuleId = u64;

/// Blockhain database module id
pub const BLOCKCHAIN_MODULE_ID: IpcModuleId = 2000;
pub const CLIENT_MODULE_ID: IpcModuleId = 2000;

/// IPC service that handles module management
pub struct HypervisorService {
Expand All @@ -43,7 +43,7 @@ impl HypervisorService {
impl HypervisorService {
/// New service with the default list of modules
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
Expand Down
5 changes: 3 additions & 2 deletions parity/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ extern crate ethcore_ipc_nano as nanoipc;
extern crate hyper; // for price_info.rs
extern crate json_ipc_server as jsonipc;

extern crate ethcore_ipc_hypervisor as hypervisor;

#[cfg(feature = "rpc")]
extern crate ethcore_rpc;

Expand All @@ -57,7 +59,6 @@ extern crate ethcore_signer;
mod die;
mod price_info;
mod upgrade;
mod hypervisor;
mod setup_log;
mod rpc;
mod dapps;
Expand Down Expand Up @@ -212,7 +213,7 @@ fn execute_client(conf: Configuration, spec: Spec, client_config: ClientConfig)

// Check fork settings.
if conf.policy() != Policy::None {
warn!("Value given for --policy, yet no proposed forks exist. Ignoring.");
warn!("Value given for --policy, yet no proposed forks exist. Ignoring.");
}

let net_settings = conf.net_settings(&spec);
Expand Down

0 comments on commit 32a4a06

Please sign in to comment.