Fix conversations API #1039

Merged
Oneric merged 19 commits from Oneric/akkoma:fix-conv-api into develop 2026-01-11 15:54:51 +00:00
Owner

See AkkomaGang/akkoma-fe#470 for reference

Mainly the pagination patch is unfinished.
However, I’m considering changing the approach. Maintaining a "proper" foreign key references for last_status_id such that we can actually use it later for displaying in results is tricky since we need to consider whether users are eligible to view the referenced post. When a new post comes in this is relatively straightforward and more or less already dealt with in the existing update logic.
Before the patch there was no logic to roll back the updated at state when a post was deleted (and in the current revision the logic is still incomplete), but this is still doable.
The real issue arises when after the field was updated a user loses the access rights via e.g. an unfollow¹. Effectively we’ll have to check user access perms at time of rendering the convo response and requery the context for a fallback if the rights were lost.
Then we also can't fully rely on post creation/deletion updates to clean up empty/dead participations and conversations.

If we need to requery this at rendering time and do extra deletion/cleanup passes anyway, we might as well simplify it and have just a last_activity_at field, which gets filled out with activity ids when new ones come in, but isn’t bound to the activity continuing to exist. Basically, just a timestamp-like field similar to updated_at, just safer against spurious bumps and usable in pagiantion parameters.

I’m also no longer sure whether changing the semantics of accounts to match Mastodon is a good idea — at least not without some surveying of clients and coordination with Pleroma first. While docs claim(ed) something else, in practice this field has been the only way to access manually managed recipients in Akkoma and Pleroma, so changing it might break existing clients if any actually use the recipient management feature.
Nonetheless, a commit changing this as initially proposed is done (sans adding tests) and included here. Might be removed before merge though.
The WIP patch for this is attached to this post.


[1]: currently the update logic only acts on DMs and ignores messages of other visibilities in the same thread. Whether deletes are allowed to roll back to other visibilities is not yet determined. Since we do not allow changing recipients (as in their AP IDs) in post edits this will not actually happen atm if we restrict this to only DMs.
However, (a) this seems brittle and likely to backfire in the future and (b) it’s not clear to me whether it’s actually desirable to limit this to DMs only. On IRC the desire to "follow" regular, non-DM conversations was expressed which would require lifting this limitation (for updates of existing participations, implicit creations should retain this).

See https://akkoma.dev/AkkomaGang/akkoma-fe/pulls/470 for reference Mainly the pagination patch is unfinished. However, I’m considering changing the approach. Maintaining a "proper" foreign key references for last_status_id such that we can actually use it later for displaying in results is tricky since we need to consider whether users are eligible to view the referenced post. When a new post comes in this is relatively straightforward and more or less already dealt with in the existing update logic. Before the patch there was no logic to roll back the updated at state when a post was deleted *(and in the current revision the logic is still incomplete)*, but this is still doable. The real issue arises when after the field was updated a user loses the access rights via e.g. an unfollow¹. Effectively we’ll have to check user access perms at time of rendering the convo response and requery the context for a fallback if the rights were lost. Then we also can't fully rely on post creation/deletion updates to clean up empty/dead participations and conversations. If we need to requery this at rendering time and do extra deletion/cleanup passes anyway, we might as well simplify it and have just a `last_activity_at` field, which gets filled out with activity ids when new ones come in, but isn’t bound to the activity continuing to exist. Basically, just a timestamp-like field similar to `updated_at`, just safer against spurious bumps and usable in pagiantion parameters. I’m also no longer sure whether changing the semantics of `accounts` to match Mastodon is a good idea — at least not without some surveying of clients and coordination with Pleroma first. While docs claim(ed) something else, in practice this field has been the only way to access manually managed recipients in Akkoma [and Pleroma](https://git.pleroma.social/pleroma/pleroma/-/blob/d6888e24e48b2333db43cc7299427ab61e0ed3c3/lib/pleroma/web/mastodon_api/views/conversation_view.ex#L48), so changing it might break existing clients if any actually use the recipient management feature. Nonetheless, a commit changing this as initially proposed is done *(sans adding tests)* and included here. Might be removed before merge though. The WIP patch for this is attached to this post. --- **[1]:** currently the update logic only acts on DMs and ignores messages of other visibilities in the same thread. Whether deletes are allowed to roll back to other visibilities is not yet determined. Since we do not allow changing recipients *(as in their AP IDs)* in post edits this will not actually happen atm if we restrict this to only DMs. However, (a) this seems brittle and likely to backfire in the future and (b) it’s not clear to me whether it’s actually _desirable_ to limit this to DMs only. On IRC the desire to "follow" regular, non-DM conversations was expressed which would require lifting this limitation *(for updates of existing participations, implicit creations should retain this)*.
Presorting the index will speed up all context queries
and avoids having to load the full context before sorting
and limiting can even start.
This is relevant when get the context of a status
and for dm conversation timelines.

Including the id column adds to the index size,
but dropping non-Creates also brings it down again
for an overall only moderate size increase.
The speedup when querying large threads/conversations
is worth it either way.

Otherwise, the context attribute is only used as a condition in
queries related to notifications, but only to filter an otherwise
pre-selected set of notifications and this index will not be relevant.
Redundant with unread_count/1 and only the latter is actually used
TODO:
  - update docs
  - add tests for accounts and pleroma.recipients update behaviour
[WIP] api/masto/conversations: paginate by last status id
Some checks failed
ci/woodpecker/pr/test/2 Pipeline failed
ci/woodpecker/pr/test/1 Pipeline failed
94b9855c9f
The old pagination logic was inconsistent and thus broken.
It used to order conversations based on updated_at but used
participation IDs as pagination parameters in link headers.
Thus entreis could repeat or be left out entirely.

Notably using updated_at also lead to bumps when
merely marking an individual conversation as read,
though not when marking _all_ conversations as read in bulk
since Repo.update_all does not touch date fields autoamtically.

For consitent and sensible "last active" ordering this is replaced
by using the flake ID (which contains the date) of the newest status
in a conversation for both ordering and pagination parameters.

Logically last_status is shared across all "participations" of the same
conversation (context). However, querying ones own "newest"
conversations is expected to be a frequent operation and thus must
perform well and in bounded time.
With filter criteria (user id) in the particpation table and
ordering criteria (last_status_id) in the conversation table
it is not possible to create one, pre-sorted index encompassing both.

With a pre-sorted last_status_id index in conversations queries will
still have to traverse entries of all other users when collecting
results which scales poorly with instance size and is always problematic
for infrequently active users. Notably the old updated_at index suffered
from this same issue despite bot criteria being in the same table simply
because it was not taken into account when creating the index.

With just an index for user ids in participation a query will need to
load _all_ participations of this user before sorting them and
afterwards applying limits. This is obviously bad.

Thus last_status_id is tracked / duplicated in participation rather than
conversations. On the upside, this enables us to apply user-specific
filters here in the future, like not updating the field if the newest
message is affected by mutes if this should seem desirable. For now
though this is simply updated indiscriminately and only "seen" is
selective, just as before the change.
Oneric force-pushed fix-conv-api from 94b9855c9f
Some checks failed
ci/woodpecker/pr/test/2 Pipeline failed
ci/woodpecker/pr/test/1 Pipeline failed
to dc248f0739
Some checks failed
ci/woodpecker/pr/test/2 Pipeline failed
ci/woodpecker/pr/test/1 Pipeline failed
2025-12-29 16:03:38 +00:00
Compare
Oneric force-pushed fix-conv-api from dc248f0739
Some checks failed
ci/woodpecker/pr/test/2 Pipeline failed
ci/woodpecker/pr/test/1 Pipeline failed
to b114efd013
Some checks failed
ci/woodpecker/pr/test/2 Pipeline failed
ci/woodpecker/pr/test/1 Pipeline failed
2025-12-30 14:42:29 +00:00
Compare
Oneric force-pushed fix-conv-api from b114efd013
Some checks failed
ci/woodpecker/pr/test/2 Pipeline failed
ci/woodpecker/pr/test/1 Pipeline failed
to 554ac9b551
All checks were successful
ci/woodpecker/pr/test/2 Pipeline was successful
ci/woodpecker/pr/test/1 Pipeline was successful
2025-12-30 19:20:30 +00:00
Compare
Oneric changed title from WIP: fix conversations API to Fix conversations API 2025-12-30 19:21:16 +00:00
Author
Owner

Changed the approach degrading the sorting field to just a funny, but more robust date as considered yesterday.

With this and some further cleanup, this should now cover all known actual bugs, pass all tests and work.
Masto-compatible accounts responses and smarter auto-reads are deferred to a later "enhancements and extensions" patch series.

Will test this now in prod for a while before merging.

UPDATE: nvm, the custom pagination isn't working yet with min/max/since_id; apparently there were no test for that yet
UPDATE 2: now fixed, but noticed another, pre-existing issue, see next post

For future reference, the very WIP and unfinished fkey version of the pagination patch is attached.

Changed the approach degrading the sorting field to just a funny, but more robust date as considered yesterday. With this and some further cleanup, this should now cover all known actual bugs, pass all tests and work. Masto-compatible `accounts` responses and smarter auto-reads are deferred to a later "enhancements and extensions" patch series. Will test this now in prod for a while before merging. **UPDATE:** nvm, the custom pagination isn't working yet with min/max/since_id; apparently there were no test for that yet **UPDATE 2**: now fixed, but noticed another, pre-existing issue, see next post For future reference, the very WIP and unfinished fkey version of the pagination patch is attached.
Oneric force-pushed fix-conv-api from 554ac9b551
All checks were successful
ci/woodpecker/pr/test/2 Pipeline was successful
ci/woodpecker/pr/test/1 Pipeline was successful
to 5137d10288
All checks were successful
ci/woodpecker/pr/test/2 Pipeline was successful
ci/woodpecker/pr/test/1 Pipeline was successful
2025-12-30 19:44:58 +00:00
Compare
Oneric changed title from Fix conversations API to WIP: Fix conversations API 2025-12-30 20:06:15 +00:00
Author
Owner

While fixing the remaining pagination issue, I realised the pre-existing post-query filtering has yet another (also pre-existing) bug on edge cases: Filtering only after the query means we can end up with fewer results than allowed by the ex- or implicit limit. That’s not great but ok'ish in itself, but crucially, pagination headers are atm also only generated after the filtering already happened. Therefore pagination headers will resume the lookup after the last unfiltered but before any already-seen but previously filtered entries. If there’s a full page worth of filtered entries (e.g. due to blocks or because all messages got deleted), it will get stuck.

This is kinda another point in favour of the original proper-foreign-key approach, but as discussed before this is hard to maintain with retroactively changing access perms.

For now I intend to workaround this by moving the filtering to the view, so that pagination headers can be generated on the full results. Then there might still be empty pages in responses, but they’ll come with valid Link headers the client can continue to follow to get all results.
Perhaps we can reattempt the foreign-key approach in the future when we have a clearer idea of how or if non-direct posts will affect participations with future enhancements and extensions. But for now this is already a strict improvement over the prior buggy mess and much of the current work can be reused or built upon for a potential future transition to actual foreign keys.

UPDATE: now also fixed and added to the test suite

While fixing the remaining pagination issue, I realised the pre-existing post-query filtering has yet another (also pre-existing) bug on edge cases: Filtering only after the query means we can end up with fewer results than allowed by the ex- or implicit `limit`. That’s not great but ok'ish in itself, but crucially, pagination headers are atm also only generated after the filtering already happened. Therefore pagination headers will resume the lookup after the last unfiltered but before any already-seen but previously filtered entries. If there’s a full page worth of filtered entries *(e.g. due to blocks or because all messages got deleted)*, it will get stuck. This is kinda another point in favour of the original proper-foreign-key approach, but as discussed before this is hard to maintain with retroactively changing access perms. For now I intend to workaround this by moving the filtering to the view, so that pagination headers can be generated on the full results. Then there might still be empty pages in responses, but they’ll come with valid `Link` headers the client can continue to follow to get all results. Perhaps we can reattempt the foreign-key approach in the future when we have a clearer idea of how or if non-direct posts will affect participations with future enhancements and extensions. But for now this is already a strict improvement over the prior buggy mess and much of the current work can be reused or built upon for a potential future transition to actual foreign keys. **UPDATE**: now also fixed and added to the test suite
Oneric force-pushed fix-conv-api from 5137d10288
All checks were successful
ci/woodpecker/pr/test/2 Pipeline was successful
ci/woodpecker/pr/test/1 Pipeline was successful
to d9bd56ea51
All checks were successful
ci/woodpecker/pr/test/2 Pipeline was successful
ci/woodpecker/pr/test/1 Pipeline was successful
2025-12-31 01:44:33 +00:00
Compare
Oneric force-pushed fix-conv-api from d9bd56ea51
All checks were successful
ci/woodpecker/pr/test/2 Pipeline was successful
ci/woodpecker/pr/test/1 Pipeline was successful
to cbf46c5bec
All checks were successful
ci/woodpecker/pr/test/2 Pipeline was successful
ci/woodpecker/pr/test/1 Pipeline was successful
2025-12-31 02:29:50 +00:00
Compare
Oneric force-pushed fix-conv-api from cbf46c5bec
All checks were successful
ci/woodpecker/pr/test/2 Pipeline was successful
ci/woodpecker/pr/test/1 Pipeline was successful
to 033f6b4647
All checks were successful
ci/woodpecker/pr/test/2 Pipeline was successful
ci/woodpecker/pr/test/1 Pipeline was successful
2025-12-31 19:06:33 +00:00
Compare
Oneric changed title from WIP: Fix conversations API to Fix conversations API 2025-12-31 19:07:37 +00:00
Oneric force-pushed fix-conv-api from 033f6b4647
All checks were successful
ci/woodpecker/pr/test/2 Pipeline was successful
ci/woodpecker/pr/test/1 Pipeline was successful
to cc35ae5514
All checks were successful
ci/woodpecker/pr/test/2 Pipeline was successful
ci/woodpecker/pr/test/1 Pipeline was successful
2025-12-31 21:10:49 +00:00
Compare
Author
Owner

Yet another pre-existing bug found during prod testing: only local messages can mark conversation as read since create_or_bump_for is only called from ActivityPub.notify_and_stream (without regard for the activity type) which is only called from either (a)ActivityPub.(do_)create via CommonAPI.post which is only used when creating local statuses, or (b) in the side-effect handling of, (for some reason) specifically only Update activities

This should probably be moved to the side-effect handling of Create i believe (assuming local activities also go through side-effect handling)
Update: turns out local and remote activities have completely distinct pipelines, except for very few activity types, in specific cases partially re-using bits from the other...

Yet another pre-existing bug found during prod testing: only _local_ messages can mark conversation as read since `create_or_bump_for` is only called from `ActivityPub.notify_and_stream` (without regard for the activity type) which is only called from either (a)`ActivityPub.(do_)create` via `CommonAPI.post` which is only used when creating local statuses, or (b) in the side-effect handling of, (for some reason) specifically only `Update` activities This should probably be moved to the side-effect handling of `Create` i believe (assuming local activities also go through side-effect handling) *Update*: turns out local and remote activities have completely distinct pipelines, except for very few activity types, in specific cases partially re-using bits from the other...
Oneric force-pushed fix-conv-api from cc35ae5514
All checks were successful
ci/woodpecker/pr/test/2 Pipeline was successful
ci/woodpecker/pr/test/1 Pipeline was successful
to 2efe44a907
Some checks failed
ci/woodpecker/pr/test/2 Pipeline was successful
ci/woodpecker/pr/test/1 Pipeline failed
2026-01-05 15:50:26 +00:00
Compare
Oneric force-pushed fix-conv-api from 2efe44a907
Some checks failed
ci/woodpecker/pr/test/2 Pipeline was successful
ci/woodpecker/pr/test/1 Pipeline failed
to c0485c3a71
All checks were successful
ci/woodpecker/pr/test/2 Pipeline was successful
ci/woodpecker/pr/test/1 Pipeline was successful
2026-01-05 18:30:25 +00:00
Compare
Oneric force-pushed fix-conv-api from c0485c3a71
All checks were successful
ci/woodpecker/pr/test/2 Pipeline was successful
ci/woodpecker/pr/test/1 Pipeline was successful
to fc89b2d983
Some checks failed
ci/woodpecker/pr/test/1 Pipeline failed
ci/woodpecker/pr/test/2 Pipeline failed
2026-01-07 01:47:56 +00:00
Compare
Oneric force-pushed fix-conv-api from fc89b2d983
Some checks failed
ci/woodpecker/pr/test/1 Pipeline failed
ci/woodpecker/pr/test/2 Pipeline failed
to 6d14d95446
Some checks failed
ci/woodpecker/pr/test/2 Pipeline failed
ci/woodpecker/pr/test/1 Pipeline failed
2026-01-08 02:54:31 +00:00
Compare
Oneric force-pushed fix-conv-api from 6d14d95446
Some checks failed
ci/woodpecker/pr/test/2 Pipeline failed
ci/woodpecker/pr/test/1 Pipeline failed
to 4df6a370ae
Some checks failed
ci/woodpecker/pr/test/2 Pipeline was successful
ci/woodpecker/pr/test/1 Pipeline failed
2026-01-08 03:43:47 +00:00
Compare
Oneric force-pushed fix-conv-api from 4df6a370ae
Some checks failed
ci/woodpecker/pr/test/2 Pipeline was successful
ci/woodpecker/pr/test/1 Pipeline failed
to 429a4602f0
Some checks failed
ci/woodpecker/pr/test/2 Pipeline failed
ci/woodpecker/pr/test/1 Pipeline was successful
2026-01-08 16:43:44 +00:00
Compare
Oneric force-pushed fix-conv-api from 429a4602f0
Some checks failed
ci/woodpecker/pr/test/2 Pipeline failed
ci/woodpecker/pr/test/1 Pipeline was successful
to cd12b3d8f1
Some checks failed
ci/woodpecker/pr/test/2 Pipeline failed
ci/woodpecker/pr/test/1 Pipeline failed
2026-01-08 17:05:55 +00:00
Compare
Oneric force-pushed fix-conv-api from cd12b3d8f1
Some checks failed
ci/woodpecker/pr/test/2 Pipeline failed
ci/woodpecker/pr/test/1 Pipeline failed
to 5ce68a83ac
All checks were successful
ci/woodpecker/pr/test/2 Pipeline was successful
ci/woodpecker/pr/test/1 Pipeline was successful
2026-01-08 17:08:14 +00:00
Compare
Author
Owner

Remote post handling is now fixed.
To avoid merge conflicts I also pulled in a notification stream+push overhaul from Pleroma, before fixing remote post handling. Though as it turns out the Pleroma commit breaks stuff so I had to rewrite everything so in the end it wouldn’t have mattered.

However, now it’s already in their and placed before the fix (and cannot be moved without conflicts). There’s on notable change and question now regarding this. It is possible to mute other users post-only (keeping notifications visible) or completely (also hiding notifications unless with_muted=true is passed). before the change notifications from post-only-muted users were however (usually) immediately marked as read.
Now only those notifications hidden without with_muted=true are automatically marked as read. This intuitively makes more sense to me since notifications were explicitly exempt from the mute (and it’s not clear whether the old behaviour was intentional.
Are there any objections to the change?

Remote post handling is now fixed. To avoid merge conflicts I also pulled in a notification stream+push overhaul from Pleroma, _before_ fixing remote post handling. Though as it turns out the Pleroma commit breaks stuff so I had to rewrite everything so in the end it wouldn’t have mattered. However, now it’s already in their and placed before the fix (and cannot be moved without conflicts). There’s on notable change and question now regarding this. It is possible to mute other users post-only (keeping notifications visible) or completely (also hiding notifications unless `with_muted=true` is passed). before the change notifications from post-only-muted users were however (usually) immediately marked as read. Now only those notifications hidden without `with_muted=true` are automatically marked as read. This intuitively makes more sense to me since notifications were explicitly exempt from the mute (and it’s not clear whether the old behaviour was intentional. Are there any objections to the change?
Oneric force-pushed fix-conv-api from 5ce68a83ac
All checks were successful
ci/woodpecker/pr/test/2 Pipeline was successful
ci/woodpecker/pr/test/1 Pipeline was successful
to 7ed0bb4ff8
Some checks failed
ci/woodpecker/pr/test/2 Pipeline failed
ci/woodpecker/pr/test/1 Pipeline failed
2026-01-10 01:51:19 +00:00
Compare
The old pagination logic was inconsistent and thus broken.
It used to order conversations based on updated_at but generated
pagination HTTP Link headers based on participation IDs.
Thus entries could repeat or be left out entirely.

Notably using updated_at also lead to bumps when
merely marking an individual conversation as read,
though not when marking _all_ conversations as read in bulk
since Repo.update_all does not touch date fields autoamtically.

For consistent and sensible "last active" ordering this is replaced
by using the flake ID (which contains the date) of the last status
which bumped the conversation for both ordering and pagination
parameters. This takes into account whether the status was
visible to the participation owner at the time of posting.

Notably however, it does not care about whether the status continues to
exist or continues to be visible to the owner. Thus this is not marked
as a foreign key and MUST NOT be blindly used as such!
For the most part, this should be considered as just a funny timestamp,
which is more resiliant against spurious bumps than updated_at, offers
deterministic sorting for simulateanously bumped conversations and
better usability in pagination HTTP headers and requests.

Implementing this as a proper foreign key with continuously enforced
visibility restrictions was considered. This would allow to just load
the "last activity" by joining on this foreign key, to immediately
delete participations once they become empty and obsoleting the
pre-existing post-query result filtering.
However, maintaining this such that visibility restrictions are
respected at all times is challenging and incurs overhead.
E.g. unfollows may retroactively change whether the participation owner
is allowed to access activities in the context.

This may be reconsidered in the future once we are clearer
on how we want to (not) extend conversation features.

This also improves on query performance by now using a multi-row,
pre-sorted index such that one user querying their latest conversations
(a frequent operation) only needs to perform an index lookup (and
loading full details from the heap).
Before queries from rarely active users needed to traverse newer
conversations of all other users to collect results.
Previously the view received pre-filtered results and therefore
pagination headers were also only generated with pre-filtered
results in mind. Thus the next page would again traverse over
previously seen but filtered out entries.
Curucially, since this last_activity filtering is happening _after_
the SQL query, it can lead to fewer results being returned than
requested and in particular even zero results remaining.
Sufficiently large blocks of filtered participations thus caused
pagination to get stuck and abort early.

Ideally we would like for this filtering to occur as part of the SQL
query ensuring we will laways return as many results as are allowed as
long as there are more to be found. This would oboslete this issue.
However, for the reasons discussed in the previous commit’s message
this is currently not feasible.

The view is the only caller inside the actual application of the
for_user_with_pagiantion* functions, thus we can simply move filtering
inside the view allowing the full results set to be used when generating
pagination headers.
This still means there might be empty results pages, but now with
correct pagination headers one can follow to eventually get the full set
This might also have prevented utilising the pre-sorted index.
Participation.set_Recipients already does something equivalent,
but it was forgotten here.
And consistently treat muted notifications.

Before, when Notifications where immediately sent out, it correctly
skipped streaming nad web pushes for muted notifications, but the
distinction was lost when notification sending was deferred.
Furthermore, for users which are muted, but are still allowed to
create notifications, it previously (sometimes) automatically marked
them as read. Now notifications are either always silent, meaning
 - will not be streamed or create web pushes
 - will automatically be marked as read on creation
 - should not show up unless passing with_muted=true
or active, meaning
 - will be streamed to active websockets and cause web pushes if any
 - must be marked as read manually
 - show up without with_muted=true

Deferring sending out of notifications isdesirable to avoid duplicate
sending and ghost notifications when processing of the actiity fails
later in the pipeline and avoids stalling the ongoing db transaction.

Inspired by https://git.pleroma.social/pleroma/pleroma/-/merge_requests/4032
but the actual implementation differs to not break with_muted=true.
Without any indication of which post was edited this is only confusing and annoying.
Create and bump conversations on new remote posts
Some checks failed
ci/woodpecker/pr/test/2 Pipeline failed
ci/woodpecker/pr/test/1 Pipeline was successful
05cab10e4e
The handling of remote and local posts should really be unified.
Currently new remote posts did not bump conversations
(notably though, until before the previous commit remote
 edits (and only edits), did in fact bump conversations due to being
 the sole caller of notify_and_stream outside its parent module)
conversation: remove unused users relationship
Some checks failed
ci/woodpecker/pr/test/2 Pipeline failed
ci/woodpecker/pr/test/1 Pipeline failed
32069561c2
It is never used outside tests
and even there its correctness and/or
worth was questionable. The participations recipients
or just testing over the particiaptions’ user_id seem
like a better fit.
In particular this was always preloaded for API responses
needlessly slowing them down
Oneric force-pushed fix-conv-api from 32069561c2
Some checks failed
ci/woodpecker/pr/test/2 Pipeline failed
ci/woodpecker/pr/test/1 Pipeline failed
to cff040a28c
All checks were successful
ci/woodpecker/pr/test/2 Pipeline was successful
ci/woodpecker/pr/test/1 Pipeline was successful
2026-01-10 02:51:43 +00:00
Compare
Oneric force-pushed fix-conv-api from cff040a28c
All checks were successful
ci/woodpecker/pr/test/2 Pipeline was successful
ci/woodpecker/pr/test/1 Pipeline was successful
to 6443db213a
All checks were successful
ci/woodpecker/pr/test/2 Pipeline was successful
ci/woodpecker/pr/test/1 Pipeline was successful
2026-01-11 00:28:53 +00:00
Compare
Author
Owner

Everything works well enough now and the patchset is already rather big, so it’s time to merge:

Enhancements left to future patchsets:

  • further optimise /api/v1/conversations, it is better but still sluggish
    • presumably mainly because querying the latests status from the index is bogged down by all the prep queries to load mutes etc. Possibly by trying last_bump first and if exists and visible use that, or by caching the prep queries
    • also preload conversations by a join to reduce query roundtrips
  • automatically mark as unread when reacting/liking most recent status
  • consider if and if so what to do about accounts semantics differing from mastodon
  • consider extensions brought up in the FE PR
Everything works well enough now and the patchset is already rather big, so it’s time to merge: Enhancements left to future patchsets: - further optimise `/api/v1/conversations`, it is better but still sluggish - presumably mainly because querying the latests status from the index is bogged down by all the prep queries to load mutes etc. Possibly by trying `last_bump` first and if exists and visible use that, or by caching the prep queries - also preload conversations by a join to reduce query roundtrips - automatically mark as unread when reacting/liking most recent status - consider if and if so what to do about `accounts` semantics differing from mastodon - consider extensions brought up in the FE PR
Oneric merged commit 93b513d09c into develop 2026-01-11 15:54:51 +00:00
Oneric deleted branch fix-conv-api 2026-01-11 15:54:51 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
AkkomaGang/akkoma!1039
No description provided.