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

Implement unsolicited message handling while IDLEing #130

Closed
wants to merge 4 commits into from

Conversation

norcalli
Copy link

@norcalli norcalli commented Aug 4, 2019

Adapted from #114


This change is Reviewable

@norcalli
Copy link
Author

norcalli commented Aug 4, 2019

Fixes #128

@norcalli
Copy link
Author

norcalli commented Aug 4, 2019

I had to change around the logic for the "read_response" after "terminate" because there could've been multiple messages sent from the server, so we need to iterate over all of them, but I also need to know when to stop, and the only cue to stop is the OK we get from the server for the IDLE DONE.

@norcalli
Copy link
Author

norcalli commented Aug 4, 2019

I'm also not sure about making the unsolicited responses be empty by default, because I found it surprising. However, from an engineering perspective, it makes sense because if someone doesn't handle them then they build up in memory. This could be solved by a bounded channel with a sane default, as well, to impose an upper limit.

For now, I think dumping all unsolicited responses unless otherwise requested is easier and works fine, though.

@norcalli
Copy link
Author

norcalli commented Aug 4, 2019

The test failure appears to be unrelated to any code I wrote.

@norcalli
Copy link
Author

norcalli commented Aug 5, 2019

thread 'main' panicked at 'assertion failed: `(left == right)`
  left: `[97, 49, 56]`,
 right: `[97, 49, 57]`', /home/ashkan/works/3rd/rust-imap/src/client.rs:1206:25
note: Run with `RUST_BACKTRACE=1` environment variable to display a backtrace.

had an error related to match being one shorter than the client expected. I'm wondering if me doing the matching for the ok response in the handle is breaking some invariants.

@norcalli
Copy link
Author

FYI, I've been running this for the past week without any crashes or problems. I'm using it as my main ingestion pipeline for my mail now.

@jonhoo
Copy link
Owner

jonhoo commented Aug 21, 2019

I've been away on vacation for the past few weeks, so haven't had a chance to look. Will try to take a look once I get the time! Thanks for writing this up! :D

@@ -46,7 +46,7 @@ where
match map(resp)? {
MapOrNot::Map(t) => things.push(t),
MapOrNot::Not(resp) => match handle_unilateral(resp, unsolicited) {
Some(Response::Fetch(..)) => continue,
// Some(Response::Fetch(..)) => continue,
Copy link
Owner

Choose a reason for hiding this comment

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

Why this change?

}
}
Err(err) => return Err(err),
Ok(_) => {
Copy link
Owner

Choose a reason for hiding this comment

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

I don't understand this clause at all. Why do we need this nested loop construct? And why do we need to terminate the IDLE for each iteration?

@@ -202,7 +199,7 @@ pub fn parse_mailbox(
if let imap_proto::Status::Ok = status {
} else {
// how can this happen for a Response::Data?
unreachable!();
unreachable!("Received something other than OK from mailbox data");
Copy link
Owner

Choose a reason for hiding this comment

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

This should probably include status for convenience.

return Err(Error::Bad(information.unwrap_or("").to_owned()))
}
imap_proto::Status::No => {
return Err(Error::Bad(information.unwrap_or("").to_owned()))
Copy link
Owner

Choose a reason for hiding this comment

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

Don't we also have Error::No?

}
Err(err) => return Err(err),
Ok(_) => {
let _ = parse::parse_idle(&buffer, &mut self.unsolicited_responses_tx)?;
Copy link
Owner

Choose a reason for hiding this comment

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

Specifically, shouldn't this use the return value from parse_idle to know whether or not DONE was sent?

}
Ok((rest, data)) => {
lines = rest;
if let Some(resp) = handle_unilateral(data, unsolicited) {
Copy link
Owner

Choose a reason for hiding this comment

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

We should probably rename handle_unilateral to try_handle_unilateral to make it clearer that Some is returned if it wasn't handled. That's orthogonal to your change though :)

Unseen(u32),
}

impl<'a> From<imap_proto::types::ResponseCode<'a>> for ResponseCode {
Copy link
Owner

Choose a reason for hiding this comment

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

I wonder if ToOwned is the trait to implement here.

// Set the new filter mask, and remove unwanted responses from the current queue.
pub(crate) fn request(
&mut self,
receiver: &mpsc::Receiver<UnsolicitedResponse>,
Copy link
Owner

Choose a reason for hiding this comment

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

I'm not sure I understand what this receiver is? Where does it come from?

mask: EnumSet<UnsolicitedResponseCategory>,
) {
self.allow = mask;
for message in receiver.try_iter() {
Copy link
Owner

Choose a reason for hiding this comment

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

This also seems pretty strange -- what about future messages? Are they never forwarded then?

Copy link
Author

Choose a reason for hiding this comment

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

I copied a lot of stuff from the existing branch, assuming that it was already reviewed. About 20% of it is mine. Frankly, I might rewrite it. I've noticed that some messages are missed if they come in too quickly.

Copy link
Owner

Choose a reason for hiding this comment

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

Long time no see :) Did you ever get around to doing this rewrite?

@jonhoo
Copy link
Owner

jonhoo commented Sep 1, 2019

Hi @norcalli -- a gentle ping on this :)

@norcalli
Copy link
Author

@jonhoo hey sorry for the late reply, gonna take a look at this today.

This was referenced Sep 16, 2019
@hpk42
Copy link

hpk42 commented Oct 2, 2019

@norcalli just so you i'd be interested in your PR landing but my Rust-Fu is not good enough yet to help much.

@jonhoo
Copy link
Owner

jonhoo commented Jan 29, 2021

@norcalli Another gentle ping on this :)

@jonhoo
Copy link
Owner

jonhoo commented Mar 6, 2021

@norcalli I'd like to try to push out 3.0.0 soon — want to give this another stab?

@jonhoo
Copy link
Owner

jonhoo commented Apr 20, 2021

Replaced by #186.

@jonhoo jonhoo closed this Apr 20, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants