Simulating network requests to test a new feature in @distributed
You know how when you follow an account on Mastodon you don't get to see any of the users older posts unless someone else on your instance follows them? Well if it's a distributed press site it'll attempt to "backfill" your instance with all the older posts once your follow request is accepted. 😎
@mauve @distributed that might have unintended side-effects
@thisismissem Probably! What sort were you thinking of?
@mauve like flooding peoples timelines with the backfilling of posts
@thisismissem I assumed timelines would sort by published time no? I'm gonna run some tests before deploying this to production ofc
@mauve I think there's a bug to the contrary
@thisismissem In mastodon? i'd love to see the source code for it if you know what part of it it'd be in.
@mauve I don't have it off top of my head but follow from /app/lib/activitypub/activity/create.rb
@thisismissem It seems to be taking the created_at part out at least. 🤔 https://github.com/mastodon/mastodon/blob/main/app/lib/activitypub/activity/create.rb#L122C7-L122C17
I'll look more after testing. Gonna let my personal instance take the bulk o9f the damage :P
@mauve yeah, I've heard of like, birdsite bridge that did similar backfilling clogging up people's timelines, but that might be specific to that implementation.
@thisismissem @mauve so... imo the ActivityPub way of doing this is to publish your last X posts at an "outbox" endpoint specified in your profile. Then a remote server following you can parse the outbox and get some content to fill things with. I did this with some software I was building and Mastodon just... didn't grab any of the outbox posts and I was confused as to why not
@darius @thisismissem @mauve yeah the outbox is there to support "web browser" use cases, fetch the latest activities and page through to see history
the thing with mastodon and timeline sorting is that the timeline sorting algorithm isn't using creation date, it's using arrival date. this is so someone can't create a post set in the far future to have it pinned at the top of your timeline.
@darius @thisismissem @mauve so delivering an activity ~now would insert the post at the top of the TL even if it was backdated in the `published` property.
@trwnh @thisismissem @mauve Oh interesting. But also: why not use arrival date for future dated posts and creation date for back dated posts? (Genuine question btw. I'm sure I'm missing some weird edge case race condition)
@darius @trwnh @thisismissem @mauve Because of Announce, as the obvious case. But more generally, when an object was created doesn't have any real connection to when it should be presented to people. Mastodon is doing more or less the right thing, here.
I wish mastodon would be more prompt in backfilling from the outbox, so that this wouldn't even seem necessary. But even that is basically the right behavior.
@jenniferplusplus @trwnh @thisismissem @mauve I see what you mean by time created vs when it should be presented. That said, if we consider the context of pulling from an outbox to backfill, then the context seems pretty clearly (to me, I could be wrong) "do not show this in the home timeline, this is just for filling in our database for views more generally"
DOES Mastodon pull from the outbox? I didn't observe it doing it at all
@darius @jenniferplusplus @thisismissem @mauve nope, mastodon p much ignores the outbox
and yeah it makes sense to *not* do timeline insertion when backfilling, backfilling seems like the kind of thing that is only/primarily useful for viewing a profile and not keeping up with current activities
@darius @jenniferplusplus @thisismissem @mauve another way to look at it is that there are really two dates, one is the date the object claims to be published, and the other is the date that the activity arrived in your inbox. most fedi dev is used to thinking in terms of objects, but it would be more technically correct and spec-accurate to think in terms of activities
@trwnh @darius @thisismissem @mauve objects have dereferenceable URIs. Why wouldn't I make that a first class entity in my data model?
@jenniferplusplus @darius @thisismissem @mauve activities do too, as well! or they should. activities are also objects.
the advantage of thinking in terms of activities is that it's a better representation of reality, with AP serving as a specialization of LDN (Linked Data Notifications), you're basically notifying your followers/audience/recipients that "something happened". it's the reason we POST Create activities and not just raw non-activity objects.
@trwnh @darius @thisismissem @mauve
Unless the activity is intentionally transient. The spec says this twice in two paragraphs. I don't know what it means for an activity to *not* be transient. Activities are actions, not ongoing persistent state. The objects the refer to are the persistent state.
@jenniferplusplus @trwnh @thisismissem @mauve I see the transient language in the spec but it's about ids and guids and referencing things globally. I don't read it as saying anything about activities being temporary things that can be thrown away (though they allow for the possibility). Every time I've worked with an Event/Object model (at least in years as an MMORPG dev) we consider both Events & Objects to be first-class entities. All of these things should be first-class and treated as such
@erincandescent @darius @thisismissem @mauve @trwnh I would argue that about non-transient activities.
@jenniferplusplus @erincandescent @darius @thisismissem @trwnh Mind elaborating on the issues you've had with Undo? It was super straightforward when we implemented it.
https://github.com/hyphacoop/social.distributed.press/blob/main/src/server/apsystem.ts#L494
@mauve @erincandescent @darius @thisismissem @trwnh If you're implementing the spec as written, you should be doing inbox forwarding. Are you supposed to unsend the forwarded objects?
@jenniferplusplus @mauve @erincandescent @thisismissem @trwnh in the latter case I would forward the Undo and that would be sufficient I think?
That is not documented as something you are supposed to do anywhere.
Especially because the undo may not be targeted the same way as the original message. Are you supposed to validate this? Are you supposed to send the Undo(Create(Note)) to everyone who has received a forwarded copy of the Note even if they didn't receive the Create?
It's a logistical nightmare of inconsistency.
@jenniferplusplus @mauve @erincandescent @thisismissem @trwnh
@hrefna @darius @jenniferplusplus @mauve @erincandescent @thisismissem technically you're not supposed to Undo Create, the spec calls out "inverse activities" as Create-Delete and Add-Remove. the use of Undo is for other activities such as Like/Follow/Block, "to the extent possible".
sending inverse activities to a different audience than the original activity is a completely separate issue (and arguably one left to the discretion of the actor sending those activities arbitrarily)
@trwnh I'm aware. Use announce instead if you prefer, the point remains. It also isn't a "completely separate issue" from a security and privacy perspective nor from a data integrity perspective. It's tied together pretty tightly.
Though it's also worth noting that the spec also contradicts itself on that point, c.f., AS 2.0 Vocabulary 5.5 which indicates that Undo(Create) and Delete(Note) are semantically distinct operations.
@darius @jenniferplusplus @mauve @erincandescent @thisismissem
@jenniferplusplus @mauve @erincandescent @darius @thisismissem @trwnh I appreciate this whole thread. I learned a lot. Thanks everybody.
Yeah really, reading discussions like this is like auditing an ActivityPub seminar. Thanks much to all involved!
@polotek@social.polotek.net @jenniferplusplus@hachyderm.io @mauve@mastodon.mauve.moe @erincandescent@akko.erincandescent.net @darius@friend.camp @thisismissem@hachyderm.io @trwnh@mastodon.social
Also firmly (unsurprisingly) in camp "Activities should always be considered transient." You could make a case for a non-dereferenceable identifier (CmRDT style), but that's it
The complexity is so so high to deal with it any other way. Not even getting into the confusion of how to handle events with multiple authors, or dealing with unwinding the stack of side effects across multiple systems (Undo(Approve(Follow(Note))
@hrefna @jenniferplusplus @mauve @erincandescent @darius @thisismissem Undo Accept Follow is already something that we have to deal with, though -- there's also Reject Follow which fedi implementations like mastodon and misskey decided would be equivalent and preferable, assuming you handle all Reject Follow activities as destroying the follow relationship regardless of prior state.
@hrefna @jenniferplusplus @mauve @erincandescent @darius @thisismissem
also re:
> Also firmly (unsurprisingly) in camp "Activities should always be considered transient." You could make a case for a non-dereferenceable identifier (CmRDT style), but that's it
i think this is something that we might have to disagree on; i didn't think of it as polarizing but i suppose it comes down to whether you see AP as a mechanism to distribute notifications or whether you see it as a state synchronization.
It is neither.
It is a very poor state synchronizer and it is a very poor notification system.
For the first, there's a reason that PAXOS looks like what it looks like.
For the second, it lacks the fundamental primatives required and there are better options.
So if either of those are the goals, I would argue that it does them at best very poorly and lacks the tooling to even consider what either should look like.
@jenniferplusplus @mauve @erincandescent @darius @thisismissem
@hrefna @jenniferplusplus @mauve @erincandescent @darius @thisismissem well i'd argue it is first and foremost about publishing web resources, which it seems to do pretty well. an activity is a resource, you can describe it with RDF, and so on. you can notify others by POSTing that resource to their LDN inbox.
i do think the attempt to shoehorn in side effects makes it a poor man's RPC, and trying to build state sync on top of that is even more unwieldy, but it still "works" even if "very poor"
@trwnh @hrefna @mauve @erincandescent @darius @thisismissem
I mean, yes, it's a web publishing mechanism. But that's not really complete. The stated goal is to be a reciprocal and bi-directional publishing mechanism. There's no world where that's not a matter of distributed state synchronization.
@jenniferplusplus @hrefna @mauve @erincandescent @darius @thisismissem where is this goal stated? from activitypub.rocks:
> It provides a client to server API for creating, updating and deleting content, as well as a federated server to server API for delivering notifications and subscribing to content.
from w3.org:
> "Federation Protocol". This protocol is used to distribute activities between actors on different servers, tying them into the same social graph.
@jenniferplusplus @hrefna @mauve @erincandescent @darius @thisismissem the "social graph" in question is heavily reliant on the Web and on Web architecture, with all the benefits and flaws it entails. this means relying on authoritative domains as sources of truth, and this ties back into why activities SHOULD have dereferenceable identifiers ("unless intentionally transient").
> Activities [...] are the core mechanism for creating, modifying and sharing content within the social graph.
@trwnh @hrefna @mauve @erincandescent @darius @thisismissem
It's literally the first sentence, and it's implied in the 2nd, which you quoted.
> The ActivityPub protocol is a decentralized social networking protocol
social networking. subscriptions. The whole concept of followers, and following, which is basically the only interaction that has a reasonably complete specification. These are all reciprocal two-way communication.
@jenniferplusplus @hrefna @mauve @erincandescent @darius @thisismissem i don’t think there is a singular conceptual bound for what a social network should look like or how it should operate. trying to build a consistent state machine for the entirety of that conceptual space seems… overly optimistic, shall we say. the lowest common denominator is the subscription mechanism which as you point out is relatively well-specified. payloads, otoh, are highly contextual…
@jenniferplusplus @hrefna @mauve @erincandescent @darius @thisismissem still, there are some broad patterns that are reflected in the object model. sure, there are plenty of issues with that, i’ve ranted about several on my wiki, lol
@hrefna Do you have an implementation you've worked on where you've come accross issues like these? I'd love to see your source code. Especially if you can point to impls that lead to these issues occuring at all. In my experience I have not had to account for an Undo of a Create or anything wild like that.
@mauve Start here: https://funfedi.dev/support_tables/generated/score/
Then here: https://www.stevebate.net/nothin-implements-activitypub/
Then here: https://docs.google.com/document/d/13LuB6Z-C_drCLCEuCtNApX98zPG7XlTxGnwHQWN2Cf0/edit
I'm talking about implementing the spec and about the broader questions of what state synchronization looks like in distributed systems, not "what currently mostly-mastodon-inspired-or-compatible servers do when talking to each other, which is not the spec and in some cases is entirely unlike the spec as written (c.f., Question)."
@hrefna so sorry, do you have an implementation you're working on or are you working on something that's a competitor to AP which you feel is better made?
@mauve Yes, and I linked you to one of the relevant documents already so you would presumably know this if you had read the links I included. It also doesn't matter in the slightest here and I'm baffled as to why you think it does matter.
"Oh, you have complaints? Show me your source code" is at best a distraction and at worst a form of gatekeeping.
@hrefna Apologies if I have upset you, this was not my intention. It was not obvious to me from your post that your implementation was among your links. I had thought it was all compatibility and example docs. I'll read the links in more detail now. TY!
@hrefna I care if you have an impl or not because it changes where the critique comes from. The pain from having to get AP to work is pretty specific IMO :P I ask for source code because it is my preferred way of looking at systems rather than docs or talking. 😅
I like the diagrams you made for featherpub. May I share this around to some colleagues?
I notice the synthesis talks about what doesn't get used but doesn't have a new spec with what does. Will you be adding your spec in there?
@hrefna Just to clarify I didn't mean to ask it as a way to gatekeep your credentials, I am just genuinely curious since I like reading through other implementations to see how they do stuff. I do not mean to cast doubt on your words and am excited to see more of your work in the future.
@mauve @erincandescent @darius @thisismissem @trwnh Undo is supposed to unwind the side effects of the arbitrary undone activity. Consider even for a simple case: Undo(Like)? You can't unsend the notification. Now what about less simple cases? What if you receive an Undo(Delete)? What if you receive an Undo(Undo)? The logical complexity it would take to support this is extreme.
And the idea that you can simply undo things in a distributed poly-central system like this is fantasy.