App icon indicating copy to clipboard operation
App copied to clipboard

HIGH: [Performance] [$500] Reliably unsubscribe from isTyping events when leaving rooms

Open quinthar opened this issue 1 year ago • 12 comments

Problem:

When you join a room, you subscribe to various Pusher channels that should only be active while in that room. However, when you leave the room, sometimes it doesn't unsubscribe you from the channels. This "leak" will gradually slow down the app. But particularly concerning is that it will cause you to receive Pusher events that do not relate to the current room (such as "istyping" events in rooms you aren't looking at), and thus drag down your performance.

Solution:

Reliably unsubscribe from the room's Pusher channel when leaving by any method. There is a theory that we do this when leaving a room to switch to another, but perhaps not when leaving the room to go to a non-room page (eg, Settings).

See: https://expensify.slack.com/archives/C049HHMV9SM/p1711131919203929

Upwork Automation - Do Not Edit
  • Upwork Job URL: https://www.upwork.com/jobs/~012a36c87d591ea59b
  • Upwork Job ID: 1773645194916745216
  • Last Price Increase: 2024-03-29

quinthar avatar Mar 25 '24 01:03 quinthar

Auto-assigning issues to engineers is no longer supported. If you think this issue should receive engineering attention, please raise it in #whatsnext.

melvin-bot[bot] avatar Mar 25 '24 01:03 melvin-bot[bot]

Triggered auto assignment to @dylanexpensify (Bug), see https://stackoverflow.com/c/expensify/questions/14418 for more details.

melvin-bot[bot] avatar Mar 25 '24 14:03 melvin-bot[bot]

Nice! @quinthar is this something we wanna get a contributor on?

dylanexpensify avatar Mar 26 '24 10:03 dylanexpensify

yes please!

quinthar avatar Mar 29 '24 02:03 quinthar

Job added to Upwork: https://www.upwork.com/jobs/~012a36c87d591ea59b

melvin-bot[bot] avatar Mar 29 '24 09:03 melvin-bot[bot]

Triggered auto assignment to Contributor-plus team member for initial proposal review - @jjcoffee (External)

melvin-bot[bot] avatar Mar 29 '24 09:03 melvin-bot[bot]

Let's get it!

dylanexpensify avatar Mar 29 '24 09:03 dylanexpensify

Proposal

Please re-state the problem that we are trying to solve in this issue.

We need to unsubscribe from isTyping events when leaving rooms.

What is the root cause of that problem?

Pusher remains subscribed even after leaving the room.

What changes do you think we should make in order to solve the problem?

In ReportActionsView.ts, we are calling Report.subscribeToReportTypingEvents(reportID);.

We can call the below to unsubscribe in a useEffect when component unmounts:

// Unsubscribe from Pusher events when component unmounts
return () => {
    Report.unsubscribeFromReportTypingEvents(reportID);
};

ShridharGoel avatar Mar 29 '24 09:03 ShridharGoel

Proposal

Please re-state the problem that we are trying to solve in this issue.

When you join a room, you subscribe to various Pusher channels that should only be active while in that room. However, when you leave the room, sometimes it doesn't unsubscribe you from the channels. This "leak" will gradually slow down the app.

What is the root cause of that problem?

In here, we already have the logic to unsubscribe from the isTyping event. However this only happens when the report screen is unmounted, it won't happen if the report screen simply loses focus (is no longer the topmost report)

What changes do you think we should make in order to solve the problem?

We need to unsubscribe from report channel if the screen loses focus, and the reportId is no longer the topmostReportId.

Then we'll resubscribe if the report screen gains focus.

We might want to do it in ReportActionsView because that's where we're subscribing to the event, but moving both to ReportActionsList is also fine.

Pseudo-code (to replace this event subscription logic, some more polishing might be needed)

useEffect(() => {
       if (route?.params?.reportID !== reportID) {
           return;
       }
       
       if (isFocused) {
           const didCreateReportSuccessfully = !report.pendingFields || (!report.pendingFields.addWorkspaceRoom && !report.pendingFields.createChat);
           
           if (!didSubscribeToReportTypingEvents.current && didCreateReportSuccessfully) {
               const interactionTask = InteractionManager.runAfterInteractions(() => {
                   Report.subscribeToReportTypingEvents(reportID);
                   didSubscribeToReportTypingEvents.current = true;
               });
               return () => {
                   interactionTask.cancel();
               };
           }
       } else {
           const topmostReportId = Navigation.getTopmostReportId();

           if (topmostReportId !== report.reportID && didSubscribeToReportTypingEvents.current) {
               didSubscribeToReportTypingEvents.current = false;
               InteractionManager.runAfterInteractions(() => {
                   Report.unsubscribeFromReportChannel(report.reportID);
               });
           }
       }
   }, [isFocused, report.reportID, report.pendingFields, didSubscribeToReportTypingEvents, route, reportID, prevIsFocused]);

Then we can remove the existing unsubscription logic here

What alternative solutions did you explore? (Optional)

NA

tienifr avatar Mar 29 '24 11:03 tienifr

I like the sound of @tienifr's proposal! The RCA looks to be correct, since we already unsubscribe on unmount (which is why it only sometimes sends the isTyping events). The solution also seems decent from a quick test run, e.g. navigating to the settings page correctly unsubscribes, whereas opening the room details modal does not unsubscribe (so you'd still see the ... is typing messages in the background).

@ShridharGoel's proposal is lacking an RCA and generally in details, for example the solution refers to a non-existent method unsubscribeFromReportTypingEvents and details of where code changes are being proposed to be made are missing. I recommend working on fleshing out your proposals with plenty of detail for the future. Best of luck!

:ribbon::eyes::ribbon: C+ reviewed

jjcoffee avatar Mar 29 '24 14:03 jjcoffee

Triggered auto assignment to @Beamanator, see https://stackoverflow.com/c/expensify/questions/7972 for more details.

melvin-bot[bot] avatar Mar 29 '24 14:03 melvin-bot[bot]

Hi! What's the ETA on assigning this out?

quinthar avatar Mar 30 '24 06:03 quinthar

Yo yo! I'm planning to review the review tomorrow, so should be able to get someone assigned early 👍

Beamanator avatar Mar 31 '24 14:03 Beamanator

📣 @jjcoffee 🎉 An offer has been automatically sent to your Upwork account for the Reviewer role 🎉 Thanks for contributing to the Expensify app!

Offer link Upwork job

melvin-bot[bot] avatar Mar 31 '24 20:03 melvin-bot[bot]

📣 @tienifr 🎉 An offer has been automatically sent to your Upwork account for the Contributor role 🎉 Thanks for contributing to the Expensify app!

Offer link Upwork job Please accept the offer and leave a comment on the Github issue letting us know when we can expect a PR to be ready for review 🧑‍💻 Keep in mind: Code of Conduct | Contributing 📖

melvin-bot[bot] avatar Mar 31 '24 20:03 melvin-bot[bot]

I like @tienifr 's proposal as well so let's move forward!

Beamanator avatar Mar 31 '24 20:03 Beamanator

@jjcoffee PR https://github.com/Expensify/App/pull/39347 is ready to review

tienifr avatar Apr 01 '24 11:04 tienifr

There are a couple of extra cases I've found that we need to handle on the PR. Waiting on @tienifr to look into it :pray:

jjcoffee avatar Apr 01 '24 14:04 jjcoffee

@jjcoffee do you mean taht @tienifr should re-review? @tienifr can you please do this today, or what's your ETA?

quinthar avatar Apr 02 '24 23:04 quinthar

@quinthar There is a case we need the confirmation from internal team. Asked here

tienifr avatar Apr 03 '24 00:04 tienifr

Issue not reproducible during KI retests. (First week)

mvtglobally avatar Apr 04 '24 03:04 mvtglobally

@tienifr - I see @Beamanator responded. What are the next steps, and your ETA?

quinthar avatar Apr 04 '24 21:04 quinthar

@quinthar I updated the PR (See comment).

tienifr avatar Apr 04 '24 23:04 tienifr

It is delayed because I need time to check if the new changes work and do not cause errors.

tienifr avatar Apr 04 '24 23:04 tienifr

What's the update here?

quinthar avatar Apr 17 '24 18:04 quinthar

oh I see it's merged!

quinthar avatar Apr 17 '24 18:04 quinthar

Yes sorry for not updating here! Was merged 3 days ago, on staging as of 7 hours ago 🙏 🚀

Beamanator avatar Apr 18 '24 12:04 Beamanator

Can we close this?

quinthar avatar Apr 25 '24 02:04 quinthar

Hmm this has been in prod for only 3 days now, so i don't believe we should close - we normally wait 7 days before payment & before considering the PR having caused no regressions

Beamanator avatar Apr 25 '24 08:04 Beamanator

Should this be tagged Awaiting Payment then?

quinthar avatar Apr 27 '24 19:04 quinthar