Closed quinthar closed 4 months ago
Job added to Upwork: https://www.upwork.com/jobs/~01856d1399295ef760
Triggered auto assignment to Contributor-plus team member for initial proposal review - @cubuspl42 (External
)
Hey Iβm going to investigate why the payload is so big in Onyx storage. Possibly track what change exactly caused the problem. Then either revert that piece of change or use one of suggestions by @thienlnam
Contributor details Your Expensify account email: maxim.grin@gmail.com Upwork Profile Link: https://www.upwork.com/freelancers/~01fb7b172c01252917
π£ @maxim-grin! π£ Hey, it seems we donβt have your contributor details yet! You'll only have to do this once, and this is how we'll hire you on Upwork. Please follow these steps:
Contributor details
Your Expensify account email: <REPLACE EMAIL HERE>
Upwork Profile Link: <REPLACE LINK HERE>
Hey Iβm going to investigate why the payload is so big in Onyx storage. Possibly track what change exactly caused the problem. Then either revert that piece of change or use one of suggestions by @thienlnam
Contributor details Your Expensify account email: maxim.grin@gmail.com Upwork Profile Link: https://www.upwork.com/freelancers/~01fb7b172c01252917
β Contributor details stored successfully. Thank you for contributing to Expensify!
We don't need to use text
from reportAction, it would be better to use originalMessage.html.
New change.
text
from message in reportAction is being used at multiple places.
We have text defined here:
Example usage:
We can change this to:
const parser = new ExpensiMark();
const actionMessage = parser.htmlToText(action.message?.[0]?.html ?? '');
Add the above in a common method getActionMessagePostParsing
in ReportUtils.
Similarly, check all usages and update them to use the method mentioned above.
Finally, we can remove text
.
There's one instance of originalMessage?.html
in ReportUtils.ts which also needs to be updated to use the common method.
if (ReportActionsUtils.isWhisperAction(reportAction)) {
// Allow flagging welcome message whispers as they can be set by any room creator
if (report?.description && !isCurrentUserAction && isOriginalMessageHaveHtml && `getActionMessagePostParsing(reportAction)` === report.description) {
return true;
}
// Disallow flagging the rest of whisper as they are sent by us
return false;
}
We want to remove the usage of text
of reportAction
in the payload sent to client side.
And also changes how we're using message.html
This is new feature request.
html
:
function getReportActionHtml(reportAction: OnyxEntry<ReportAction>) {
return reportAction?.message?.html || reportAction?.message?.[0]?.html;
}
function getReportActionText(reportAction: OnyxEntry
2. > Update every instance of originalMessage.html to use message.html || message[0].html
In [here](https://github.com/Expensify/App/blob/4e13dada426c067e2945fbd2bd06ddd73c0b8409/src/libs/ReportUtils.ts#L4618), replace `reportAction?.originalMessage?.html` by `getReportActionHtml(reportAction)`
3. > Update every instance of message.text to dynamically strip the text from message.html || message[0].html
There're some places that are using `message?.[0]?.text`, examples: [here](https://github.com/Expensify/App/blob/4e13dada426c067e2945fbd2bd06ddd73c0b8409/src/libs/ReportUtils.ts#L2877), [here](https://github.com/Expensify/App/blob/4e13dada426c067e2945fbd2bd06ddd73c0b8409/src/libs/actions/Report.ts#L853), [here](https://github.com/Expensify/App/blob/4e13dada426c067e2945fbd2bd06ddd73c0b8409/src/libs/actions/Report.ts#L1523), ... (There're more)
We can replace them by `getReportActionText(reportAction)`.
4. > Phase 3 (External / clientside): Remove checking for "array message"
After phase 2 is done, we can just change the implementation of `getReportActionHtml` to
function getReportActionHtml(reportAction: OnyxEntry
5. There're other places that use `originalMessage`, but not its `html` field, like [here](https://github.com/Expensify/App/blob/4e13dada426c067e2945fbd2bd06ddd73c0b8409/src/libs/ReportActionsUtils.ts#L777)
We might need to replace them with `getReportActionMessage(reportAction)`
Where `getReportActionMessage` will be the following:
function getReportActionMessage(reportAction: OnyxEntry
To be compatible with both current format of `message` (as array) and new message format later (single item). The `reportAction?.message?.[0]` part can be removed after Phase 2 is done.
### What alternative solutions did you explore? (Optional)
NA
<!---
ATTN: Contributor+
You are the first line of defense in making sure every proposal has a clear and easily understood problem with a "root cause". Do not approve any proposals that lack a satisfying explanation to the first two prompts. It is CRITICALLY important that we understand the root cause at a minimum even if the solution doesn't directly address it. When we avoid this step we can end up solving the wrong problems entirely or just writing hacks and workarounds.
Instructions for how to review a proposal:
1. Address each contributor proposal one at a time and address each part of the question one at a time e.g. if a solution looks acceptable, but the stated problem is not clear then you should provide feedback and make suggestions to improve each prompt before moving on to the next. Avoid responding to all sections of a proposal at once. Move from one question to the next each time asking the contributor to "Please update your original proposal and tag me again when it's ready for review".
2. Limit excessive conversation and moderate issues to keep them on track. If someone is doing any of the following things please kindly and humbly course-correct them:
- Posting PRs.
- Posting large multi-line diffs (this is basically a PR).
- Skipping any of the required questions.
- Not using the proposal template at all.
- Suggesting that an existing issue is related to the current issue before a problem or root cause has been established.
- Excessively wordy explanations.
3. Choose the first proposal that has a reasonable answer to all the required questions.
-->
@ShridharGoel
Similarly, check all usages and update them
Are you saying to literally repeat this code snippet in all places? Couldn't we refactor the code to avoid this repetition?
As the scope of the issue is well-defined and rather narrow, I believe this part of the plan can be a part of the proposal.
@nkdengineer
Aren't you quoting browser-specific local notifications code? π€ As I understand it, the ultimate goal is to optimize the payload size of remote push notifications.
Aren't you quoting browser-specific local notifications code? π€ As I understand it, the ultimate goal is to optimize the payload size of remote push notifications.
@cubuspl42 In the OP it's mentioned
@thienlnam thinks we added
text
for notifications
So I'm quoting the place that we're showing notification based on text
, so it's clear where it's used.
It's only 1 part of the proposal though, what do you think about the rest of my proposal?
Are you saying to literally repeat this code snippet in all places? Couldn't we refactor the code to avoid this repetition?
@cubuspl42 My alternative solution achieves this
Updated. @cubuspl42 We can add a method in ReportUtils, updated the proposal.
@quinthar
Would you summarize the Expensify notifications architecture in a few sentences so that we can be more confident with proposal preparation and review?
As I understand that most (if not all?) notification processing on mobile Native is server-side (push-based), and we're talking about optimizing the pushed payload size. But I'm not 100% confident how that relates to the Onyx schema.
Also, there were some doubts about the scope...
I'm assuming here that we're only omitting the text from reportActions in urban airship native updates, if we're going to remove text in Pusher update too, then we need to populate the text in the Pusher report actions updates by htmlToText.
Would you clarify this too? My intuition was that we wanted to nuke all usage of the text
property client-side, also removing it from the typing. But it would be good to be sure about it.
Great question. I've updated the original post with a more detailed description of the problem and solutions. Thanks!
Updated the proposal again (sorry!!!) in light of message
being in this weird one-element array. Thanks for your understanding and help in cleaning up this mess!
Proposal updated after latest requirements update
@nkdengineer I think your proposal shows more preparation. How is your capacity, though? Would you be able to start working on this within 24-48 hours?
Would you be able to start working on this within 24-48 hours?
@cubuspl42 Yes, I definitely can
I approve the proposal by @nkdengineer
C+ reviewed π π π
Triggered auto assignment to @thienlnam, see https://stackoverflow.com/c/expensify/questions/7972 for more details.
π£ @cubuspl42 π An offer has been automatically sent to your Upwork account for the Reviewer role π Thanks for contributing to the Expensify app!
π£ @nkdengineer You have been assigned to this job! Please apply to the Upwork job and leave a comment on the Github issue letting us know when we can expect a PR to be ready for review π§βπ» Once you apply to this job, your Upwork ID will be stored and you will be automatically hired for future jobs! Keep in mind: Code of Conduct | Contributing π
@thienlnam Hi! I see this is a HIGH
priority issue so it should start at $500 (from the announcement here)
While bugs/feature requests will now start at $250, any that are deemed Critical or High to our roadmap (noted via the label
High Priority
) will automatically be updated to $500. This is to ensure we get the necessary attention and urgency applied to these issues.
Perhaps the automation did not work well in this case.
If that's right, could you help to adjust the bounty here, thanks π
Hm, it's likely because the issue is missing the "High priority" label. But I'm not sure if the "HIGH:" prefix and the "High priority" label represent the same concept π€
We already have a draft PR here to fix things in phase 1, @thienlnam please let me know when phase 2 is completed on the server side, I will then update phase 3 accordingly. Cc @cubuspl42
Great work! What's your ETA for submitting the PR for review?
I will open PR tomorrow
@nkdengineer Just so we're on the same page, phase 1 must be deployed to production first. Also, some time has to pass, so Native users have the time to update. So we're not blocked by phase 2 in any way.
@cubuspl42 The PR is here.
Great! @cubuspl42 what is your ETA for review?
I'm on it π
Great, what is your ETA for review?
It was yesterday. I raised concerns about whether we actually covered the whole scope of the Phase 1. I even pinged you π We can continue the dialogue on the PR.
Triggered auto assignment to Contributor Plus for review of internal employee PR - @parasharrajat (Internal
)
@parasharrajat reassigning, please take over as C+. If you don't have bandwidth, unassign yourself. Thanks. PR is
Sorry, I don't have the bandwidth to work on this. I was OOO since Thursday. let me request someone to push this forward.
@c3024 will review this.
Thanks @parasharrajat , π @c3024 @c3024 commented on the PR earlier today
This issue has not been updated in over 15 days. @thienlnam, @c3024, @nkdengineer eroding to Monthly issue.
P.S. Is everyone reading this sure this is really a near-term priority? Be brave: if you disagree, go ahead and close it out. If someone disagrees, they'll reopen it, and if they don't: one less thing to do!
@c3024 looks like the PR is awaiting an action from you
@thienlnam @quinthar
The issue talks about only text
and html
Phase 1 (External / clientside): Stop using originalMessage, start using array-message Update every instance of originalMessage.html to use message.html || message[0].html Update every instance of message.text to dynamically strip the text from message.html || message[0].html
but originalMessage
has many more fields like reason
, resolution
, IOUTransactionID
, events
, oldName
, newName
, participantAccountIDs
, etc. which are not present in message
. So this phase 1 should be to update every instance of originalMessage
(not just fields of html
or text
) with array message
Also in phase 2
Phase 2 (Internal / serverside): Once we've confirmed the client no longer uses originalMessage or message.text: Stop sending originalMessage Start sending message without an array
message
should be sent including all the above mentioned other fields to completely deprecate originalMessage
.
Can you please update phase 1 and 2 of the issue description to include these?
Triggered auto assignment to @puneetlath (Bug
), see https://stackoverflow.com/c/expensify/questions/14418 for more details. Please add this bug to a GH project, as outlined in the SO.
Added Bug
to assign a BZ. @quinthar @thienlnam , can you address @c3024 's request above when you have a min
https://github.com/Expensify/App/issues/39797#issuecomment-2130753109
I've updated the description
I did some exploratory work on this topic in https://github.com/Expensify/App/pull/41872 - maybe useful for you @nkdengineer @c3024 @thienlnam.
The main idea is that we make ReportAction
take a generic param for the type, and that determines the originalMessage
it will have. This helps ensure that we correctly and safely narrow the ReportAction type to ensure the originalMessage is as we expect before trying to access any of its properties
self-assigning as I've been pulled into the PR for review
@puneetlath, @thienlnam, @roryabraham, @c3024, @nkdengineer Whoops! This issue is 2 days overdue. Let's get this updated quick!
@puneetlath, @thienlnam, @roryabraham, @c3024, @nkdengineer Huh... This is 4 days overdue. Who can take care of this?
@puneetlath, @thienlnam, @roryabraham, @c3024, @nkdengineer Now this issue is 8 days overdue. Are you sure this should be a Daily? Feel free to change it!
@nkdengineer @c3024 how is this going? Are we almost done?
Problem:
Each comment in the server database is stored in
reportAction.message
in HTML form. However, for some reason lost to time, when we send that same comment out as an Onyx update, we:reportAction.originalMessage
in the update (which is confusing)message
object that contains a copy of thehtml
message, as well as a strippedtext
version.message
object inside a totally unnecessary one-element arrayThat means every comment is actually sent out three times (four, if you include the update to the
report
object, but that's out of scope for now). This is clearly wasteful in a number of ways:Additionally, it's particularly problematic when sending Onyx updates out via UrbanAirship, which is extremely limited in the payload sizes allowed -- with anything over a certain limit just dropped quietly and never delivered, causing "gaps" in our update stream (which require more network calls to "backfill" the Onyx data on app open, which makes things slow). Basically, this was just a mistake introduced for reasons we can't remember, but that we want to undo.
Solution:
To solve this, please:
originalMessage
, start using array-message
originalMessage.html
to usemessage.html || message[0].html
message.text
to dynamically strip the text frommessage.html || message[0].html
originalMessage
ormessage.text
or any other key within originalMessage:originalMessage
message
without an arrayThis issue is for phase 1 and phase 3.
Upwork Automation - Do Not Edit
Issue Owner
Current Issue Owner: @puneetlath