Change JsonRpc exit to use wait->close (#5566)

* Add wait-close-join pattern to rpc_service

* Create ValidatorExit struct
This commit is contained in:
carllin
2019-08-20 23:59:31 -07:00
committed by GitHub
parent 159e518671
commit bb558acdf0
4 changed files with 94 additions and 35 deletions

View File

@@ -5,17 +5,18 @@ use crate::cluster_info::ClusterInfo;
use crate::rpc::*;
use crate::service::Service;
use crate::storage_stage::StorageState;
use crate::validator::ValidatorExit;
use jsonrpc_core::MetaIoHandler;
use jsonrpc_http_server::CloseHandle;
use jsonrpc_http_server::{
hyper, AccessControlAllowOrigin, DomainsValidation, RequestMiddleware, RequestMiddlewareAction,
ServerBuilder,
};
use std::net::SocketAddr;
use std::path::{Path, PathBuf};
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::mpsc::channel;
use std::sync::{Arc, RwLock};
use std::thread::{self, sleep, Builder, JoinHandle};
use std::time::Duration;
use std::thread::{self, Builder, JoinHandle};
use tokio::prelude::Future;
pub struct JsonRpcService {
@@ -23,6 +24,8 @@ pub struct JsonRpcService {
#[cfg(test)]
pub request_processor: Arc<RwLock<JsonRpcRequestProcessor>>, // Used only by test_rpc_new()...
close_handle: Option<CloseHandle>,
}
#[derive(Default)]
@@ -88,7 +91,7 @@ impl JsonRpcService {
config: JsonRpcConfig,
bank_forks: Arc<RwLock<BankForks>>,
ledger_path: &Path,
exit: &Arc<AtomicBool>,
validator_exit: &Arc<RwLock<Option<ValidatorExit>>>,
) -> Self {
info!("rpc bound to {:?}", rpc_addr);
info!("rpc configuration: {:?}", config);
@@ -96,14 +99,14 @@ impl JsonRpcService {
storage_state,
config,
bank_forks,
exit,
validator_exit,
)));
let request_processor_ = request_processor.clone();
let cluster_info = cluster_info.clone();
let exit_ = exit.clone();
let ledger_path = ledger_path.to_path_buf();
let (close_handle_sender, close_handle_receiver) = channel();
let thread_hdl = Builder::new()
.name("solana-jsonrpc".to_string())
.spawn(move || {
@@ -126,16 +129,30 @@ impl JsonRpcService {
return;
}
while !exit_.load(Ordering::Relaxed) {
sleep(Duration::from_millis(100));
}
server.unwrap().close();
let server = server.unwrap();
close_handle_sender.send(server.close_handle()).unwrap();
server.wait();
})
.unwrap();
let close_handle = close_handle_receiver.recv().unwrap();
let close_handle_ = close_handle.clone();
let mut validator_exit_write = validator_exit.write().unwrap();
validator_exit_write
.as_mut()
.unwrap()
.register_exit(Box::new(move || close_handle_.close()));
Self {
thread_hdl,
#[cfg(test)]
request_processor,
close_handle: Some(close_handle),
}
}
pub fn exit(&mut self) {
if let Some(c) = self.close_handle.take() {
c.close()
}
}
}
@@ -153,9 +170,11 @@ mod tests {
use super::*;
use crate::contact_info::ContactInfo;
use crate::genesis_utils::{create_genesis_block, GenesisBlockInfo};
use crate::rpc::tests::create_validator_exit;
use solana_runtime::bank::Bank;
use solana_sdk::signature::KeypairUtil;
use std::net::{IpAddr, Ipv4Addr, SocketAddr};
use std::sync::atomic::AtomicBool;
#[test]
fn test_rpc_new() {
@@ -165,6 +184,7 @@ mod tests {
..
} = create_genesis_block(10_000);
let exit = Arc::new(AtomicBool::new(false));
let validator_exit = create_validator_exit(&exit);
let bank = Bank::new(&genesis_block);
let cluster_info = Arc::new(RwLock::new(ClusterInfo::new_with_invalid_keypair(
ContactInfo::default(),
@@ -174,14 +194,14 @@ mod tests {
solana_netutil::find_available_port_in_range((10000, 65535)).unwrap(),
);
let bank_forks = Arc::new(RwLock::new(BankForks::new(bank.slot(), bank)));
let rpc_service = JsonRpcService::new(
let mut rpc_service = JsonRpcService::new(
&cluster_info,
rpc_addr,
StorageState::default(),
JsonRpcConfig::default(),
bank_forks,
&PathBuf::from("farf"),
&exit,
&validator_exit,
);
let thread = rpc_service.thread_hdl.thread();
assert_eq!(thread.name().unwrap(), "solana-jsonrpc");
@@ -194,7 +214,7 @@ mod tests {
.unwrap()
.get_balance(&mint_keypair.pubkey())
);
exit.store(true, Ordering::Relaxed);
rpc_service.exit();
rpc_service.join().unwrap();
}
}