Skip to content
This repository has been archived by the owner on Apr 26, 2024. It is now read-only.

Delete push actions on receipt #13834

Closed

Conversation

Fizzadar
Copy link
Contributor

@Fizzadar Fizzadar commented Sep 17, 2022

Further work on optimising push action processing. Now that the push actions table is regularly summarised moving to delete-on-receipt seems appropriate.

I've not touched any of the receipt handling code in the event push actions store, or deleting from event push summary, both of which might be good future improvements?

Signed off by Nick @ Beeper (@Fizzadar).

Pull Request Checklist

This matches the existing logic used in the push action processing, now
that event push actions is very regularly summarised the table should
be relatively lean and the delete low impact.
@Fizzadar Fizzadar marked this pull request as ready for review September 19, 2022 09:30
@Fizzadar Fizzadar requested a review from a team as a code owner September 19, 2022 09:30
@erikjohnston
Copy link
Member

Ah, alas we had to move away from this approach as on busy servers there was too much contention, resulting in lots of could not serialize access due to concurrent update errors (c.f. #13117)

@Fizzadar
Copy link
Contributor Author

@erikjohnston makes sense, although I was thinking for #13117 was that the contention is on the summary table rather than the push actions table?

Copy link
Contributor

@babolivier babolivier left a comment

Choose a reason for hiding this comment

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

The code lgtm, but I'd like to see a regression test for this (eg generating some push actions, sending a receipt and checking that the actions have been correctly deleted).

@Fizzadar
Copy link
Contributor Author

Test added in: ef04bc8, also caught a bug and added an additional test for that in 65b5bca.

@Fizzadar
Copy link
Contributor Author

Merged in develop to fixup the receipts test, complement still flaking though but unrelated 😬!

Copy link
Contributor

@babolivier babolivier left a comment

Choose a reason for hiding this comment

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

also caught a bug and added an additional test for that

Yay testing works 🎉

It looks pretty much good to me apart from a few bits of documentation. I'd also like @erikjohnston to have a look since it sounded like he had concern last week.

result = self.get_success(
self.store.db_pool.simple_select_list(
table="event_push_actions",
keyvalues={"1": 1},
Copy link
Contributor

Choose a reason for hiding this comment

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

You can also just set keyvalues to None which generates an SQL query with no WHERE clause

@@ -290,3 +290,76 @@ def test_get_last_receipt_event_id_for_user(self) -> None:
)
)
self.assertEqual(res, event2_1_id)

def test_receipts_clear_push_actions(self) -> None:
Copy link
Contributor

Choose a reason for hiding this comment

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

Could you add a docstring explaining what this test tests please? Same with the other test.

WHERE room_id = ?
AND user_id = ?
AND stream_ordering <= ?
AND highlight = 0
Copy link
Contributor

Choose a reason for hiding this comment

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

Could you add a comment explaining why we are special casing highlights here?

event_1_id = self.create_and_send_event(
self.room_id1,
UserID.from_string(OTHER_USER_ID),
content="our",
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
content="our",
content=UserID.from_string(OUR_USER_ID).localpart,

Bit more boilerplatey, but it makes it easier to understand what "our" is supposed to be here (and that it's not just a magic value we're not pulling out of nowhere).

Comment on lines 734 to 745
if stream_ordering is not None and receipt_type in (
ReceiptTypes.READ,
ReceiptTypes.READ_PRIVATE,
):
sql = """
DELETE FROM event_push_actions
WHERE room_id = ?
AND user_id = ?
AND stream_ordering <= ?
AND highlight = 0
"""
txn.execute(sql, (room_id, user_id, stream_ordering))
Copy link
Member

Choose a reason for hiding this comment

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

This query is incorrect if a thread_id is provided.

It should be something like:

Suggested change
if stream_ordering is not None and receipt_type in (
ReceiptTypes.READ,
ReceiptTypes.READ_PRIVATE,
):
sql = """
DELETE FROM event_push_actions
WHERE room_id = ?
AND user_id = ?
AND stream_ordering <= ?
AND highlight = 0
"""
txn.execute(sql, (room_id, user_id, stream_ordering))
if stream_ordering is not None and receipt_type in (
ReceiptTypes.READ,
ReceiptTypes.READ_PRIVATE,
):
args = [room_id, user_id, stream_ordering)
where_clause = ""
if thread_id is not None:
where_clause = "AND thread_id = ?"
args.append(thread_id)
sql = f"""
DELETE FROM event_push_actions
WHERE room_id = ?
AND user_id = ?
AND stream_ordering <= ?
AND highlight = 0
{threads_clause}
"""
txn.execute(sql, args)

Although I'm not really confident of the interaction between this change and #13776 or how this interacts with _remove_old_push_actions_that_have_rotated which is unchanged in this PR.

Copy link
Member

Choose a reason for hiding this comment

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

(Although right now we take this into account in #13878, not #13776)

@erikjohnston
Copy link
Member

@erikjohnston makes sense, although I was thinking for #13117 was that the contention is on the summary table rather than the push actions table?

Hmm, true. I'm struggling to reason about if this will suffer from a similar problem. Have you tried this on a busy server?

@erikjohnston erikjohnston removed their request for review October 12, 2022 09:23
@Fizzadar
Copy link
Contributor Author

Fizzadar commented Oct 20, 2022

Been distracted with other priorities the last few weeks! I am just rolling this (only the delete query) out to our synapse install now to confirm there isn't a contention issue on the delete.

Assuming that's the case I'll update for threads/etc and cleanup the rotation parts too.

@Fizzadar
Copy link
Contributor Author

Hm so the failing test here is a test that push a highlight action, which never gets cleared, but the test is selecting push actions over this time period (

http_actions = self.get_success(
).

Because they don't get deleted this means if a pusher fails for a bit once it recovers all highlight push actions will be notified, irrespective of read receipt position. The only way to maintain support for that situation is to check receipts at fetch time, so maybe there's no point in this 😩.

@Fizzadar
Copy link
Contributor Author

Based on my last comment about highlights also using the event_push_actions table I'm closing this as it's not going to remove any checks without moving highlights elsewhere which is a whole other thing (:

@Fizzadar Fizzadar closed this Dec 12, 2022
@Fizzadar Fizzadar deleted the delete-push-actions-on-receipt branch December 16, 2022 10:06
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants