diff options
Diffstat (limited to 'crates/server')
-rw-r--r-- | crates/server/src/main.rs | 45 |
1 files changed, 34 insertions, 11 deletions
diff --git a/crates/server/src/main.rs b/crates/server/src/main.rs index 116abce1c..2d8695d23 100644 --- a/crates/server/src/main.rs +++ b/crates/server/src/main.rs | |||
@@ -41,10 +41,10 @@ fn main() -> Result<()> { | |||
41 | .log_to_file() | 41 | .log_to_file() |
42 | .directory("log") | 42 | .directory("log") |
43 | .start()?; | 43 | .start()?; |
44 | info!("starting server"); | 44 | info!("lifecycle: server started"); |
45 | match ::std::panic::catch_unwind(|| main_inner()) { | 45 | match ::std::panic::catch_unwind(|| main_inner()) { |
46 | Ok(res) => { | 46 | Ok(res) => { |
47 | info!("shutting down: {:?}", res); | 47 | info!("lifecycle: terminating process with {:?}", res); |
48 | res | 48 | res |
49 | } | 49 | } |
50 | Err(_) => { | 50 | Err(_) => { |
@@ -105,15 +105,31 @@ fn initialize(io: &mut Io) -> Result<()> { | |||
105 | type Thunk = Box<for<'a> FnBox<&'a mut Io, Result<()>>>; | 105 | type Thunk = Box<for<'a> FnBox<&'a mut Io, Result<()>>>; |
106 | 106 | ||
107 | fn initialized(io: &mut Io) -> Result<()> { | 107 | fn initialized(io: &mut Io) -> Result<()> { |
108 | let mut world = WorldState::new(); | 108 | { |
109 | let mut pool = ThreadPool::new(4); | 109 | let mut world = WorldState::new(); |
110 | let (sender, receiver) = bounded::<Thunk>(16); | 110 | let mut pool = ThreadPool::new(4); |
111 | let res = main_loop(io, &mut world, &mut pool, sender, receiver.clone()); | 111 | let (sender, receiver) = bounded::<Thunk>(16); |
112 | info!("waiting for background jobs to finish..."); | 112 | info!("lifecycle: handshake finished, server ready to serve requests"); |
113 | receiver.for_each(drop); | 113 | let res = main_loop(io, &mut world, &mut pool, sender, receiver.clone()); |
114 | pool.join(); | 114 | info!("waiting for background jobs to finish..."); |
115 | info!("...background jobs have finished"); | 115 | receiver.for_each(drop); |
116 | res | 116 | pool.join(); |
117 | info!("...background jobs have finished"); | ||
118 | res | ||
119 | }?; | ||
120 | |||
121 | match io.recv()? { | ||
122 | RawMsg::Notification(n) => { | ||
123 | if n.method == "exit" { | ||
124 | info!("lifecycle: shutdown complete"); | ||
125 | return Ok(()); | ||
126 | } | ||
127 | bail!("unexpected notification during shutdown: {:?}", n) | ||
128 | } | ||
129 | m => { | ||
130 | bail!("unexpected message during shutdown: {:?}", m) | ||
131 | } | ||
132 | } | ||
117 | } | 133 | } |
118 | 134 | ||
119 | fn main_loop( | 135 | fn main_loop( |
@@ -172,10 +188,17 @@ fn main_loop( | |||
172 | }); | 188 | }); |
173 | Ok(()) | 189 | Ok(()) |
174 | })?; | 190 | })?; |
191 | let mut shutdown = false; | ||
175 | dispatch::handle_request::<req::Shutdown, _>(&mut req, |(), resp| { | 192 | dispatch::handle_request::<req::Shutdown, _>(&mut req, |(), resp| { |
176 | resp.result(io, ())?; | 193 | resp.result(io, ())?; |
194 | shutdown = true; | ||
177 | Ok(()) | 195 | Ok(()) |
178 | })?; | 196 | })?; |
197 | if shutdown { | ||
198 | info!("lifecycle: initiating shutdown"); | ||
199 | drop(sender); | ||
200 | return Ok(()); | ||
201 | } | ||
179 | if let Some(req) = req { | 202 | if let Some(req) = req { |
180 | error!("unknown method: {:?}", req); | 203 | error!("unknown method: {:?}", req); |
181 | dispatch::unknown_method(io, req)?; | 204 | dispatch::unknown_method(io, req)?; |