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