Skip to content

Conversation

aatifsyed
Copy link

@aatifsyed aatifsyed commented Oct 31, 2024

Simplified the Encoder state machine.
It should now handle poll_flush calls after poll_shutdown calls.

Closes #308
See also #246

@robjtede robjtede added the A-semver-norelease change that does not require a release label Oct 31, 2024
@NobodyXu
Copy link
Collaborator

NobodyXu commented Nov 1, 2024

Thanks!

You are right, poll_shutdown should indeed call self.poll_flush before calling inner.poll_shutdown

1 similar comment
@NobodyXu
Copy link
Collaborator

NobodyXu commented Nov 1, 2024

Thanks!

You are right, poll_shutdown should indeed call self.poll_flush before calling inner.poll_shutdown

@aatifsyed aatifsyed changed the title Add test case for #308 (#246) fix: Encoder state machine Nov 1, 2024
@aatifsyed aatifsyed changed the title fix: Encoder state machine fix: Encoder state machine tolerates being wrapped by an AsyncWrite Nov 1, 2024
Copy link
Collaborator

@NobodyXu NobodyXu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, mostly LGTM

cc @robjtede can you take a look at this please?

.with_span_events(FmtSpan::NEW)
.init();
let mut zstd_encoder = Wrapper::new(Trace::new(ZstdEncoder::new(DelayedShutdown::default())));
futures::executor::block_on(zstd_encoder.shutdown()).unwrap();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should test poll_shutdown by keeping track of numbers of calls to underlying poll_flush?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that feels a bit excessive - we know that poll_shutdown has been called twice because of how DelayedShutdown is implemented (only returns Poll::Ready the second time), and that's what we really want to test.

i.e I don't think a change like this actually does anything for the test:

-    let mut zstd_encoder = Wrapper::new(Trace::new(ZstdEncoder::new(DelayedShutdown::default())));
+    let mut delayed_shutdown = DelayedShutdown::default();
+    let mut zstd_encoder = Wrapper::new(Trace::new(ZstdEncoder::new(&mut delayed_shutdown)));
     futures::executor::block_on(zstd_encoder.shutdown()).unwrap();
+    assert_eq!(delayed_shutdown.num_times_shutdown_called, 1);

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd want the poll_flush to be tested, by making sure it is called if and only if poll_shutdown is called.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:) could you help me write this test?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bit busy now, but in general, I think we want something like this:

struct DummyWriter {
    is_poll_flush_called: boolean,
    is_poll_shutdown_called: usize,
}

impl AsyncWrite {
    fn poll_flush(...) {
        assert!(!self.is_poll_shutdown_called);
        self.is_poll_flush_called = true;
        Ready(Ok())
    }

    fn poll_shutdown(...) {
        self.is_poll_shutdown_called = true;
        Ready(Ok())
    }
}

And then after shutdown is called, we check that both is set to true to verify this fix.

@aatifsyed
Copy link
Author

What's the level of enthusiasm on this PR?

@NobodyXu
Copy link
Collaborator

What's the level of enthusiasm on this PR?

I can continue review once the feedback has been addressed

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-semver-norelease change that does not require a release
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Encoder does not follow the tokio::io::AsyncWrite protocol
3 participants