Skip to content

Conversation

chrisbobbe
Copy link
Collaborator

This fixes the "fourth buggy behavior" in #1798:
#1798 (comment)

Fixes-partly: #1798

@chrisbobbe chrisbobbe added the maintainer review PR ready for review by Zulip maintainers label Oct 10, 2025
@chrisbobbe chrisbobbe marked this pull request as draft October 10, 2025 23:49
@chrisbobbe
Copy link
Collaborator Author

(Oops, I'll need to rethink this a bit following some discussion with Greg in the office.)

@chrisbobbe chrisbobbe force-pushed the pr-unsubscribed-channels-fourth-buggy-behavior branch from 3612e86 to 4fa0a1a Compare October 15, 2025 23:49
@chrisbobbe chrisbobbe marked this pull request as ready for review October 15, 2025 23:49
Copy link
Member

@gnprice gnprice left a comment

Choose a reason for hiding this comment

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

Thanks! At #1798 (comment) you asked for an initial look at this logic, so comments on that below.

Comment on lines 557 to 559
// If the message is one we already know about (from a fetch),
// clobber it with the one from the event system.
// See [fetchedMessages] for reasoning.
Copy link
Member

Choose a reason for hiding this comment

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

(Is this existing comment meant to refer to reconcileMessages? I think fetchedMessages was a previous name for that.)

Comment on lines 454 to 478
/// (We have seen a few such events, actually --
/// maybe because the channel was recently subscribed? --
/// but not consistently, and we're not supposed to rely on them.)
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
/// (We have seen a few such events, actually --
/// maybe because the channel was recently subscribed? --
/// but not consistently, and we're not supposed to rely on them.)
/// (We have seen a few such events, actually --
/// maybe because the channel was recently unsubscribed? --
/// but not consistently, and we're not supposed to rely on them.)

?

Comment on lines 419 to 420
// [1] With one exception: if the version we have was in an unsubscribed
// channel when we got it or sometime since, we take the fetched version
Copy link
Member

Choose a reason for hiding this comment

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

I like this formulation of which messages go in _maybeStaleChannelMessages. It'd be good to put it in that field's doc.

Comment on lines 430 to 434
// Side effect: update our "potentially stale" knowledge based on
// whether the channel is subscribed right now.
&& (subscriptions[message.streamId] != null
? _maybeStaleChannelMessages.remove(message.id)
: !_maybeStaleChannelMessages.add(message.id));
Copy link
Member

Choose a reason for hiding this comment

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

It's a bit confusing that we need this side effect on the maybe-stale set here. I think this logic could benefit from some unpacking.

In particular, it seems like there are really four cases here:

  • currently subscribed vs. not;
  • for each of those, currently in the maybe-stale set or not.

chrisbobbe added a commit to chrisbobbe/zulip-flutter that referenced this pull request Oct 16, 2025
@chrisbobbe chrisbobbe force-pushed the pr-unsubscribed-channels-fourth-buggy-behavior branch from 4fa0a1a to 6ed2244 Compare October 16, 2025 21:04
@chrisbobbe
Copy link
Collaborator Author

Thanks for taking a look! Revision pushed.

@chrisbobbe chrisbobbe force-pushed the pr-unsubscribed-channels-fourth-buggy-behavior branch 3 times, most recently from e8f8054 to a9b4906 Compare October 16, 2025 21:20
Copy link
Member

@gnprice gnprice left a comment

Choose a reason for hiding this comment

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

Thanks! I think that's helpful. A couple of comments below on the new version.

Comment on lines +478 to 485
Message _stripMatchFields(Message message) {
message.matchContent = null;
message.matchTopic = null;
return message;
}
Copy link
Member

Choose a reason for hiding this comment

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

The factoring out of this step could happen in a prep commit. That would simplify the complexity of the main commit a bit — it'd be moving around where an expression like _stripMatchFields(incoming) appears, and adding a case where something else gets used instead, but the expression itself would remain the same.

(Or maybe the main commit would change from "message" to "incoming", but anyway that's a rather smaller change.)

Comment on lines 432 to 447
Message _reconcileWhenPresent(Message current, Message incoming) {
bool currentIsMaybeStale = false;
if (incoming is StreamMessage) {
if (subscriptions[incoming.streamId] != null) {
// The incoming message won't grow stale; it's in a subscribed channel.
// Remove it from _maybeStaleChannelMessages if it was there.
currentIsMaybeStale = _maybeStaleChannelMessages.remove(incoming.id);
} else {
assert(_maybeStaleChannelMessages.contains(incoming.id));
currentIsMaybeStale = true;
}
}

return currentIsMaybeStale
? _stripMatchFields(incoming)
: current;
Copy link
Member

Choose a reason for hiding this comment

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

I think this logic would benefit from having the explanation in the long comment above worked into it.

Probably that mostly means just moving that comment from reconcileMessages into this method. After all, it starts with:

What to do when some of the just-fetched messages are already known?

so it's entirely about this "present" case.

Beyond that, I think once the comment is here in this method, the "normally" vs. "with one exception" cases can be worked a bit into the corresponding cases in this code's control flow.

Copy link
Collaborator Author

@chrisbobbe chrisbobbe Oct 17, 2025

Choose a reason for hiding this comment

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

That makes a lot of sense, thanks!!

}
}

Message _reconcileWhenPresent(Message current, Message incoming) {
Copy link
Member

Choose a reason for hiding this comment

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

nit: maybe give these names that are a bit more semantic: like "reconcile known message" vs. "reconcile unknown message" (or "new" or "previously unknown"?)

: current;
}

Message _reconcileWhenAbsent(Message incoming) {
Copy link
Member

Choose a reason for hiding this comment

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

nit: maybe put the absent/unknown case first — it happens first chronologically, after all (except in the case of a message we learn about from an event), and it's also simpler, so I think conceptually prior

(can do the same at the call site too, thanks to Dart accepting named arguments before positional)

It's way more common to be using the app with subscribed channels
than unsubscribed channels, so we might as well test with subscribed
channels except where we specifically want to check behavior for
unsubscribed channels.
Like we did in the compose-box tests in the previous commit.
@chrisbobbe chrisbobbe force-pushed the pr-unsubscribed-channels-fourth-buggy-behavior branch from a9b4906 to 6f75b2b Compare October 17, 2025 21:13
@chrisbobbe
Copy link
Collaborator Author

Thanks for the review! Revision pushed.

@gnprice
Copy link
Member

gnprice commented Oct 18, 2025

Thanks! I think that revision is helpful.

Over to @rajveermalviya for normal maintainer-review.

Copy link
Member

@rajveermalviya rajveermalviya left a comment

Choose a reason for hiding this comment

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

Thanks @chrisbobbe! LGTM, and tests great.
Moving over to Greg's review.

@rajveermalviya rajveermalviya added integration review Added by maintainers when PR may be ready for integration and removed maintainer review PR ready for review by Zulip maintainers labels Oct 23, 2025
@rajveermalviya rajveermalviya removed their assignment Oct 23, 2025
@chrisbobbe
Copy link
Collaborator Author

Thanks for the review!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

integration review Added by maintainers when PR may be ready for integration

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants