RAS-1867 Re-implement My Messages to make query more performant#472
RAS-1867 Re-implement My Messages to make query more performant#472LJBabbage wants to merge 5 commits into
Conversation
|
|
||
| for message in paginated_list.items: | ||
| msg = message.serialize(user, body_summary=body_summary) | ||
| msg["_links"] = {"self": {"href": f"{host_url}{MESSAGE_BY_ID_ENDPOINT}/{msg['msg_id']}"}} |
There was a problem hiding this comment.
This isn't used so removed
| "self": {"href": f"{host_url}{endpoint}?{string_query_args}&page={message_args.page}"}, | ||
| } | ||
|
|
||
| if paginated_list.has_next: |
There was a problem hiding this comment.
As above this isn't used
| "subject": self.subject, | ||
| "body": self.body[:100] if body_summary else self.body, | ||
| "thread_id": self.thread_id, | ||
| "case_id": self.case_id, |
|
|
||
| @staticmethod | ||
| def thread_count_by_survey(request_args, user): | ||
| """Count users threads for a specific survey""" |
There was a problem hiding this comment.
merged with results to stop drift in the future and make more maintainable
| self.assertEqual(len(response), 1) | ||
|
|
||
| self.assertEqual(len(response.items), 1) | ||
| def test_thread_list_no_message(self): |
There was a problem hiding this comment.
Not related to this PR, but added line coverage
| "from_internal": self.from_internal, | ||
| "sent_date": str(self.sent_at), | ||
| "read_date": str(self.read_at), | ||
| "_links": "", |
| ) | ||
|
|
||
| logger.info("Successfully retrieved threads for user", user_uuid=g.user.user_uuid) | ||
| messages, links = process_paginated_list(result, request.host_url, g.user, message_args, THREAD_LIST_ENDPOINT) |
There was a problem hiding this comment.
I've split the internal and external respondent process up, so this is done else where
| @@ -1,8 +0,0 @@ | |||
| from behave import given, when | |||
| @@ -1,8 +0,0 @@ | |||
| from behave import given, when | |||
| Then the thread count is '0' threads | ||
|
|
||
|
|
||
| Scenario: Respondent sends messages to different ce, internal user filters by ce |
There was a problem hiding this comment.
We don't offer the ability to filter on these criteria https://github.com/ONSdigital/response-operations-ui/blob/main/response_operations_ui/controllers/message_controllers.py#L129 and never have so I removed it in the code and naturally the test here. Frontstage only allows filtering is_closed
| | specific user | | ||
| | group | | ||
|
|
||
| Scenario Outline: There are 3 conversations between an internal user and respondent each with 2 messages , |
There was a problem hiding this comment.
As above we don't have this functionality in rops
| if messages: | ||
| messages = add_users_and_business_details(messages) | ||
| return jsonify({"messages": messages, "_links": links}) | ||
| return jsonify({"messages": messages}) |
There was a problem hiding this comment.
_links isn't used at all in rops or frontstage, so it and all code associated with it can be removed. Rops doesn't even mock it in tests, frontstage does, which has now been removed without any effect.
|
/deploy wilkia |
|
Deploying to dev cluster with following parameters:
|
| args = get_args(new_respondent_conversations=True) | ||
| response = Retriever.retrieve_thread_list(self.user_internal, args) | ||
| self.assertEqual(len(response), 1) | ||
| self.assertEqual(response[0]["labels"], ["INBOX", "UNREAD"]) |
There was a problem hiding this comment.
Should this also include the "SENT" label?
There was a problem hiding this comment.
Sent is only associated with a ROPS user i believe, the assert is also only proving what I set above is coming back. The irony is that the system only cares about UNREAD (to highlight) and not the others, but I didn't want to unpick it at this juncture
There was a problem hiding this comment.
When i tested it SENT is getting attached to a respondent and a Rops user but I wasn't sure how the labels were actually being used. I did think that maybe they weren't all used when they returned to Rops/frontstage so that makes sense if it is just UNREAD. It's working the same on the PR as on main so no issues with it.
Respondent creates a new thread:
SENT <respondent_uuid>
INBOX GROUP
UNREAD GROUP
Rops creates a new thread:
SENT <rops_user_uuid>
INBOX <respondent_uuid>
UNREAD <respondent_uuid>
| """ | ||
|
|
||
| PAGINATION_SQL = """ | ||
| ORDER BY sm.msg_id, sm.id DESC |
There was a problem hiding this comment.
The my messages tab is displaying the messages in sent_at DESC in the current implementation
matthew-robinson-ons
left a comment
There was a problem hiding this comment.
Tested multiple message scenarios. Labels are consistently displayed as before, attaching to the correct actor. Messages move in and out of my messages as before based on which internal user replied most recently. It's hard to comment on the performance of the queries without having anything to compare it against, we only really have that information in PROD currently.
The pagination object is displaying the messages on the page in a different order, previously it was showing the most recent (last sent) messages first.
What and why?
This PR improves performance for internal thread retrieval (
My Messages), removes unused functionality, rationalises the query logic, and adds coverage for previously untested paths.Performance
Before
When the
My Messagestab was selected, we queried thesecure_messagetable first and performed operations such as determining the latest message before joining to thestatustable, without index.This resulted in unnecessary scanning and processing of large datasets before pagination was applied, causing poor performance for users with a high message volume.
Now
The query flow has been reversed for internal users using my_messages:
statustable first using actor-based filterssecure_messageusing the indexedmsg_idLIMITandOFFSETare used to paginate efficiently at the database levelAdditional changes
How to test
Deploy this branch and test a variety of thread and filtering scenarios. Suggested checks:
My MessagesMy MessagesJira