@@ -18,7 +18,7 @@ extern crate lazy_static;
18
18
extern crate url;
19
19
20
20
use clap:: { App , Arg } ;
21
- use futures:: sync:: { mpsc, oneshot } ;
21
+ use futures:: sync:: mpsc;
22
22
use git_testament:: { git_testament, render_testament} ;
23
23
use ipfs_api:: IpfsClient ;
24
24
use lazy_static:: lazy_static;
@@ -27,7 +27,7 @@ use std::str::FromStr;
27
27
use std:: time:: Duration ;
28
28
29
29
use graph:: components:: forward;
30
- use graph:: log:: { guarded_logger , logger, register_panic_hook } ;
30
+ use graph:: log:: logger;
31
31
use graph:: prelude:: { JsonRpcServer as JsonRpcServerTrait , * } ;
32
32
use graph:: tokio_executor;
33
33
use graph:: tokio_timer;
@@ -63,38 +63,45 @@ lazy_static! {
63
63
git_testament ! ( TESTAMENT ) ;
64
64
65
65
fn main ( ) {
66
- let ( shutdown_sender, shutdown_receiver) = oneshot:: channel ( ) ;
67
- // Register guarded panic logger which ensures logs flush on shutdown
68
- let ( panic_logger, _panic_guard) = guarded_logger ( ) ;
69
- register_panic_hook ( panic_logger, shutdown_sender) ;
70
-
71
- // Create components for tokio context: multi-threaded runtime,
72
- // executor context on the runtime, and Timer handle.
73
- let runtime = tokio:: runtime:: Runtime :: new ( ) . expect ( "Failed to create runtime" ) ;
74
- let mut executor = runtime. executor ( ) ;
66
+ use std:: sync:: Mutex ;
67
+ use tokio:: runtime;
68
+
69
+ // Create components for tokio context: multi-threaded runtime, executor
70
+ // context on the runtime, and Timer handle.
71
+ //
72
+ // Configure the runtime to shutdown after a panic.
73
+ let runtime: Arc < Mutex < Option < runtime:: Runtime > > > = Arc :: new ( Mutex :: new ( None ) ) ;
74
+ let handler_runtime = runtime. clone ( ) ;
75
+ * runtime. lock ( ) . unwrap ( ) = Some (
76
+ runtime:: Builder :: new ( )
77
+ . panic_handler ( move |_| {
78
+ let runtime = handler_runtime. clone ( ) ;
79
+ std:: thread:: spawn ( move || {
80
+ if let Some ( runtime) = runtime. lock ( ) . unwrap ( ) . take ( ) {
81
+ // Try to cleanly shutdown the runtime, but
82
+ // unconditionally exit after a while.
83
+ std:: thread:: spawn ( || {
84
+ std:: thread:: sleep ( Duration :: from_millis ( 3000 ) ) ;
85
+ std:: process:: exit ( 1 ) ;
86
+ } ) ;
87
+ runtime
88
+ . shutdown_now ( )
89
+ . wait ( )
90
+ . expect ( "Failed to shutdown Tokio Runtime" ) ;
91
+ println ! ( "Runtime cleaned up and shutdown successfully" ) ;
92
+ }
93
+ } ) ;
94
+ } )
95
+ . build ( )
96
+ . unwrap ( ) ,
97
+ ) ;
98
+
99
+ let mut executor = runtime. lock ( ) . unwrap ( ) . as_ref ( ) . unwrap ( ) . executor ( ) ;
75
100
let mut enter = tokio_executor:: enter ( )
76
101
. expect ( "Failed to enter runtime executor, multiple executors at once" ) ;
77
102
let timer = Timer :: default ( ) ;
78
103
let timer_handle = timer. handle ( ) ;
79
104
80
- // Shutdown the runtime after a panic
81
- std:: thread:: spawn ( || {
82
- let shutdown_logger = logger ( false ) ;
83
- shutdown_receiver
84
- . wait ( )
85
- . map ( |_| {
86
- let _ = runtime
87
- . shutdown_now ( )
88
- . wait ( )
89
- . expect ( "Failed to shutdown Tokio Runtime" ) ;
90
- info ! (
91
- shutdown_logger,
92
- "Runtime cleaned up and shutdown successfully"
93
- ) ;
94
- } )
95
- . expect ( "Runtime shutdown process did not finish" ) ;
96
- } ) ;
97
-
98
105
// Setup runtime context with defaults and run the main application
99
106
tokio_executor:: with_default ( & mut executor, & mut enter, |enter| {
100
107
tokio_timer:: with_default ( & timer_handle, enter, |enter| {
@@ -592,7 +599,9 @@ fn async_main() -> impl Future<Item = (), Error = ()> + Send + 'static {
592
599
break ;
593
600
}
594
601
let mut timeout = Duration :: from_millis ( 1 ) ;
595
- while pong_receive. recv_timeout ( timeout) . is_err ( ) {
602
+ while pong_receive. recv_timeout ( timeout)
603
+ == Err ( crossbeam_channel:: RecvTimeoutError :: Timeout )
604
+ {
596
605
warn ! ( contention_logger, "Possible contention in tokio threadpool" ;
597
606
"timeout_ms" => timeout. as_millis( ) ,
598
607
"code" => LogCode :: TokioContention ) ;
0 commit comments