- Wenn man einen ActivityPub-Server direkt selbst baut, scheitert man leicht schon an der ersten
Follow-Anfrage mit einem kommentarlosen401 Unauthorized; Fedify ist ein TypeScript-Framework, das den Aufwand für Signaturen, JSON-LD, Zustellung und Sicherheit aus dem Anwendungscode herausverlagert - Für Authentifizierung im Fediverse werden sowohl der abgelaufene Entwurf
draft-cavage-http-signatures-12als auch der StandardRFC 9421verwendet; bezieht man Dokumentsignaturen mit ein, muss man vier Signaturmechanismen sowie RSA- und Ed25519-Schlüssel handhaben - Selbst dieselbe ActivityPub-Aktivität kann in JSON-LD in verschiedenen Formen ankommen, etwa als String, Array, Inline-Objekt oder URI-Referenz; je mehr man selbst implementiert, desto weiter verbreitet sich defensiver Code über die gesamte Codebasis
- Bei verteilter Zustellung entstehen Probleme wie „Zombie-Posts“, bei denen ein
Deletevor einemCreateeintrifft; dafür braucht man Queues, Retries, Idempotenz, Reihenfolgegarantien und Circuit Breaker - Fedify bietet Integrationen für 13 Web-Frameworks, Adapter für KV und Message Queues sowie CLI, Linter, Debugger und OpenTelemetry, sodass man auch ohne Detailwissen über ActivityPub mit der Entwicklung föderierter Apps beginnen kann
Probleme bei der direkten Implementierung von ActivityPub
- Um die erste
Follow-Aktivität an Mastodon zu senden, muss man JSON erstellen, die HTTP-Anfrage signieren undPOSTverarbeiten; bei einem Fehlschlag kann aber nur eine einzige Zeile401 Unauthorizedzurückkommen- Die Ursache kann in einer Zeitabweichung im
Date-Header, einem Fehler imDigest-Hash, der Groß-/Kleinschreibung von(request-target)oder der Darstellung des öffentlichen Schlüssels liegen - Wenn der entfernte Server den Grund nicht nennt, muss man zum Debuggen den Code anderer Server lesen
- Die Ursache kann in einer Zeitabweichung im
- Fedify entstand beim Bau von Hollo, einem Microblogging-Server für einen einzelnen Benutzer
- Als der Aufwand für die ActivityPub-Implementierung die Produktentwicklung zu verschlingen begann, wurde daraus zuerst ein Framework, noch vor der eigentlichen App
- Die Schwierigkeiten konzentrieren sich vor allem auf Signaturstandards, JSON-LD-Dokumentformen, verteilte Zustellung, implementierungsspezifische Gepflogenheiten und grundlegende Sicherheitseinstellungen
Es gibt nicht nur einen Signaturstandard
- Für die Authentifizierung zwischen Servern werden HTTP-Signaturen verwendet, im tatsächlichen Fediverse existieren jedoch sowohl der abgelaufene Entwurf draft-cavage-http-signatures-12 als auch der Standard RFC 9421
- Welcher Server welche Signatur akzeptiert, weiß man erst nach einem Versuch; wird eine Methode abgelehnt, muss man mit der anderen erneut signieren und sich pro Server merken, welche Variante funktioniert hat
- Dieses Verfahren wird double-knocking genannt
- HTTP-Signaturen beweisen nur den Absender einer Anfrage; in Fällen wie inbox forwarding, bei denen eine empfangene Aktivität an Dritte weitergeleitet wird, sind daher auch Signaturen erforderlich, die direkt am Dokument hängen
- Insgesamt sind dafür vier Mechanismen nötig, darunter Linked Data Signatures und Object Integrity Proofs
- Außerdem müssen zwei Schlüsseltypen parallel verwaltet werden: RSA und Ed25519
Die Form von JSON-LD-Dokumenten ändert sich ständig
- Das Transportformat von ActivityPub ist JSON-LD, und selbst eine
Create-Aktivität mit derselben Bedeutung kann in mehreren Formen dargestellt werdenactorkann ein URI-String oder ein eingebettetesPerson-Objekt seintokann ein einzelner String oder ein Array seinobjectkann sowohl ein eingebettetes Objekt als auch eine URI sein
- Auch die Adresse für das öffentliche Ziel ist in drei Schreibweisen gültig:
https://www.w3.org/ns/activitystreams#Public,as:PublicundPublic - Um spezifikationskonform damit umzugehen, muss man mit einem JSON-LD-Prozessor erst expandieren und dann durch compaction normalisieren
- Viele Implementierungen behandeln das einfach als „normales JSON“ und brechen dann stillschweigend bei Formen, die ein bestimmter Server ausgibt
- Bei einer Eigenimplementierung entsteht überall defensiver Code, der prüft, ob ein Wert ein String, ein Array, ein Objekt oder eine URI ist, die erst geholt werden muss
Verteilte Zustellung und „Zombie-Posts“
- Wenn ein Benutzer direkt nach dem Veröffentlichen einen Tippfehler bemerkt und den Beitrag löscht, sendet der Server nach
CreateeinDelete; je nach Netzwerksituation kann der empfangende Server jedoch zuerst dasDeleteerhalten- Ignoriert er die Löschung eines noch nicht existierenden Beitrags und verarbeitet später
Create, bleibt ein Beitrag auf diesem Server bestehen, von dem der Autor glaubt, dass er gelöscht wurde
- Ignoriert er die Löschung eines noch nicht existierenden Beitrags und verarbeitet später
- Hat ein Konto 5.000 Follower, erzeugt ein einzelner Beitrag Tausende HTTP-Zustellungen; verarbeitet man das im Request-Handler, kann die Antwort auf den Publish-Button träge werden oder der Server zusammenbrechen
- Selbst mit Queues muss man noch Retry-Zeitpläne für fehlgeschlagene Zustellungen, exponentielles Backoff, Retry-Zahlen, den Unterschied zwischen
500 Internal Server Errorund410 Gone, das Aufräumen von Followern verschwundener Server und den Umgang mit langfristig gestörten Hosts festlegen - Dieser Bereich ist weniger einfache Protokollimplementierung als vielmehr Engineering für verteilte Systeme
Mit der Spezifikation allein ist Interoperabilität nicht erledigt
- Selbst wenn man die Spezifikation perfekt einhält, bleiben Interoperabilitätsprobleme mit realen Fediverse-Implementierungen bestehen
- Der Secure Mode von Mastodon verwendet authorized fetch, das auch für
GET-Anfragen HTTP-Signaturen verlangt- Wenn beide Server im Secure Mode laufen, entsteht ein Deadlock: Um den öffentlichen Schlüssel der Gegenseite zu holen, muss man signieren, aber zum Verifizieren der Signatur muss die Gegenseite zuerst den eigenen öffentlichen Schlüssel abrufen
- Die Community umgeht das, indem sie mit einem instance actor signiert, der den Server selbst repräsentiert; das steht jedoch nicht in der Spezifikation
- Threads kann Aktivitäten, bei denen
actorals eingebettetes Objekt kommt, nicht parsen; beim Senden an Threads mussactordaher als URI gesendet werden - Lemmy lehnt stillschweigend ab, wenn bei einem
Group-Actor Felder fehlen, die Mastodon nicht verlangt- Beispiele sind eine über
attributedToverknüpfte moderators collection und einefeaturedcollection
- Beispiele sind eine über
- Misskey hat eigene Vokabular-Erweiterungen, und allein für Quote-Posts werden je nach Implementierung drei verschiedene Property-Namen verwendet
- Interoperabilität ist kein Thema, das man einmal abstimmt und dann abhakt, sondern ein Bereich, der kontinuierlich gepflegt werden muss
Der Grundzustand einer Eigenimplementierung ist unsicher
- Wenn man die Verifikation eingehender Aktivitätssignaturen überspringt, kann jeder gefälschte
Follow- oderDelete-Nachrichten einschleusen - Wenn man den Dokument-Loader nicht einschränkt, kann eine bösartige Aktivität auf
http://169.254.169.254/oder interne Netzwerke verweisen und den Server zu einem SSRF-Proxy machen - Lässt man die Herkunftsprüfung eingebetteter Objekte weg, kann jeder Server Dokumente ausliefern, die so wirken, als hätte eine bestimmte Person sie verfasst
- Solche Fallstricke fallen nicht sofort auf, und bis zu ihrer Ausnutzung kann alles so aussehen, als funktioniere es korrekt
Bereiche, die Fedify übernimmt
- Fedify ist eine TypeScript-Bibliothek zum Erstellen föderierter Server-Apps mit ActivityPub und zugehörigen Standards
- Läuft auf Deno, Node.js und Bun und unterstützt auch Edge-Runtimes wie Cloudflare Workers
- Das Designziel ist, Signaturen, JSON-LD, Zustellung, Implementierungsunterschiede und Sicherheitsdetails aus dem Anwendungscode herauszuhalten
-
Signaturverarbeitung
- Wenn man einen actor dispatcher und einen key pair dispatcher registriert, kann man einen Actor ins Fediverse bringen
- Alle ausgehenden Requests werden signiert
- Bei RSA-Schlüsseln werden HTTP Signatures und Linked Data Signatures erzeugt
- Fügt man Ed25519-Schlüssel hinzu, werden auch Object Integrity Proofs angehängt
- Diese vier Mechanismen können bei einer einzelnen Aktivität koexistieren, und Empfänger prüfen mit der stärksten Methode, die sie verstehen
- Fedify verarbeitet double-knocking direkt selbst
- Der erste Kontakt geht mit RFC 9421 raus, bei Ablehnung wird mit draft-cavage erneut versucht
- Die erfolgreiche Methode wird pro Server gecacht
- Wenn die Ablehnungsantwort eine
Accept-Signature-Challenge enthält, wird mit den vom Server angeforderten Komponenten erneut signiert
- Eingehende Signaturen werden validiert, bevor der Anwendungscode sie überhaupt sieht; Aktivitäten mit fehlgeschlagener Validierung erreichen den Listener nicht
- Schon allein durch die Registrierung eines actor dispatcher entsteht auch ein WebFinger-RFC 7033-Server, sodass man im Mastodon-Suchfeld einen Actor in der Form
@alice@example.comfinden kann
-
Typen statt JSON-LD behandeln
- Fedify bietet rund 80 Klassen, die den gesamten Activity Vocabulary und wichtige Vendor-Erweiterungen abdecken
- Die Klassen sind typisiert und unveränderlich, und Accessors fangen die Unterschiede in den von JSON-LD erlaubten Dokumentformen ab
lookupObject()nimmt ein Handle entgegen und führt den gesamten Lookup-Prozess inklusive WebFinger-Discovery aus- Accessors wie
getFollowers()funktionieren gleich, egal ob der Wert eine URI-Referenz oder ein Inline-Objekt ist, und geholte Werte werden gecacht - Auch Unterschiede zwischen einzelnen Anbietern werden hinter der API verborgen
- Die drei Quote-Eigenschaften
quoteUri,_misskey_quoteundquoteUrlwerden zusammen mitquoteaus dem neu aufkommenden FEP-044f hinter einer einzigen API zusammengeführt - Auch die Eigenschaft
isCatvon Misskey existiert als Typ und kann typsicher verarbeitet werden
- Die drei Quote-Eigenschaften
-
Zustellinfrastruktur und Reihenfolgegarantie
- Wenn man an
createFederation()eine Message Queue anschließt, wandert die Zustellung in den Hintergrund und wird bei Fehlern standardmäßig mit exponentiellem Backoff bis zu zehnmal automatisch wiederholt - Wenn ein einzelner Beitrag an Tausende Follower zugestellt wird, greift two-stage fan-out
- Eine einzige zusammengefasste Nachricht wird in die Queue gestellt
- Ein Background-Worker teilt sie in Zustelljobs pro Server auf
- Der Publish-Button reagiert sofort
- Durch Retries kann dieselbe Aktivität zweimal ankommen, deshalb überspringt Fedify Duplikate vor dem Handler mithilfe eines Idempotenz-Caches, der verarbeitete Aktivitäten 24 Stunden lang speichert
- Gibt man beim Aufruf von
sendActivity(){ orderingKey: post.id }an, werden Aktivitäten mit demselben orderingKey an jeden empfangenden Server in der Reihenfolge zugestellt, in der sie gesendet wurden- Ein
Deletekann einCreatenicht überholen - Aktivitäten mit unterschiedlichen Schlüsseln gehen parallel raus und erhalten so den Durchsatz
- Ein
- Bei
404 Not Foundoder410 Gonewerden Retries gestoppt und der registrierte Handler für permanente Zustellfehler aufgerufen - Wenn an eine Shared Inbox zugestellt wurde, kann man auch die dahinterstehende Follower-Liste abrufen, um verschwundene Accounts zu bereinigen
- Bei Hosts mit wiederholten Fehlern setzt der standardmäßig aktivierte Circuit Breaker die Zustellung aus und prüft periodisch, ob die Gegenstelle sich erholt hat
- Wenn man an
Implementierungsspezifische Praktiken und sichere Standardeinstellungen
- Bei Authorized Fetch verbindet Fedify
.authorize()mit dem Dispatcher und übergibt die verifizierte Identität des Requesters per Callback- Dinge wie Blocklisten oder private Collections lassen sich als Anwendungslogik schreiben
- Auch für das Deadlock-Problem beim Instance Actor gibt es unterstützte Muster
- Das Inline-Actor-Problem von Threads wird dadurch behandelt, dass der standardmäßig aktivierte activity transformer Inline-Actors in ausgehenden Aktivitäten in URIs umwandelt
- Die von Lemmy verlangte Moderators-Collection lässt sich mit der Custom-Collection-API in wenigen Zeilen bereitstellen, und der JSON-LD-Context von Lemmy ist bereits enthalten
- Wenn neue Interoperabilitätsprobleme entdeckt werden, fließt die Korrektur in Fedify ein statt in jede einzelne Anwendung
- Die sicheren Standardeinstellungen sind auf die sichere Seite ausgelegt
- Die Signaturprüfung ist keine Funktion, die man erst aktivieren muss, sondern eine, die man für Tests deaktivieren kann
- Der Document Loader blockiert standardmäßig private Adressbereiche und Loopback und berücksichtigt auch DNS-Rebinding
- Um SSRF ausgesetzt zu sein, muss man ausdrücklich eine Option aktivieren, deren Name klar macht, dass sie nur für Tests gedacht ist
- Wenn bei eingebetteten Objekten die Herkunft von der des übergeordneten Dokuments abweicht, vertraut der Accessor ihnen nicht und lädt sie vom Ursprung erneut
- Dieses herkunftsbasierte Sicherheitsmodell basiert auf FEP-fe34
Bestehende Stacks und Entwicklungstools
- Fedify wurde so konzipiert, dass es zu bestehenden Web-Stacks passt, und bietet Integrationen für 13 Web-Frameworks
- Express, Hono, Fastify, Koa, NestJS, Elysia
- Next.js, Nuxt, SvelteKit, Astro, SolidStart, Fresh
- Middleware übernimmt die Content-Negotiation, sodass dieselbe URL dem Browser HTML und dem Fediverse JSON-LD liefern kann
- Das eigene Storage von Fedify verlangt nur eine einzige Key-Value-Schnittstelle
- Es gibt Adapter für Redis, PostgreSQL, MySQL/MariaDB, SQLite, Deno KV, Cloudflare Workers KV und In-Memory
- Für Message Queues werden 8 Varianten bereitgestellt, darunter PostgreSQL, Redis und AMQP/RabbitMQ; falls nichts passt, kann man die Schnittstelle selbst implementieren
- Domänendaten können unverändert in der bestehenden Datenbank und dem vorhandenen ORM bleiben
- Wer Federation bereits mit einer anderen Bibliothek betreibt, kann mit dem Migrationsleitfaden und Datenmigrationsskripten von activitypub-express und anderen Lösungen wechseln, ohne bestehende Follower zu verlieren
- Es werden auch Higher-Level-Pakete angeboten
@fedify/relaystellt mit einem einzigen Funktionsaufruf einen vollständigen ActivityPub-Relay-Server bereit@fedify/backfillfolgt dem Fediverse und rekonstruiert unvollständige Gesprächs-Threads
-
Tools für die Entwicklungsschleife
fedify initscaffoldet ein Projekt mit einer einzigen Zeilefedify tunnelmacht einen lokalen Server per HTTPS erreichbar, damit er sich mit echtem Mastodon testen lässtfedify inboxstartet einen temporären Inbox-Server, der Aktivitäten empfängt, die der Server sendetfedify lookupermöglicht die Inspektion von Objekten, die von anderen Servern veröffentlicht wurdenfedify lookup --authorized-fetcherzeugt ein temporäres Schlüsselpaar und startet einen temporären ActivityPub-Server, um signierte Anfragen an Objekte hinter Secure Mode zu senden@fedify/lintist ein ActivityPub-spezifischer Linter, der 20 Arten von Interoperabilitätsfehlern erkennt, etwa wenn einem Actorinboxfehlt- Mit den Mocks von
@fedify/testinglassen sich Tests ohne Netzwerk ausführen @fedify/debuggerhängt mit einer Zeile ein Debug-Dashboard an, sodass sich Aktivitäten und Ergebnisse der Signaturprüfung im Browser in Echtzeit ansehen lassen- Für Produktionsumgebungen ist OpenTelemetry-Instrumentierung eingebaut und liefert 28 Span-Typen sowie 37 Metriken
- Es gibt außerdem einen Monitoring-Leitfaden und das Lasttest-Tool
fedify benchfür ActivityPub - Die offizielle Dokumentation besteht aus 30 Handbuchkapiteln und 5 Tutorials und behandelt reale Praktiken wie PromQL-Abfragen und Alert-Regeln zum Anzeigen von Queue-Backlogs sowie Eigenschaften, damit Avatare in Mastodon sichtbar werden
Bereits im Einsatz und Einstieg
- Fedify wird bereits in realen Diensten eingesetzt
- Ghosts ActivityPub-Dienst
- Encyclia, das ORCID-Forschungsprofile mit dem Fediverse verbindet
- SiliconBeest, das serverless auf Cloudflare Workers läuft
- die koreanische Blogging-Plattform Typo Blue
- die Single-User-Microblogging-Plattform Hollo
- das von der Community betriebene Hackers' Pub
- Die Tutorials bieten Beispiele für verschiedene Größenordnungen
- Ein Single-File-Server mit einigen Dutzend Zeilen, dem Mastodon folgen kann
- Ein Bildfreigabedienst mit rund 750 Zeilen, der mit Pixelfed bei Folgen, Likes und Kommentaren interoperiert
- Ein Tutorial für Community-Plattformen, das bidirektionale Federation mit dem echten lemmy.ml behandelt
- Das Ziel von Fedify ist nicht, mehr ActivityPub-Expertinnen und -Experten auszubilden, sondern Entwicklerinnen und Entwicklern zu ermöglichen, föderierte Apps zu bauen, ohne die Details von ActivityPub kennen zu müssen
- Der Startbefehl lautet
npm init @fedify - Wenn Hilfe benötigt wird, können der Matrix-Raum oder GitHub Discussions genutzt werden
1 Kommentare
Meinungen auf Lobste.rs
Das ist der Grund, warum es bei ActivityPub-Projekten so viele gegenseitige Forks gibt: Es ist einfacher, den Ansatz anderer nachzuvollziehen, als alles selbst zu implementieren.
Was der Autor vorschlägt, wirkt tatsächlich nicht sehr anders als die häufig anzutreffenden Forks von Misskey oder Pleroma. Auch eine Library hat ihre eigene Sichtweise und ihren eigenen Ansatz und scheint nicht allzu viel Kontrolle abzugeben. Trotzdem hat sie den Vorteil, dass sie nicht wie beim Forken eines ganzen Servers sogar die UI vorgibt.
Aus Sicht von jemandem, der AP implementiert, ist der schwierigste Teil, dass es keine gute Methode gibt, JSON-LD korrekt zu verwenden. Wenn man Objekte einfach in eine Standardrepräsentation umwandeln könnte, würde die Interaktion ganz natürlich folgen. Aber um es wirklich wie verlinkte Dokumente zu verwenden, ist es zu ineffizient, und wenn man es wie rohe JSON-Dokumente verwendet, wird man von unzähligen Edge Cases erschlagen. Bisher habe ich den zweiten Ansatz gewählt und bin daran zugrunde gegangen.
Das ist nicht exakt dasselbe Problem wie in der JSON-LD-Welt, aber auch nicht völlig unabhängig davon.
Allerdings haben meiner Ansicht nach viele JSON-nahe Technologien ähnliche Probleme. Es gibt zu viele Arten, dasselbe logische Schema mit JSON Schema auszudrücken, und dadurch wird die Interaktion mit Technologien rund um JSON Schema geradezu absurd schrecklich. Besonders OpenAPI-Schemas sind ein ähnliches, aber nicht identisches Horrorkabinett, und selbst ohne die Zahl der Schema-Draft-Versionen zu berücksichtigen, ist es schon schlimm genug.
Der „MTA“-Dienst von AP wäre dafür zuständig, Nachrichten aus der Outbox zu versenden und Nachrichten in der Inbox zu empfangen. JSON-LD-Dokumente sind aus Sicht dieses Dienstes im Grunde fast Blob-Daten. Ein wenig Parsing ist nötig, um Absender und Empfänger zu ermitteln, aber viel mehr nicht. Auch der Speicher könnte dateibasiert sein; wenn ich mich richtig erinnere, nutzt go-ap so einen Ansatz.
Der „MUA“ von AP ist die eigentliche Anwendung. Das ist die Seite, die die Bedeutung von JSON-LD verstehen muss. Man könnte etwas wie PostgreSQL nutzen, die Dokumente als jsonb speichern und über generierte Spalten und Views eine SQL-freundliche Form bereitstellen. Dann kann man je nach Objekttyp entscheiden, wie sich das Dokument am sinnvollsten darstellen lässt.
Als weiteres Beispiel könnte man auch einen Suchdienst als Actor modellieren und die Ergebnisse über eine temporäre Outbox zurückgeben lassen.
Eine äußerst wertvolle Liste von eigenwilligem Verhalten verschiedener Implementierungen und möglichen Gegenmaßnahmen.
Leider ist in GoActivityPub noch nicht einmal die Hälfte davon implementiert.
Ich war dankbar, dass der Artikel zunächst technisch begann, aber ab der Mitte schien er in Richtung Eigenwerbung für das Framework abzubiegen, was die Lektüre weniger angenehm machte.
Es ist schön, dass manche Teile der TypeScript-Welt diese Implementierungsbesonderheiten vielleicht nicht noch einmal neu entdecken müssen. Aber als mentales Modell gilt: Wenn es Aufzeichnungen gibt wie „unter diesen Bedingungen und in diesen Situationen kommt dieses Ergebnis heraus, und diese Korrektur ist nötig“, dann können auch Nicht-TypeScript-Kontexte, etwa die Autoren des Schwesterprojekts GoActivityPub, von den Ergebnissen dieser Mühen profitieren. Einige dieser Dinge werden hier zwar behandelt, aber der Artikel ist eine Momentaufnahme, während das Projekt mit der Zeit offenbar alle Interoperabilitätsbugs ansammeln will.
Die derzeitige Alternative besteht aus meiner Sicht nur darin, alle nicht von Menschen geschriebenen Commit-Messages durchzulesen und dabei Bugs von Fedify selbst von Interoperabilitätsbugs zu unterscheiden.
Besonders ironisch ist, dass das Repository zwar so wirkt, als sei es bei AI „all in“, aber trotzdem keine solche Buchführung betreibt. Die Werbung, die ich über LLMs gehört habe, lautete doch, dass sie repetitive Fleißarbeit automatisieren. Dann könnte Claude GitHub-Issues erstellen oder, noch besser, in einer .md-Datei im Repository dokumentieren, was beobachtet wurde und wie Fedify es behebt. Es gibt sogar einen eigenen Debugger und irgendwelche „Best Practices“, deren Bedeutung mir unklar ist; das wäre also genau die passende Aufgabe.
Warum führt man Requests an Drittanbieterdienste inline aus? Das ist Webanwendungs-Grundwissen. Wenn man mit Drittanbieterdiensten kommunizieren muss, schickt man das in einen Background Job. Wenn Informationen für die Antwort auf den Request nicht nötig sind, gehören sie in einen Background Job. Probleme, die entstehen, weil man solche Requests im Request-Handler ausführt, sind selbstverschuldet auf dem Niveau, auf einen Rechen zu treten und ihn ins Gesicht zu bekommen; mit ActivityPub hat das nichts zu tun.
Wenn eine Zustellung fehlschlägt, muss man sie erneut versuchen, und Fragen wie der Zeitplan, ob man exponentielles Backoff nutzt, wie oft man es versucht oder ob man 500 Internal Server Error und 410 Gone als denselben Fehler betrachtet, sind einfach allgemeine Probleme der Webanwendungsentwicklung. Das sind Probleme, die auftreten, wenn eine Job Queue Requests an Drittanbieterdienste stellt, und sie haben nichts mit ActivityPub zu tun. Die meisten Web-Frameworks haben dafür vernünftige Defaults. Entscheiden muss man nur an der Stelle, an der abhängig vom konkreten Fehler bestimmt wird, ob ein Retry sinnvoll ist. Einen 410 zu wiederholen ist Verschwendung, aber kein Problem, das dringend gelöst werden muss. Es erhöht zwar den Speicherdruck auf die Job Queue, wird die Anwendung aber wahrscheinlich nicht innerhalb weniger Stunden zum Absturz bringen.
„Schau, ob es abgelehnt wird, signiere dann auf andere Weise erneut und merke dir pro Server, welche Methode funktioniert hat“ – was lese ich hier eigentlich? Ist das der Grund, warum die Mastodon-Entwicklung so langsam ist?
„Ein einzelner Beitrag wird zu Tausenden HTTP-Zustellungen“ – und das in Ruby, einer Sprache, die für hervorragende Netzwerk-Systemprogrammierung und Queuing berühmt ist.
Kaum zu glauben; gut, dass das in eine Library verpackt wurde, aber trotzdem.
Nachdem ich ActivityPub in Java implementiert hatte, kam ich zu dem Schluss, dass man solche Server-zu-Server-Protokolle einfach besser auf git aufbauen sollte.
Ein großer Teil der Komplexität existiert, um Probleme erneut zu lösen, die git bereits besser löst. Wenn man das als JSON-Dokumente in einem git-Repository modelliert, muss man sich nicht mit Pagination beschäftigen. Das Protokoll garantiert bereits, dass nur noch nicht vorhandene Daten gesendet werden, man bekommt Commit-Signaturen, garantierte Ereignisreihenfolge, die im Artikel genannten Probleme werden gelöst, und die Historie gibt es gratis dazu. Man könnte daraus eine Art Greenspun’sche zehnte Regel formulieren: In solchen Protokollen steckt eine fehlerhafte, langsame halbe Implementierung von git.
Dieser Artikel liest sich wie ein von AI erzeugter Beitrag niedriger Qualität.
Genauer gesagt verstehe ich nicht, warum er in Erzählform geschrieben wurde. Die hier vermittelten Fakten hätten viel knapper und weniger voreingenommen dargestellt werden können, und die Erzählung überzeugt nicht. Vor allem, weil es viele typisch AI-artige Formulierungen gibt.
Angenehm zu lesen war es nicht. Trotzdem danke, dass die Probleme benannt wurden; ich hoffe, dass man sie auf andere Weise nachlesen und beheben kann.