mirror of
https://github.com/mimblewimble/grin.git
synced 2025-01-21 03:21:08 +03:00
Speedup shutdown (#2862)
I made an suboptimal (aka stupid) decision to stop and wait for peers one by one which makes shutdown very slow - O(n). This PR decouples sending stop signal from waiting a thread to exit. On top of it in Peers we first send stop signal to all peers and only after that start waiting for them to exit. It gives us a constant time of shutdown in most of the cases.
This commit is contained in:
parent
a1f71deba0
commit
2863ed67fd
3 changed files with 12 additions and 10 deletions
|
@ -181,18 +181,17 @@ impl StopHandle {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn stop_and_wait(&mut self) {
|
pub fn wait(&mut self) {
|
||||||
self.stop();
|
|
||||||
if let Some(peer_thread) = self.peer_thread.take() {
|
if let Some(peer_thread) = self.peer_thread.take() {
|
||||||
// wait only if other thread is calling us, eg shutdown
|
// wait only if other thread is calling us, eg shutdown
|
||||||
if thread::current().id() != peer_thread.thread().id() {
|
if thread::current().id() != peer_thread.thread().id() {
|
||||||
debug!("waiting for thread {:?} exit", peer_thread.thread().id());
|
debug!("waiting for thread {:?} exit", peer_thread.thread().id());
|
||||||
if let Err(e) = peer_thread.join() {
|
if let Err(e) = peer_thread.join() {
|
||||||
error!("failed to stop peer thread: {:?}", e);
|
error!("failed to wait for peer thread to stop: {:?}", e);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
debug!(
|
debug!(
|
||||||
"attempt to stop thread {:?} from itself",
|
"attempt to wait for thread {:?} from itself",
|
||||||
peer_thread.thread().id()
|
peer_thread.thread().id()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -397,18 +397,18 @@ impl Peer {
|
||||||
|
|
||||||
/// Stops the peer
|
/// Stops the peer
|
||||||
pub fn stop(&self) {
|
pub fn stop(&self) {
|
||||||
debug!("Stopping peer without waiting {:?}", self.info.addr);
|
debug!("Stopping peer {:?}", self.info.addr);
|
||||||
match self.stop_handle.try_lock() {
|
match self.stop_handle.try_lock() {
|
||||||
Some(handle) => handle.stop(),
|
Some(handle) => handle.stop(),
|
||||||
None => error!("can't get stop lock for peer"),
|
None => error!("can't get stop lock for peer"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Stops the peer and wait until peer's thread exit
|
/// Waits until the peer's thread exit
|
||||||
pub fn stop_and_wait(&self) {
|
pub fn wait(&self) {
|
||||||
debug!("Stopping peer {:?}", self.info.addr);
|
debug!("Waiting for peer {:?} to stop", self.info.addr);
|
||||||
match self.stop_handle.try_lock() {
|
match self.stop_handle.try_lock() {
|
||||||
Some(mut handle) => handle.stop_and_wait(),
|
Some(mut handle) => handle.wait(),
|
||||||
None => error!("can't get stop lock for peer"),
|
None => error!("can't get stop lock for peer"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -510,8 +510,11 @@ impl Peers {
|
||||||
|
|
||||||
pub fn stop(&self) {
|
pub fn stop(&self) {
|
||||||
let mut peers = self.peers.write();
|
let mut peers = self.peers.write();
|
||||||
|
for peer in peers.values() {
|
||||||
|
peer.stop();
|
||||||
|
}
|
||||||
for (_, peer) in peers.drain() {
|
for (_, peer) in peers.drain() {
|
||||||
peer.stop_and_wait();
|
peer.wait();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue