Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add experimental server-side notification grouping #29889

Merged
merged 12 commits into from
Jun 3, 2024

Conversation

ClearlyClaire
Copy link
Contributor

@ClearlyClaire ClearlyClaire commented Apr 10, 2024

This PR adds a group_key attribute on the Notification model that is filled when creating the notification and is used to allow efficient pagination, fetching no more than one notification per group from the database.

It also adds an experimental API:

  • GET /api/v2_alpha/notifications
  • GET /api/v2_alpha/notifications/:group_key
  • POST /api/v2_alpha/notifications/:group_key/dismiss

This relies on a recursive CTE, which is currently not possible to write with stock ActiveRecord, and therefore relies on a couple monkey-patches:

These patches allow to write the CTE in a pretty readable fashion, and allowing the use of already-defined scopes. This can be used to build an API that returns a page of notifications with no more than one notification per group, and still returns a good number of groups, instead of having to call the notification API repeatedly to possibly get more than one group worth of notifications.

Caveats

  • while performance should be really good in most cases, large amounts of notifications within few groups will cause large amounts of rows to be filtered. This may cause performance issues. But it may also work well in practice. Needs more investigation.
  • because of the monkey-patches, this introduces a fairly high maintenance burden.
    That being said, one of the two patches has been merged upstream, and the other one is under consideration.

    EDIT: both patches have been adopted upstream, so we won't have a long-term maintenance burden
  • notification marker ID: we need to return the most recent notification of a page

@ClearlyClaire ClearlyClaire force-pushed the recursive-cte-grouped-notifications branch from b44af10 to 8259dfd Compare April 10, 2024 10:56
@ClearlyClaire ClearlyClaire changed the title Recursive cte grouped notifications Add server-side notification grouping Apr 10, 2024
@ClearlyClaire ClearlyClaire force-pushed the recursive-cte-grouped-notifications branch 5 times, most recently from 8b7f171 to ad2aebf Compare April 11, 2024 13:49
@ClearlyClaire ClearlyClaire force-pushed the recursive-cte-grouped-notifications branch from ad2aebf to 16374e4 Compare April 12, 2024 07:23
@ClearlyClaire
Copy link
Contributor Author

While this PR is still exploratory, this approach is promising. The Arel patch has been accepted into ActiveRecord, so the only monkey-patch left is the recursive CTE one.

On that topic, @lorint, I've used the code you published here to validate the approach, but I have to double-check whether you are ok for this to be included in Mastodon (AGPLv3) or Rails (MIT). Furthermore, are you interested in trying to get this feature merged upstream yourself, or do you prefer I try to do it?

@ClearlyClaire ClearlyClaire force-pushed the recursive-cte-grouped-notifications branch 6 times, most recently from 8e2ba0b to ee09aa6 Compare April 23, 2024 12:49
@ClearlyClaire ClearlyClaire force-pushed the recursive-cte-grouped-notifications branch from ee09aa6 to a50b871 Compare April 23, 2024 13:17
@ClearlyClaire ClearlyClaire changed the title Add server-side notification grouping Add experimental server-side notification grouping Apr 24, 2024
@ClearlyClaire ClearlyClaire marked this pull request as ready for review April 24, 2024 10:04
@ClearlyClaire
Copy link
Contributor Author

I think this is ready for review, with the understanding that the API is experimental for now (hence the /api/v2_alpha namespace) and will likely change before v4.3.0, so marked it as such.

cc @mjankowski if you can have a quick look at the implementation.

@mjankowski
Copy link
Contributor

Some questions before I get into any detailed code review...

  • Is the idea here that the /v1/notifications* endpoints continue to exist as-is, and these /v2/... are opt-in versions for getting grouped notification data? so depending on client need they can either stick with the existing one notification at a time approach or switch to new grouped approach?
  • I assume the intention with the namespace is to deploy this in sort of an alpha/preview mode and let clients test against live deployed api, and iterate from there?
  • Is there any existing client impl done in tandem to use for guidance here, or is this sort of a first pass at the API level in advance of that? It would be useful to see some (even crude) mocks or wireframes of the expected changing UX to contemplate.

@ClearlyClaire
Copy link
Contributor Author

  • Is the idea here that the /v1/notifications* endpoints continue to exist as-is, and these /v2/... are opt-in versions for getting grouped notification data? so depending on client need they can either stick with the existing one notification at a time approach or switch to new grouped approach?

Yes. We might discontinue /api/v1/notifications eventually, but this is not planned for now.

  • I assume the intention with the namespace is to deploy this in sort of an alpha/preview mode and let clients test against live deployed api, and iterate from there?

Yes.

  • Is there any existing client impl done in tandem to use for guidance here, or is this sort of a first pass at the API level in advance of that? It would be useful to see some (even crude) mocks or wireframes of the expected changing UX to contemplate.

The UI work has not started yet.

@mjankowski
Copy link
Contributor

Great, noted on API preview expectations and migration path.

The lack of UI work makes it sort of challenging to review the approach, since there's not a use case or design to support it seems a little speculative, rather than emerging from a need of a feature? If we're doing alpha/preview just to put actual endpoints up for clients to experiment with ... could we literally just hardcode some JSON showing the proposed new response, and get feedback from client devs? Or if there's internal WIP for the web client, leave this in draft until that's further along?

app/serializers/rest/notification_group_serializer.rb Outdated Show resolved Hide resolved
app/serializers/rest/notification_group_serializer.rb Outdated Show resolved Hide resolved
@ClearlyClaire ClearlyClaire force-pushed the recursive-cte-grouped-notifications branch from ee0d1e1 to 5a8f729 Compare May 28, 2024 07:44
Copy link
Contributor

This pull request has merge conflicts that must be resolved before it can be merged.

Copy link
Contributor

This pull request has resolved merge conflicts and is ready for review.

renchap
renchap previously approved these changes May 29, 2024
Copy link
Sponsor Member

@renchap renchap left a comment

Choose a reason for hiding this comment

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

I am fine with merging this.

The database side should not change now, and the API is marked as experimental, so I do not expect problems deploying it.

We can change the API in further PRs until we mark it as stable if needed, and having it merged will make working on the frontend implementation much easier and less prone to rebase issues.

@ClearlyClaire
Copy link
Contributor Author

@mjankowski I marked your conversations as resolved in order to move forward, but there's a couple refactors that may still be worth exploring:

  • moving the notification_group_key logic from NotifyService to the Notification class
  • refactor pagination tests to use named variables (but this requires fighting rubocop)

@ClearlyClaire ClearlyClaire added this pull request to the merge queue Jun 3, 2024
Merged via the queue into main with commit 974335e Jun 3, 2024
51 checks passed
@ClearlyClaire ClearlyClaire deleted the recursive-cte-grouped-notifications branch June 3, 2024 08:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants