2 điểm bởi GN⁺ 5 giờ trước | 1 bình luận | Chia sẻ qua WhatsApp
  • Nếu tự xây dựng máy chủ ActivityPub, bạn dễ bị chặn ngay từ yêu cầu Follow đầu tiên bởi lỗi 401 Unauthorized không có giải thích; Fedify là một framework TypeScript chuyển gánh nặng về chữ ký, JSON-LD, chuyển tiếp và bảo mật ra khỏi mã ứng dụng
  • Xác thực trong Fediverse dùng song song bản nháp đã hết hạn draft-cavage-http-signatures-12 và tiêu chuẩn RFC 9421; nếu tính cả chữ ký tài liệu, bạn phải xử lý bốn cơ chế chữ ký cùng khóa RSA và Ed25519
  • Ngay cả cùng một hoạt động ActivityPub, trong JSON-LD nó có thể đến dưới nhiều dạng như chuỗi, mảng, đối tượng nhúng trực tiếp hoặc tham chiếu URI; càng tự triển khai, mã phòng thủ càng lan khắp codebase
  • Trong việc phân phối phân tán có thể phát sinh các vấn đề như “bài viết zombie”, khi Delete đến trước Create; cần có hàng đợi, thử lại, tính lũy đẳng, bảo đảm thứ tự và circuit breaker
  • Fedify cung cấp tích hợp với 13 web framework, adapter KV và hàng đợi tin nhắn, CLI, linter, debugger và OpenTelemetry, giúp bắt đầu phát triển ứng dụng liên hợp mà không cần biết chi tiết ActivityPub

Những vấn đề gặp phải khi tự triển khai ActivityPub

  • Để gửi hoạt động Follow đầu tiên tới Mastodon, bạn phải viết JSON, ký yêu cầu HTTP rồi xử lý cả POST, nhưng nếu thất bại có thể chỉ nhận lại một dòng 401 Unauthorized
    • Nguyên nhân có thể là sai lệch đồng hồ trong header Date, lỗi hash Digest, chữ hoa/thường của (request-target), cách biểu diễn khóa công khai, v.v.
    • Nếu máy chủ từ xa không cho biết lý do, bạn phải đọc mã của máy chủ khác để debug
  • Fedify bắt đầu từ quá trình xây dựng Hollo, một máy chủ microblog một người dùng
    • Khi gánh nặng triển khai ActivityPub nuốt chửng việc phát triển sản phẩm, nó được tạo thành framework cần thiết trước cả ứng dụng
  • Khó khăn chủ yếu tập trung vào chuẩn chữ ký, hình dạng tài liệu JSON-LD, phân phối phân tán, thông lệ riêng của từng implementation và thiết lập bảo mật mặc định

Không chỉ có một chuẩn chữ ký

  • Xác thực giữa các máy chủ dùng chữ ký HTTP, nhưng trong Fediverse thực tế, bản nháp đã hết hạn draft-cavage-http-signatures-12 và tiêu chuẩn RFC 9421 cùng tồn tại
  • Trước khi thử, bạn không thể biết máy chủ nào chấp nhận chữ ký nào, nên phải ký theo một cách, nếu bị từ chối thì ký lại theo cách khác và ghi nhớ cách đã thành công cho từng máy chủ
  • Chữ ký HTTP chỉ chứng minh người gửi yêu cầu, nên trong các tình huống như inbox forwarding, khi hoạt động nhận được được chuyển tiếp cho bên thứ ba, cũng cần chữ ký gắn với chính tài liệu

Hình dạng tài liệu JSON-LD liên tục thay đổi

  • Định dạng truyền tải của ActivityPub là JSON-LD, và cùng một hoạt động Create có cùng ý nghĩa cũng có thể được biểu diễn bằng nhiều hình dạng
    • actor có thể là chuỗi URI hoặc một đối tượng Person nhúng trực tiếp
    • to có thể là một chuỗi đơn lẻ hoặc một mảng
    • object có thể là đối tượng nhúng trực tiếp hoặc URI
  • Địa chỉ biểu thị đối tượng công khai cũng có cả ba cách biểu diễn hợp lệ: https://www.w3.org/ns/activitystreams#Public, as:Public, Public
  • Để xử lý đúng theo đặc tả, cần chuẩn hóa bằng cách expansion rồi compaction qua bộ xử lý JSON-LD
    • Nhiều implementation xử lý nó như “chỉ là JSON”, rồi âm thầm hỏng với dạng mà một máy chủ cụ thể phát ra
  • Nếu tự triển khai, mã phòng thủ để kiểm tra giá trị là chuỗi, mảng, đối tượng hay URI cần fetch sẽ xuất hiện khắp nơi

Phân phối phân tán và “bài viết zombie”

  • Nếu người dùng đăng bài rồi ngay sau đó thấy lỗi chính tả và xóa, máy chủ sẽ gửi Create rồi Delete, nhưng tùy tình trạng mạng, máy chủ nhận có thể nhận Delete trước
    • Nếu bỏ qua việc xóa một bài viết chưa tồn tại rồi sau đó xử lý Create, bài viết mà tác giả tin là đã xóa sẽ vẫn còn trên máy chủ đó
  • Nếu có 5.000 người theo dõi, một bài viết sẽ tạo ra hàng nghìn lượt gửi HTTP; nếu xử lý trong request handler, phản hồi của nút đăng bài sẽ chậm hoặc máy chủ có thể sập
  • Ngay cả khi dùng hàng đợi, vẫn phải quyết định lịch thử lại cho các lần gửi thất bại, exponential backoff, số lần thử lại, sự khác biệt giữa 500 Internal Server Error410 Gone, dọn dẹp follower của máy chủ đã biến mất và cách xử lý host lỗi kéo dài
  • Mảng này gần với kỹ thuật hệ thống phân tán hơn là triển khai giao thức đơn giản

Chỉ đặc tả thôi chưa đủ để hoàn tất khả năng tương tác

  • Ngay cả khi tuân thủ đặc tả hoàn hảo, vẫn còn vấn đề tương tác với các implementation Fediverse thực tế
  • Secure mode của Mastodon dùng authorized fetch, yêu cầu chữ ký HTTP cả với yêu cầu GET
    • Nếu cả hai máy chủ đều ở secure mode, sẽ có bế tắc: muốn lấy khóa công khai của đối phương thì phải ký, nhưng muốn xác minh chữ ký thì đối phương trước tiên phải lấy khóa công khai của mình
    • Cộng đồng lách bằng cách ký bằng instance actor đại diện cho chính máy chủ, nhưng điều này không có trong đặc tả
  • Threads không phân tích được hoạt động có actor là đối tượng nhúng trực tiếp, nên khi gửi tới Threads phải gửi actor dưới dạng URI
  • Lemmy âm thầm từ chối nếu thiếu các trường của Group actor mà Mastodon không yêu cầu
    • Ví dụ là moderators collection và featured collection được liên kết bằng attributedTo
  • Misskey có phần mở rộng từ vựng riêng, và chỉ riêng quote post cũng đã có ba tên thuộc tính khác nhau tùy implementation
  • Khả năng tương tác không phải là việc làm khớp một lần rồi xong, mà là lĩnh vực phải liên tục duy trì

Trạng thái mặc định khi tự triển khai là không an toàn

  • Nếu bỏ qua việc xác minh chữ ký của hoạt động gửi đến, bất kỳ ai cũng có thể chèn Follow hoặc Delete giả mạo
  • Nếu không giới hạn document loader, hoạt động độc hại có thể trỏ tới http://169.254.169.254/ hoặc mạng nội bộ, biến máy chủ thành proxy SSRF
  • Nếu bỏ qua kiểm tra nguồn gốc của đối tượng nhúng, bất kỳ máy chủ nào cũng có thể phát ra tài liệu trông như thể do một người cụ thể nói ra
  • Những cạm bẫy này không hiện ra ngay lập tức, và mọi thứ có thể trông như đang hoạt động cho đến khi bị khai thác

Những phần Fedify xử lý thay bạn

  • Fedify là thư viện TypeScript để xây dựng ứng dụng máy chủ liên hợp dựa trên ActivityPub và các tiêu chuẩn liên quan
  • Chạy trên Deno, Node.js, Bun và cũng hỗ trợ các runtime edge như Cloudflare Workers
  • Mục tiêu thiết kế là loại bỏ chữ ký, JSON-LD, việc chuyển phát, khác biệt giữa các implementation và các chi tiết bảo mật khỏi mã ứng dụng
  • Xử lý chữ ký

    • Chỉ cần đăng ký actor dispatcher và key pair dispatcher là có thể đưa một actor lên fediverse
    • Tất cả yêu cầu đi ra đều được ký
    • Với khóa RSA, nó tạo HTTP Signatures và Linked Data Signatures
    • Nếu thêm khóa Ed25519, Object Integrity Proofs cũng được gắn kèm
    • Bốn cơ chế cùng tồn tại trong một activity, và bên nhận xác minh bằng phương thức mạnh nhất mà họ hiểu
    • Fedify tự xử lý double-knocking
      • Lần tiếp xúc đầu tiên dùng RFC 9421; nếu bị từ chối thì thử lại bằng draft-cavage
      • Phương thức thành công được cache theo từng máy chủ
      • Nếu phản hồi từ chối có challenge Accept-Signature, nó sẽ ký lại bằng các thành phần mà máy chủ yêu cầu
    • Chữ ký đến được xác minh trước khi mã ứng dụng nhìn thấy; activity không xác minh được sẽ không đến listener
    • Chỉ cần đăng ký actor dispatcher là cũng có máy chủ WebFinger RFC 7033, nên có thể tìm actor trong ô tìm kiếm Mastodon theo dạng @alice@example.com
  • Làm việc với kiểu thay vì JSON-LD

    • Fedify cung cấp khoảng 80 class bao phủ toàn bộ Activity Vocabulary và các phần mở rộng chính của nhà cung cấp
    • Các class có kiểu, bất biến, và accessor hấp thụ các khác biệt về dạng tài liệu mà JSON-LD cho phép
    • lookupObject() nhận handle và thực hiện toàn bộ quy trình tra cứu, bao gồm cả WebFinger discovery
    • Các accessor như getFollowers() hoạt động theo cùng một cách dù giá trị là tham chiếu URI hay object inline, và giá trị đã fetch sẽ được cache
    • Khác biệt theo từng nhà cung cấp cũng được che sau API
      • Ba thuộc tính quote quoteUri, _misskey_quote, quoteUrl được hợp nhất sau một API cùng với quote của FEP-044f mới xuất hiện
      • Thuộc tính isCat của Misskey cũng tồn tại dưới dạng kiểu, nên có thể xử lý an toàn về kiểu
  • Hạ tầng chuyển phát và bảo đảm thứ tự

    • Khi nối hàng đợi thông điệp vào createFederation(), việc chuyển phát được chuyển sang nền và khi thất bại sẽ tự động thử lại với exponential backoff, mặc định tối đa 10 lần
    • Khi một bài viết được chuyển phát đến hàng nghìn follower, two-stage fan-out sẽ hoạt động
      • Một thông điệp hợp nhất được đưa vào hàng đợi
      • Worker nền chia nó thành các tác vụ chuyển phát theo từng máy chủ
      • Nút đăng bài phản hồi ngay lập tức
    • Vì thử lại có thể khiến cùng một activity đến hai lần, Fedify dùng cache idempotency lưu activity đã xử lý trong 24 giờ để bỏ qua bản trùng trước khi đến handler
    • Nếu chỉ định { orderingKey: post.id } khi gọi sendActivity(), các activity dùng chung cùng orderingKey sẽ được chuyển phát đến từng máy chủ nhận theo đúng thứ tự đã gửi
      • Delete không thể vượt lên trước Create
      • Activity có khóa khác nhau được gửi song song để duy trì throughput
    • Với 404 Not Found hoặc 410 Gone, nó dừng thử lại và gọi handler lỗi chuyển phát vĩnh viễn đã đăng ký
    • Nếu gửi qua shared inbox, cũng có thể nhận danh sách follower phía sau đó để dọn các tài khoản đã biến mất
    • Với host liên tục thất bại, circuit breaker được bật mặc định sẽ tạm giữ việc chuyển phát và kiểm tra phục hồi định kỳ

Tập quán theo từng implementation và mặc định bảo mật

  • Với authorized fetch, Fedify nối .authorize() vào dispatcher và chuyển danh tính người yêu cầu đã xác minh cho callback
    • Các xử lý như danh sách chặn, collection riêng tư có thể viết bằng logic ứng dụng
    • Cũng có pattern hỗ trợ cho vấn đề deadlock của instance actor
  • Vấn đề actor inline của Threads được xử lý bởi activity transformer bật mặc định, chuyển actor inline trong activity đi ra thành URI
  • Moderators collection mà Lemmy yêu cầu có thể được expose bằng vài dòng qua custom collection API, và JSON-LD context của Lemmy đã được bao gồm sẵn
  • Khi phát hiện vấn đề tương tác mới, bản sửa sẽ đi vào Fedify chứ không phải từng ứng dụng
  • Các mặc định bảo mật nghiêng về phía an toàn
    • Xác minh chữ ký không phải là tính năng cần bật, mà là tính năng chỉ tắt cho mục đích thử nghiệm
    • Document loader mặc định chặn private address range và loopback, đồng thời cũng tính đến DNS rebinding
    • Để bị phơi trước SSRF, phải bật rõ ràng một tùy chọn có tên thể hiện đây là tùy chọn dùng cho thử nghiệm
    • Nếu nguồn của object nhúng khác với tài liệu cha, accessor sẽ không tin tưởng và fetch lại từ nguồn gốc
    • Mô hình bảo mật dựa trên nguồn gốc này dựa trên FEP-fe34

Ngăn xếp hiện có và công cụ phát triển

  • Fedify được thiết kế để phù hợp với ngăn xếp web hiện có và cung cấp tích hợp với 13 web framework
    • Express, Hono, Fastify, Koa, NestJS, Elysia
    • Next.js, Nuxt, SvelteKit, Astro, SolidStart, Fresh
  • Middleware xử lý content negotiation, để cùng một URL có thể cung cấp HTML cho trình duyệt và JSON-LD cho fediverse
  • Kho lưu trữ riêng của Fedify chỉ yêu cầu một giao diện key-value
    • Có các adapter cho Redis, PostgreSQL, MySQL/MariaDB, SQLite, Deno KV, Cloudflare Workers KV và in-memory
  • Message queue có 8 lựa chọn, bao gồm PostgreSQL, Redis, AMQP/RabbitMQ, v.v.; nếu không có lựa chọn phù hợp, bạn có thể tự triển khai giao diện
  • Dữ liệu miền có thể được giữ nguyên trong cơ sở dữ liệu và ORM hiện có
  • Nếu bạn đã vận hành federation bằng thư viện khác, có thể chuyển từ activitypub-express và các thư viện tương tự mà không mất follower hiện có nhờ hướng dẫn migration và script migration dữ liệu
  • Cũng có các gói cấp cao hơn
    • @fedify/relay cung cấp một server ActivityPub relay hoàn chỉnh chỉ bằng một lần gọi hàm
    • @fedify/backfill đi theo fediverse và khôi phục các thread hội thoại chưa đầy đủ
  • Công cụ cho vòng lặp phát triển

    • fedify init scaffold dự án chỉ bằng một dòng
    • fedify tunnel phơi bày server cục bộ qua HTTPS để có thể thử nghiệm với Mastodon thật
    • fedify inbox khởi chạy một server inbox tạm thời để nhận các activity mà server gửi đi
    • fedify lookup cho phép kiểm tra các object do server khác đăng
    • fedify lookup --authorized-fetch tạo một cặp khóa dùng một lần, dựng server ActivityPub tạm thời và gửi request đã ký tới object nằm sau secure mode
    • @fedify/lint là linter chuyên dụng cho ActivityPub, bắt khoảng 20 lỗi tương tác liên thông như trường hợp actor không có inbox
    • Có thể chạy test không cần mạng bằng mock của @fedify/testing
    • @fedify/debugger gắn dashboard debug chỉ bằng một dòng, cho phép xem activity và kết quả xác minh chữ ký theo thời gian thực trong trình duyệt
    • Trong môi trường vận hành, instrumentation OpenTelemetry được tích hợp sẵn, cung cấp 28 loại span và 37 metric
    • Cũng có hướng dẫn monitoring và công cụ load test cho ActivityPub, fedify bench
    • Tài liệu chính thức gồm manual 30 chương và 5 tutorial, đề cập đến các thực hành thực tế như truy vấn PromQL và quy tắc cảnh báo để xem backlog của queue, cũng như các thuộc tính giúp avatar hiển thị trên Mastodon

Các ví dụ đã được sử dụng và cách bắt đầu

  • Fedify đang được dùng trong các dịch vụ thực tế
    • Dịch vụ ActivityPub của Ghost
    • Encyclia, kết nối hồ sơ nhà nghiên cứu ORCID với fediverse
    • SiliconBeest, chạy serverless trên Cloudflare Workers
    • Nền tảng blogging Hàn Quốc Typo Blue
    • Nền tảng microblogging một người dùng Hollo
    • Hackers' Pub do cộng đồng vận hành
  • Các tutorial cung cấp ví dụ theo quy mô
  • Mục tiêu của Fedify không phải là tạo ra thêm nhiều chuyên gia ActivityPub, mà là giúp nhà phát triển có thể xây dựng ứng dụng liên hợp mà không cần biết các chi tiết của ActivityPub
  • Lệnh bắt đầu là npm init @fedify
  • Nếu cần trợ giúp, có thể dùng Matrix room hoặc GitHub Discussions

1 bình luận

 
Ý kiến trên Lobste.rs
  • Đây là lý do các dự án ActivityPub có nhiều fork của nhau như vậy: hiểu cách tiếp cận của người khác còn dễ hơn là tự triển khai toàn bộ
    Điều tác giả đề xuất thực ra cũng không có vẻ khác mấy so với các fork của Misskey hay Pleroma thường thấy. Bản thân thư viện cũng có góc nhìn và cách tiếp cận riêng, và có vẻ không trao nhiều quyền kiểm soát. Dù vậy, ưu điểm là nó không ép luôn cả UI như khi fork cả máy chủ
    Ở góc độ người đang triển khai AP, phần khó nhất là không có cách tốt để dùng JSON-LD cho đúng nghĩa. Nếu có thể dễ dàng chuyển đối tượng sang biểu diễn chuẩn thì khả năng tương tác tự nhiên sẽ theo sau, nhưng dùng nó như tài liệu liên kết thực thụ thì quá kém hiệu quả, còn dùng như tài liệu JSON thô thì chết chìm trong vô số trường hợp ngoại lệ. Từ trước đến giờ tôi chọn cách thứ hai và đã bị hành lên bờ xuống ruộng

    • Đặc biệt khi nghĩ đến chữ ký, vấn đề “biểu diễn chuẩn của đối tượng” lại càng quan trọng hơn. Chuẩn hóa XML ngày xưa tồn tại chính vì vấn đề chữ ký này, tức là để bảo đảm chuỗi byte được tuần tự hóa ở phía nhận khớp với phía gửi
      Dù không hoàn toàn là cùng một vấn đề với thế giới JSON-LD, nhưng cũng không hề vô can
      Tuy vậy, tôi nghĩ khá nhiều công nghệ lân cận JSON cũng gặp vấn đề tương tự. Có quá nhiều cách làm JSON Schema để biểu diễn cùng một lược đồ logic, vì thế việc tương tác với hệ công nghệ xung quanh JSON Schema trở nên khủng khiếp đến mức nực cười. Đặc biệt, lược đồ OpenAPI là một kiểu kinh dị na ná nhưng không hoàn toàn giống vậy, và kể cả không tính đến số lượng phiên bản bản thảo của lược đồ thì mọi thứ cũng đã đủ tệ rồi
    • Tôi đã nghĩ đến việc triển khai một máy chủ AP nhưng vẫn chưa bắt tay vào làm, nên hãy nghe với mức độ dè dặt cao. Một điều có thể giúp là chia ứng dụng thành các dịch vụ nhỏ hơn, rồi dựa nhiều hơn vào mô hình actor để khiến chúng trông như một giao diện “hợp nhất”. Chẳng hạn có thể học từ việc tách MTA và MUA của máy chủ email
      Dịch vụ “MTA” của AP sẽ phụ trách gửi thông điệp từ hộp thư đi và nhận thông điệp vào hộp thư đến. Tài liệu JSON-LD, từ góc nhìn của dịch vụ này, gần như chỉ là dữ liệu dạng khối. Cần một chút phân tích để tìm ra bên gửi và bên nhận, nhưng ngoài ra không nhiều. Phần lưu trữ cũng có thể là dạng tệp; nếu nhớ không nhầm thì go-ap làm theo kiểu đó
      “MUA” của AP là ứng dụng thực tế. Đây là phía cần hiểu ngữ nghĩa JSON-LD. Có thể dùng thứ như PostgreSQL để lưu tài liệu dưới dạng jsonb, rồi dùng cột sinh ra và view để cung cấp dạng thân thiện với SQL. Khi đó có thể quyết định cách biểu diễn tài liệu phù hợp nhất tùy theo loại đối tượng
      Một ví dụ khác là cũng có thể mô hình hóa dịch vụ tìm kiếm như một actor để nó trả kết quả vào một hộp thư đi tạm thời
  • Đây là một danh sách rất quý giá, tổng hợp các hành vi kỳ quặc và cách giảm nhẹ của nhiều implementation
    Tiếc là GoActivityPub vẫn chưa triển khai được đến một nửa trong số đó

  • Ban đầu bài viết đi vào kỹ thuật nên tôi thấy biết ơn, nhưng từ giữa bài trở đi có vẻ nó rẽ sang quảng bá framework của chính tác giả nên làm giảm hứng đọc
    May là trong một vài cộng đồng dùng TypeScript, có thể họ sẽ không cần tái khám phá lại các dị điểm khi triển khai này. Nhưng nếu có một bản ghi ở mức mô hình tinh thần kiểu “trong điều kiện và tình huống này sẽ cho ra kết quả như vậy, và cần sửa thế này”, thì ngay cả trong bối cảnh không dùng TypeScript, ví dụ tác giả của dự án anh em GoActivityPub, cũng có thể hưởng thành quả của những gian khổ đó. Ở đây bài có đề cập vài thứ như vậy, nhưng bài viết chỉ là ảnh chụp tại một thời điểm, còn dự án thì theo thời gian dường như đang tích lũy mọi lỗi tương tác được có thể
    Theo tôi, lựa chọn hiện tại là phải đọc toàn bộ các commit message không giống do con người viết, rồi cố phân biệt đâu là lỗi riêng của Fedify và đâu là lỗi tương tác
    Điều mỉa mai là kho mã trông như đã “all-in” với AI mà lại không làm sổ cái kiểu đó. Những gì được quảng bá về LLM là nó tự động hóa việc lặp đi lặp lại. Vậy thì cứ để Claude tạo GitHub issue, hoặc tốt hơn nữa là viết các tệp .md trong kho mã để ghi lại các kết quả quan sát được và Fedify sửa chúng ra sao. Đã có cả trình gỡ lỗi riêng và cả “best practice” mà chẳng rõ nghĩa gì, nên đây đúng là việc quá hợp

    • Họ thực sự thổi phồng một vấn đề rất nhỏ rồi trình bày như thể đó là sự thất bại của ActivityPub. Ví dụ, nếu có 5.000 người theo dõi thì một bài đăng sẽ thành hàng nghìn lượt gửi HTTP, và nếu làm trực tiếp việc này trong request handler thì phản hồi nút đăng sẽ mất 30 giây hoặc máy chủ sập, nên hãy dùng queue, đại loại vậy
      Tại sao lại thực hiện request gửi sang dịch vụ bên thứ ba theo kiểu inline? Đây là kiến thức cơ bản của ứng dụng web. Nếu phải giao tiếp với dịch vụ bên thứ ba thì hãy đẩy sang background job. Nếu đó không phải thông tin cần để trả response cho request thì hãy đẩy sang background job. Những vấn đề phát sinh khi làm mấy request kiểu này trong request handler là kiểu tự mình dẫm phải cào rồi bị cán vào mặt, chứ chẳng liên quan gì đến ActivityPub
      Nếu việc chuyển phát thất bại thì phải retry, lên lịch thế nào, có dùng exponential backoff không, dùng mấy lần, có coi 500 Internal Server Error và 410 Gone là cùng một kiểu thất bại hay không — tất cả những thứ đó đơn giản chỉ là các vấn đề phát triển ứng dụng web thông thường. Đó là vấn đề nảy sinh khi dùng job queue để gọi dịch vụ bên thứ ba, không liên quan đến ActivityPub. Phần lớn framework web đều có mặc định hợp lý. Chỉ đến chỗ cần quyết định có retry hay không tùy vào loại lỗi thì mới cần phán đoán. Retry với 410 thì là lãng phí, nhưng cũng không phải vấn đề cấp bách. Nó sẽ làm tăng áp lực bộ nhớ của job queue, nhưng khó có khả năng làm ứng dụng sập trong vài giờ
  • “Xem có bị từ chối không, rồi ký lại theo cách khác, rồi ghi nhớ cách nào hiệu quả với từng máy chủ” — thật sự không hiểu mình đang đọc cái gì nữa. Đây có phải vì thế mà việc phát triển Mastodon chậm chạp không?
    “Một bài đăng thành hàng nghìn lượt gửi HTTP”, lại còn được nói trong Ruby, ngôn ngữ nổi tiếng vì rất giỏi lập trình hệ thống mạng và queueing
    Khó mà tin nổi, và đúng là việc bọc nó thành thư viện thì tốt, nhưng vẫn thấy sao sao

  • Sau khi từng triển khai ActivityPub bằng Java, tôi đi đến kết luận rằng các giao thức liên máy chủ kiểu này tốt hơn hết nên xây trên git
    Một phần lớn của sự phức tạp tồn tại chỉ để giải lại những vấn đề mà git vốn đã xử lý tốt hơn. Nếu mô hình hóa nó thành các tài liệu JSON trong một kho git thì không cần xử lý phân trang. Giao thức tự nó đã bảo đảm chỉ gửi dữ liệu còn thiếu, có luôn chữ ký commit, có luôn bảo đảm thứ tự sự kiện, giải quyết được các vấn đề bài viết này nhắc đến, và còn có lịch sử miễn phí. Có lẽ có thể đặt ra một biến thể của định luật thứ mười của Greenspun rằng các giao thức kiểu này chứa một nửa bản cài đặt git chậm chạp và đầy lỗi

    • git phụ thuộc lịch sử vào commit cha nên không phải lựa chọn xuất sắc. Tuy vậy, một giao thức gossip cây Merkle hoạt động bằng chiến lược thương lượng tương tự có thể sẽ rất phù hợp
  • Bài này đọc như một bài viết chất lượng thấp do AI tạo ra
    Cụ thể hơn, tôi không hiểu tại sao lại viết theo kiểu kể chuyện. Các thông tin truyền tải ở đây đáng ra có thể viết ngắn gọn hơn nhiều và bớt thiên lệch hơn, mà phần tự sự cũng không thuyết phục. Đặc biệt là có rất nhiều kiểu diễn đạt rất đặc trưng của AI
    Đọc không thấy thích thú. Dù vậy, vẫn cảm ơn vì đã chỉ ra các vấn đề, và hy vọng có thể đọc cũng như sửa các vấn đề đó theo một cách khác