aboutsummaryrefslogtreecommitdiff
path: root/crates/server/src/main.rs
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2018-09-01 15:40:45 +0100
committerAleksey Kladov <[email protected]>2018-09-01 15:40:45 +0100
commit8f1ce8275347e915b1cc824567e96369875cefd4 (patch)
tree1d7b56d7947a5c6a20a6547b5342e3363e6c0e0f /crates/server/src/main.rs
parent3588d6b2da6e63730cc560c9986ba7fda5de816e (diff)
move to gen-server impl
Diffstat (limited to 'crates/server/src/main.rs')
-rw-r--r--crates/server/src/main.rs104
1 files changed, 6 insertions, 98 deletions
diff --git a/crates/server/src/main.rs b/crates/server/src/main.rs
index eeb343b80..3e3bd44a1 100644
--- a/crates/server/src/main.rs
+++ b/crates/server/src/main.rs
@@ -17,26 +17,20 @@ extern crate walkdir;
17extern crate libeditor; 17extern crate libeditor;
18extern crate libanalysis; 18extern crate libanalysis;
19extern crate libsyntax2; 19extern crate libsyntax2;
20extern crate gen_lsp_server;
20extern crate im; 21extern crate im;
21extern crate relative_path; 22extern crate relative_path;
22 23
23mod io;
24mod caps; 24mod caps;
25mod req; 25mod req;
26mod dispatch;
27mod conv; 26mod conv;
28mod main_loop; 27mod main_loop;
29mod vfs; 28mod vfs;
30mod path_map; 29mod path_map;
31mod server_world; 30mod server_world;
32 31
33use threadpool::ThreadPool;
34use crossbeam_channel::bounded;
35use flexi_logger::{Logger, Duplicate}; 32use flexi_logger::{Logger, Duplicate};
36 33use gen_lsp_server::{run_server, stdio_transport};
37use ::{
38 io::{Io, RawMsg, RawResponse, RawNotification},
39};
40 34
41pub type Result<T> = ::std::result::Result<T, ::failure::Error>; 35pub type Result<T> = ::std::result::Result<T, ::failure::Error>;
42 36
@@ -60,96 +54,10 @@ fn main() -> Result<()> {
60} 54}
61 55
62fn main_inner() -> Result<()> { 56fn main_inner() -> Result<()> {
63 let mut io = Io::from_stdio(); 57 let (receiver, sender, threads) = stdio_transport();
64 let res = initialize(&mut io); 58 run_server(caps::server_capabilities(), main_loop::main_loop, receiver, sender)?;
65 info!("shutting down IO..."); 59 info!("shutting down IO...");
66 let io_res = io.stop(); 60 threads.join()?;
67 info!("... IO is down"); 61 info!("... IO is down");
68 match (res, io_res) { 62 Ok(())
69 (Ok(()), Ok(())) => Ok(()),
70 (res, Ok(())) => res,
71 (Ok(()), io_res) => io_res,
72 (res, Err(io_err)) => {
73 error!("shutdown error: {:?}", io_err);
74 res
75 }
76 }
77}
78
79fn initialize(io: &mut Io) -> Result<()> {
80 match io.recv()? {
81 RawMsg::Notification(n) =>
82 bail!("expected initialize request, got {:?}", n),
83 RawMsg::Response(res) =>
84 bail!("expected initialize request, got {:?}", res),
85
86 RawMsg::Request(req) => {
87 let req = dispatch::handle_request::<req::Initialize, _>(req, |_params, resp| {
88 let res = req::InitializeResult { capabilities: caps::server_capabilities() };
89 let resp = resp.into_response(Ok(res))?;
90 io.send(RawMsg::Response(resp));
91 Ok(())
92 })?;
93 if let Err(req) = req {
94 bail!("expected initialize request, got {:?}", req)
95 }
96 match io.recv()? {
97 RawMsg::Notification(n) => {
98 if n.method != "initialized" {
99 bail!("expected initialized notification");
100 }
101 }
102 _ => bail!("expected initialized notification"),
103 }
104 }
105 }
106 initialized(io)
107}
108
109enum Task {
110 Respond(RawResponse),
111 Notify(RawNotification),
112 Die(::failure::Error),
113}
114
115fn initialized(io: &mut Io) -> Result<()> {
116 {
117 let mut pool = ThreadPool::new(4);
118 let (task_sender, task_receiver) = bounded::<Task>(16);
119 let (fs_events_receiver, watcher) = vfs::watch(vec![
120 ::std::env::current_dir()?,
121 ]);
122 info!("lifecycle: handshake finished, server ready to serve requests");
123 let res = main_loop::main_loop(
124 io,
125 &mut pool,
126 task_sender,
127 task_receiver.clone(),
128 fs_events_receiver,
129 );
130
131 info!("waiting for background jobs to finish...");
132 task_receiver.for_each(drop);
133 pool.join();
134 info!("...background jobs have finished");
135
136 info!("waiting for file watcher to finish...");
137 watcher.stop()?;
138 info!("...file watcher has finished");
139
140 res
141 }?;
142
143 match io.recv()? {
144 RawMsg::Notification(n) => {
145 if n.method == "exit" {
146 info!("lifecycle: shutdown complete");
147 return Ok(());
148 }
149 bail!("unexpected notification during shutdown: {:?}", n)
150 }
151 m => {
152 bail!("unexpected message during shutdown: {:?}", m)
153 }
154 }
155} 63}