|
1 | 1 | use std::{ |
2 | 2 | cell::RefCell, |
3 | 3 | collections::HashMap, |
4 | | - io::Write, |
5 | | - net::SocketAddr, |
| 4 | + io::{ErrorKind, Write}, |
| 5 | + net::{Shutdown, SocketAddr}, |
6 | 6 | rc::{Rc, Weak}, |
7 | 7 | time::Duration, |
8 | 8 | }; |
@@ -47,7 +47,7 @@ macro_rules! println_ { |
47 | 47 | }; |
48 | 48 | } |
49 | 49 | fn debug_kawa(_kawa: &GenericHttpStream) { |
50 | | - kawa::debug_kawa(_kawa); |
| 50 | + // kawa::debug_kawa(_kawa); |
51 | 51 | } |
52 | 52 |
|
53 | 53 | /// Generic Http representation using the Kawa crate using the Checkout of Sozu as buffer |
@@ -299,18 +299,24 @@ impl<Front: SocketHandler> Connection<Front> { |
299 | 299 | Connection::H2(c) => &mut c.position, |
300 | 300 | } |
301 | 301 | } |
302 | | - pub fn timeout_container(&mut self) -> &mut TimeoutContainer { |
303 | | - match self { |
304 | | - Connection::H1(c) => &mut c.timeout_container, |
305 | | - Connection::H2(c) => &mut c.timeout_container, |
306 | | - } |
307 | | - } |
308 | 302 | pub fn socket(&self) -> &TcpStream { |
309 | 303 | match self { |
310 | 304 | Connection::H1(c) => c.socket.socket_ref(), |
311 | 305 | Connection::H2(c) => c.socket.socket_ref(), |
312 | 306 | } |
313 | 307 | } |
| 308 | + pub fn socket_mut(&mut self) -> &mut TcpStream { |
| 309 | + match self { |
| 310 | + Connection::H1(c) => c.socket.socket_mut(), |
| 311 | + Connection::H2(c) => c.socket.socket_mut(), |
| 312 | + } |
| 313 | + } |
| 314 | + pub fn timeout_container(&mut self) -> &mut TimeoutContainer { |
| 315 | + match self { |
| 316 | + Connection::H1(c) => &mut c.timeout_container, |
| 317 | + Connection::H2(c) => &mut c.timeout_container, |
| 318 | + } |
| 319 | + } |
314 | 320 | fn force_disconnect(&mut self) -> MuxResult { |
315 | 321 | match self { |
316 | 322 | Connection::H1(c) => c.force_disconnect(), |
@@ -951,6 +957,9 @@ impl<Front: SocketHandler + std::fmt::Debug> SessionState for Mux<Front> { |
951 | 957 | *position = Position::Client(BackendStatus::Connected( |
952 | 958 | std::mem::take(cluster_id), |
953 | 959 | )); |
| 960 | + backend |
| 961 | + .timeout_container() |
| 962 | + .set_duration(self.router.configured_backend_timeout); |
954 | 963 | } |
955 | 964 | _ => {} |
956 | 965 | } |
@@ -981,7 +990,29 @@ impl<Front: SocketHandler + std::fmt::Debug> SessionState for Mux<Front> { |
981 | 990 | } |
982 | 991 | if !dead_backends.is_empty() { |
983 | 992 | for token in &dead_backends { |
984 | | - self.router.backends.remove(token); |
| 993 | + let proxy_borrow = proxy.borrow(); |
| 994 | + if let Some(mut backend) = self.router.backends.remove(token) { |
| 995 | + backend.timeout_container().cancel(); |
| 996 | + let socket = backend.socket_mut(); |
| 997 | + if let Err(e) = proxy_borrow.deregister_socket(socket) { |
| 998 | + error!("error deregistering back socket({:?}): {:?}", socket, e); |
| 999 | + } |
| 1000 | + if let Err(e) = socket.shutdown(Shutdown::Both) { |
| 1001 | + if e.kind() != ErrorKind::NotConnected { |
| 1002 | + error!( |
| 1003 | + "error shutting down back socket({:?}): {:?}", |
| 1004 | + socket, e |
| 1005 | + ); |
| 1006 | + } |
| 1007 | + } |
| 1008 | + } else { |
| 1009 | + error!("session {:?} has no backend!", token); |
| 1010 | + } |
| 1011 | + if !proxy_borrow.remove_session(*token) { |
| 1012 | + error!("session {:?} was already removed!", token); |
| 1013 | + } else { |
| 1014 | + println!("SUCCESS: session {token:?} was removed!"); |
| 1015 | + } |
985 | 1016 | } |
986 | 1017 | println_!("FRONTEND: {:#?}", self.frontend); |
987 | 1018 | println_!("BACKENDS: {:#?}", self.router.backends); |
@@ -1013,10 +1044,15 @@ impl<Front: SocketHandler + std::fmt::Debug> SessionState for Mux<Front> { |
1013 | 1044 | } |
1014 | 1045 |
|
1015 | 1046 | let context = &mut self.context; |
1016 | | - let front_readiness = self.frontend.readiness_mut(); |
1017 | 1047 | let mut dirty = false; |
1018 | 1048 | for stream_id in 0..context.streams.len() { |
1019 | 1049 | if context.streams[stream_id].state == StreamState::Link { |
| 1050 | + // Before the first request triggers a stream Link, the frontend timeout is set |
| 1051 | + // to a shorter request_timeout, here we switch to the longer nominal timeout |
| 1052 | + self.frontend |
| 1053 | + .timeout_container() |
| 1054 | + .set_duration(self.configured_frontend_timeout); |
| 1055 | + let front_readiness = self.frontend.readiness_mut(); |
1020 | 1056 | dirty = true; |
1021 | 1057 | match self.router.connect( |
1022 | 1058 | stream_id, |
@@ -1105,9 +1141,9 @@ impl<Front: SocketHandler + std::fmt::Debug> SessionState for Mux<Front> { |
1105 | 1141 | should_write = true; |
1106 | 1142 | } |
1107 | 1143 | StreamState::Linked(_) => { |
1108 | | - // A stream Linked to a backend is waiting for the response, not the answer. |
| 1144 | + // A stream Linked to a backend is waiting for the response, not the request. |
1109 | 1145 | // For streaming or malformed requests, it is possible that the request is not |
1110 | | - // terminated at this point. For now, we do nothing and |
| 1146 | + // terminated at this point. For now, we do nothing |
1111 | 1147 | should_close = false; |
1112 | 1148 | } |
1113 | 1149 | StreamState::Unlinked => { |
@@ -1202,27 +1238,48 @@ impl<Front: SocketHandler + std::fmt::Debug> SessionState for Mux<Front> { |
1202 | 1238 | } |
1203 | 1239 | } |
1204 | 1240 |
|
1205 | | - fn close(&mut self, _proxy: Rc<RefCell<dyn L7Proxy>>, _metrics: &mut SessionMetrics) { |
1206 | | - let s = match &mut self.frontend { |
1207 | | - Connection::H1(c) => &mut c.socket, |
1208 | | - Connection::H2(c) => &mut c.socket, |
1209 | | - }; |
1210 | | - let mut b = [0; 1024]; |
1211 | | - let (size, status) = s.socket_read(&mut b); |
1212 | | - println_!("{size} {status:?} {:?}", &b[..size]); |
1213 | | - for stream in &mut self.context.streams { |
1214 | | - for kawa in [&mut stream.front, &mut stream.back] { |
1215 | | - debug_kawa(kawa); |
1216 | | - kawa.prepare(&mut kawa::h1::BlockConverter); |
1217 | | - let out = kawa.as_io_slice(); |
1218 | | - let mut writer = std::io::BufWriter::new(Vec::new()); |
1219 | | - let amount = writer.write_vectored(&out).unwrap(); |
1220 | | - println_!( |
1221 | | - "amount: {amount}\n{}", |
1222 | | - String::from_utf8_lossy(writer.buffer()) |
1223 | | - ); |
| 1241 | + fn close(&mut self, proxy: Rc<RefCell<dyn L7Proxy>>, _metrics: &mut SessionMetrics) { |
| 1242 | + println_!("FRONTEND: {:#?}", self.frontend); |
| 1243 | + println_!("BACKENDS: {:#?}", self.router.backends); |
| 1244 | + |
| 1245 | + for (token, backend) in &mut self.router.backends { |
| 1246 | + let proxy_borrow = proxy.borrow(); |
| 1247 | + backend.timeout_container().cancel(); |
| 1248 | + let socket = backend.socket_mut(); |
| 1249 | + if let Err(e) = proxy_borrow.deregister_socket(socket) { |
| 1250 | + error!("error deregistering back socket({:?}): {:?}", socket, e); |
| 1251 | + } |
| 1252 | + if let Err(e) = socket.shutdown(Shutdown::Both) { |
| 1253 | + if e.kind() != ErrorKind::NotConnected { |
| 1254 | + error!("error shutting down back socket({:?}): {:?}", socket, e); |
| 1255 | + } |
| 1256 | + } |
| 1257 | + if !proxy_borrow.remove_session(*token) { |
| 1258 | + error!("session {:?} was already removed!", token); |
| 1259 | + } else { |
| 1260 | + println!("SUCCESS: session {token:?} was removed!"); |
1224 | 1261 | } |
1225 | 1262 | } |
| 1263 | + // let s = match &mut self.frontend { |
| 1264 | + // Connection::H1(c) => &mut c.socket, |
| 1265 | + // Connection::H2(c) => &mut c.socket, |
| 1266 | + // }; |
| 1267 | + // let mut b = [0; 1024]; |
| 1268 | + // let (size, status) = s.socket_read(&mut b); |
| 1269 | + // println_!("{size} {status:?} {:?}", &b[..size]); |
| 1270 | + // for stream in &mut self.context.streams { |
| 1271 | + // for kawa in [&mut stream.front, &mut stream.back] { |
| 1272 | + // debug_kawa(kawa); |
| 1273 | + // kawa.prepare(&mut kawa::h1::BlockConverter); |
| 1274 | + // let out = kawa.as_io_slice(); |
| 1275 | + // let mut writer = std::io::BufWriter::new(Vec::new()); |
| 1276 | + // let amount = writer.write_vectored(&out).unwrap(); |
| 1277 | + // println_!( |
| 1278 | + // "amount: {amount}\n{}", |
| 1279 | + // String::from_utf8_lossy(writer.buffer()) |
| 1280 | + // ); |
| 1281 | + // } |
| 1282 | + // } |
1226 | 1283 | } |
1227 | 1284 |
|
1228 | 1285 | fn shutting_down(&mut self) -> SessionIsToBeClosed { |
|
0 commit comments