when receiving a GOAWAY, allow earlier streams to still process (#133)
Once all active streams have finished, send a GOAWAY back and close the connection.
This commit is contained in:
		| @@ -101,22 +101,14 @@ where | ||||
|         // Transition the state | ||||
|         stream.state.set_reset(reason); | ||||
|  | ||||
|         // Clear all pending outbound frames | ||||
|         self.prioritize.clear_queue(stream); | ||||
|  | ||||
|         // Reclaim all capacity assigned to the stream and re-assign it to the | ||||
|         // connection | ||||
|         let available = stream.send_flow.available(); | ||||
|         stream.send_flow.claim_capacity(available); | ||||
|         self.recv_err(stream); | ||||
|  | ||||
|         let frame = frame::Reset::new(stream.id, reason); | ||||
|  | ||||
|         trace!("send_reset -- queueing; frame={:?}", frame); | ||||
|         self.prioritize.queue_frame(frame.into(), stream, task); | ||||
|  | ||||
|         // Re-assign all capacity to the connection | ||||
|         self.prioritize | ||||
|             .assign_connection_capacity(available, stream); | ||||
|  | ||||
|     } | ||||
|  | ||||
|     pub fn send_data( | ||||
| @@ -221,6 +213,19 @@ where | ||||
|         Ok(()) | ||||
|     } | ||||
|  | ||||
|     pub fn recv_err(&mut self, stream: &mut store::Ptr<B, P>) { | ||||
|         // Clear all pending outbound frames | ||||
|         self.prioritize.clear_queue(stream); | ||||
|  | ||||
|         // Reclaim all capacity assigned to the stream and re-assign it to the | ||||
|         // connection | ||||
|         let available = stream.send_flow.available(); | ||||
|         stream.send_flow.claim_capacity(available); | ||||
|         // Re-assign all capacity to the connection | ||||
|         self.prioritize | ||||
|             .assign_connection_capacity(available, stream); | ||||
|     } | ||||
|  | ||||
|     pub fn apply_remote_settings( | ||||
|         &mut self, | ||||
|         settings: &frame::Settings, | ||||
|   | ||||
| @@ -222,7 +222,6 @@ where | ||||
|     } | ||||
| } | ||||
|  | ||||
| #[cfg(feature = "unstable")] | ||||
| impl<B, P> Store<B, P> | ||||
| where | ||||
|     P: Peer, | ||||
| @@ -231,6 +230,7 @@ where | ||||
|         self.ids.len() | ||||
|     } | ||||
|  | ||||
|     #[cfg(feature = "unstable")] | ||||
|     pub fn num_wired_streams(&self) -> usize { | ||||
|         self.slab.len() | ||||
|     } | ||||
|   | ||||
| @@ -192,6 +192,7 @@ where | ||||
|             .for_each(|stream| { | ||||
|                 counts.transition(stream, |_, stream| { | ||||
|                     actions.recv.recv_err(err, &mut *stream); | ||||
|                     actions.send.recv_err(stream); | ||||
|                     Ok::<_, ()>(()) | ||||
|                 }) | ||||
|             }) | ||||
| @@ -202,6 +203,37 @@ where | ||||
|         last_processed_id | ||||
|     } | ||||
|  | ||||
|     pub fn recv_goaway(&mut self, frame: &frame::GoAway) { | ||||
|         let mut me = self.inner.lock().unwrap(); | ||||
|         let me = &mut *me; | ||||
|  | ||||
|         let actions = &mut me.actions; | ||||
|         let counts = &mut me.counts; | ||||
|  | ||||
|         let last_stream_id = frame.last_stream_id(); | ||||
|         let err = frame.reason().into(); | ||||
|  | ||||
|         me.store | ||||
|             .for_each(|stream| { | ||||
|                 if stream.id > last_stream_id { | ||||
|                     counts.transition(stream, |_, stream| { | ||||
|                         actions.recv.recv_err(&err, &mut *stream); | ||||
|                         actions.send.recv_err(stream); | ||||
|                         Ok::<_, ()>(()) | ||||
|                     }) | ||||
|                 } else { | ||||
|                     Ok::<_, ()>(()) | ||||
|                 } | ||||
|             }) | ||||
|             .unwrap(); | ||||
|  | ||||
|         actions.conn_error = Some(err); | ||||
|     } | ||||
|  | ||||
|     pub fn last_processed_id(&self) -> StreamId { | ||||
|         self.inner.lock().unwrap().actions.recv.last_processed_id() | ||||
|     } | ||||
|  | ||||
|     pub fn recv_window_update(&mut self, frame: frame::WindowUpdate) -> Result<(), RecvError> { | ||||
|         let id = frame.stream_id(); | ||||
|         let mut me = self.inner.lock().unwrap(); | ||||
| @@ -446,7 +478,6 @@ where | ||||
|     } | ||||
| } | ||||
|  | ||||
| #[cfg(feature = "unstable")] | ||||
| impl<B, P> Streams<B, P> | ||||
| where | ||||
|     B: Buf, | ||||
| @@ -457,6 +488,7 @@ where | ||||
|         me.store.num_active_streams() | ||||
|     } | ||||
|  | ||||
|     #[cfg(feature = "unstable")] | ||||
|     pub fn num_wired_streams(&self) -> usize { | ||||
|         let me = self.inner.lock().unwrap(); | ||||
|         me.store.num_wired_streams() | ||||
|   | ||||
		Reference in New Issue
	
	Block a user