Skip to content

Commit b473092

Browse files
committed
fsm: streams
1 parent e827253 commit b473092

4 files changed

Lines changed: 46 additions & 53 deletions

File tree

‎fsm/src/lib.rs‎

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -342,6 +342,15 @@ impl<M: StreamMeta> QlFsm<M> {
342342
fsm::stream(self, stream_id)
343343
}
344344

345+
/// returns the open streams
346+
pub fn streams(&mut self) -> impl Iterator<Item = StreamOps<'_, M>> {
347+
self.state
348+
.link
349+
.connected_mut()
350+
.into_iter()
351+
.flat_map(|connection| connection.session.streams())
352+
}
353+
345354
/// queues a ping on the active session
346355
pub fn queue_ping(&mut self) -> Result<(), NoSessionError> {
347356
fsm::queue_ping(self)

‎fsm/src/session/mod.rs‎

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -216,20 +216,31 @@ impl<M: StreamMeta> SessionFsm<M> {
216216
),
217217
);
218218
let stream_index = self.state.streams.len() - 1;
219-
Ok(StreamOps::new(self, stream_id, stream_index))
219+
Ok(StreamOps::new(
220+
stream_id,
221+
self.state.streams.get_index_mut(stream_index).unwrap().1,
222+
))
220223
}
221224

222225
pub fn stream(&mut self, stream_id: StreamId) -> Result<StreamOps<'_, M>, StreamError> {
223-
let Some(stream_index) = (|| {
224-
let index = self.state.streams.get_index_of(&stream_id)?;
225-
// Event::Opened only fires after we receive the first frame of a stream
226-
// prevent early access to streams
227-
let _ = self.state.streams[index].io.header.as_ref()?;
228-
Some(index)
229-
})() else {
230-
return Err(StreamError::MissingStream);
231-
};
232-
Ok(StreamOps::new(self, stream_id, stream_index))
226+
// unopened remote streams are not available yet
227+
let stream = self
228+
.state
229+
.streams
230+
.get_mut(&stream_id)
231+
.filter(|stream| stream.io.header.is_some())
232+
.ok_or(StreamError::MissingStream)?;
233+
Ok(StreamOps::new(stream_id, stream))
234+
}
235+
236+
pub fn streams(&mut self) -> impl Iterator<Item = StreamOps<'_, M>> {
237+
self.state
238+
.streams
239+
.iter_mut()
240+
.filter_map(|(&stream_id, stream)| {
241+
stream.io.header.as_ref()?;
242+
Some(StreamOps::new(stream_id, stream))
243+
})
233244
}
234245

235246
pub fn queue_ping(&mut self) {

‎fsm/src/session/stream_ops.rs‎

Lines changed: 12 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,51 +1,38 @@
11
use ql_common::{ResetCode, StreamId};
22
use ql_wire::StreamReset;
33

4-
use super::{
5-
state::{InboundState, OutboundState, StreamIoState, StreamState},
6-
SessionFsm,
7-
};
4+
use super::state::{InboundState, OutboundState, StreamIoState, StreamState};
85
use crate::{CommitReadError, ResetOrigin, StreamMeta, StreamResetEvent, StreamResetTarget};
96

7+
/// mutable access to one stream
8+
/// terminal streams are reaped when the session is next polled
109
pub struct StreamOps<'a, M: StreamMeta> {
11-
session: &'a mut SessionFsm<M>,
1210
stream_id: StreamId,
13-
stream_index: usize,
11+
stream: &'a mut StreamState<M>,
1412
}
1513

1614
impl<'a, M: StreamMeta> StreamOps<'a, M> {
17-
pub(super) fn new(
18-
session: &'a mut SessionFsm<M>,
19-
stream_id: StreamId,
20-
stream_index: usize,
21-
) -> Self {
22-
Self {
23-
session,
24-
stream_id,
25-
stream_index,
26-
}
15+
pub(super) fn new(stream_id: StreamId, stream: &'a mut StreamState<M>) -> Self {
16+
Self { stream_id, stream }
2717
}
2818

2919
pub fn metadata(&self) -> &M {
30-
&self.stream().metadata
20+
&self.stream.metadata
3121
}
3222

3323
pub fn metadata_mut(&mut self) -> &mut M {
34-
&mut self.stream_mut().metadata
24+
&mut self.stream.metadata
3525
}
3626

3727
pub fn io(&mut self) -> StreamIo<'_> {
38-
let stream_id = self.stream_id;
39-
StreamIo::new(stream_id, &mut self.stream_mut().io)
28+
StreamIo::new(self.stream_id, &mut self.stream.io)
4029
}
4130

4231
/// returns the metadata and stream I/O together
4332
pub fn split_mut(&mut self) -> (&mut M, StreamIo<'_>) {
44-
let stream_id = self.stream_id;
45-
let stream = self.stream_mut();
4633
(
47-
&mut stream.metadata,
48-
StreamIo::new(stream_id, &mut stream.io),
34+
&mut self.stream.metadata,
35+
StreamIo::new(self.stream_id, &mut self.stream.io),
4936
)
5037
}
5138

@@ -64,7 +51,7 @@ impl<'a, M: StreamMeta> StreamOps<'a, M> {
6451
/// resets the stream and notifies its metadata
6552
pub fn reset(&mut self, target: StreamResetTarget, code: ResetCode) {
6653
let stream_id = self.stream_id;
67-
let StreamState { metadata, io } = self.stream_mut();
54+
let StreamState { metadata, io } = &mut *self.stream;
6855
let wire_target = match target {
6956
StreamResetTarget::Reader => io.role.inbound_target(),
7057
StreamResetTarget::Writer => io.role.outbound_target(),
@@ -91,22 +78,6 @@ impl<'a, M: StreamMeta> StreamOps<'a, M> {
9178
origin: ResetOrigin::Local,
9279
});
9380
}
94-
95-
#[inline]
96-
fn stream(&self) -> &StreamState<M> {
97-
&self.session.state.streams[self.stream_index]
98-
}
99-
100-
#[inline]
101-
fn stream_mut(&mut self) -> &mut StreamState<M> {
102-
&mut self.session.state.streams[self.stream_index]
103-
}
104-
}
105-
106-
impl<M: StreamMeta> Drop for StreamOps<'_, M> {
107-
fn drop(&mut self) {
108-
self.session.try_reap_stream(self.stream_id);
109-
}
11081
}
11182

11283
/// I/O operations for one stream

‎fsm/src/session/tests.rs‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -976,7 +976,7 @@ fn one_sided_remote_reset_notifies_metadata_and_preserves_stream() {
976976
}
977977

978978
#[test]
979-
fn draining_the_last_bytes_reaps_a_terminal_stream_on_drop() {
979+
fn draining_the_last_bytes_reaps_a_terminal_stream_on_next_poll() {
980980
let now = Instant::now();
981981
let mut fsm =
982982
super::SessionFsm::<TestMeta>::new(SessionConfig::default(), SessionParams::default(), now);
@@ -1010,6 +1010,8 @@ fn draining_the_last_bytes_reaps_a_terminal_stream_on_drop() {
10101010
}
10111011
drop(stream);
10121012

1013+
assert!(fsm.state.streams.contains_key(&stream_id));
1014+
fsm.take_next_write(now);
10131015
assert!(fsm.stream(stream_id).is_err());
10141016
}
10151017

0 commit comments

Comments
 (0)