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:
Sean McArthur
2017-10-05 15:32:13 -07:00
committed by GitHub
parent c4ca8f7def
commit ecd2764f4b
6 changed files with 174 additions and 31 deletions

View File

@@ -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,

View File

@@ -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()
}

View File

@@ -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()