Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: Encoder state machine tolerates being wrapped by an AsyncWrite #309

Open
wants to merge 7 commits into
base: main
Choose a base branch
from

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?

tests/issues.rs Show resolved Hide resolved
.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.

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