About Discourse

Discussion on Federation support for Discourse.

2 Likes

thanks for the link here, really excited to see Discourse moving in this direction.

Reading what you’re hoping to achieve for v1, here are some quick thoughts:

ActivityPub (server to server) is a push-based, actor-based protocol. like WebSub, which it partially evolved out of, it’s based around users subscribing to activities (using Follow) and getting notified when they occur (using inbox distribution). there are other ways for actors to interact, but this is the most fundamental and the lowest common denominator in terms of what is actually implemented.

so just providing ActivitySteams 2.0 versions of your content, while a good first step, isn’t enough to get things federating to another platform—you’ll also need a concept of remote users and allow those remote users to Follow local actors

another assumption that might be a little tricky for discourse is that most current ActivityPub implementations assume that the actors create content and then distribute it to their own followers list—discourse works slightly differently, where actors (users) create content and then distribute it to another actor’s following list (the forum’s or thread’s). Making this work correctly, and with the right semantics, is a little tricky, and it’s something other projects have taken a stab at, but I think we’ll probably need to hash out a good, solid solution for this going forward, and it’ll require some tweaking of existing implementations.

3 Likes

Just a note that Software > Discourse is now following #activitypub on meta.discourse.org. There is actually a backfill feature in the Discourse plugin to bring the existing activitypub content from meta.discourse.org here to socialhub. @how please run this command in the terminal for this server

# ssh into the server
cd /var/discourse
./launcher enter app
rake "activity_pub:process[discourse@socialhub.activitypub.rocks, activitypub@meta.discourse.org]"
1 Like

Here is the result:

rake activity_pub:process...
[Discourse Activity Pub] discourse@socialhub.activitypub.rocks started processing the activities of activitypub@meta.discourse.org.
[Discourse Activity Pub] Created 4 actors.
[Discourse Activity Pub] Updated 2 actors.
[Discourse Activity Pub] Created 5 users.
[Discourse Activity Pub] Updated 1 user.
rake aborted!
ActiveRecord::RecordNotUnique: PG::UniqueViolation: ERROR:  duplicate key value violates unique constraint "unique_activity_pub_actor_models" (ActiveRecord::RecordNotUnique)
DETAIL:  Key (model_type, model_id)=(User, 939) already exists.
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/rack-mini-profiler-3.3.1/lib/patches/db/pg.rb:69:in `exec_params'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/rack-mini-profiler-3.3.1/lib/patches/db/pg.rb:69:in `exec_params'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/activerecord-7.2.2.1/lib/active_record/connection_adapters/postgresql_adapter.rb:894:in `block (2 levels) in exec_no_cache'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/activerecord-7.2.2.1/lib/active_record/connection_adapters/abstract_adapter.rb:1004:in `block in with_raw_connection'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/activesupport-7.2.2.1/lib/active_support/concurrency/null_lock.rb:9:in `synchronize'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/activerecord-7.2.2.1/lib/active_record/connection_adapters/abstract_adapter.rb:976:in `with_raw_connection'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/activerecord-7.2.2.1/lib/active_record/connection_adapters/postgresql_adapter.rb:893:in `block in exec_no_cache'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/activesupport-7.2.2.1/lib/active_support/notifications/instrumenter.rb:58:in `instrument'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/activerecord-7.2.2.1/lib/active_record/connection_adapters/abstract_adapter.rb:1119:in `log'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/activerecord-7.2.2.1/lib/active_record/connection_adapters/postgresql_adapter.rb:892:in `exec_no_cache'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/activerecord-7.2.2.1/lib/active_record/connection_adapters/postgresql_adapter.rb:872:in `execute_and_clear'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/activerecord-7.2.2.1/lib/active_record/connection_adapters/postgresql/database_statements.rb:66:in `internal_exec_query'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/activerecord-7.2.2.1/lib/active_record/connection_adapters/abstract/database_statements.rb:177:in `exec_insert_all'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/activerecord-7.2.2.1/lib/active_record/connection_adapters/abstract/query_cache.rb:27:in `exec_insert_all'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/activerecord-7.2.2.1/lib/active_record/insert_all.rb:54:in `execute'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/activerecord-7.2.2.1/lib/active_record/insert_all.rb:13:in `block in execute'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/activerecord-7.2.2.1/lib/active_record/connection_adapters/abstract/connection_pool.rb:415:in `with_connection'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/activerecord-7.2.2.1/lib/active_record/connection_handling.rb:296:in `with_connection'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/activerecord-7.2.2.1/lib/active_record/insert_all.rb:12:in `execute'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/activerecord-7.2.2.1/lib/active_record/relation.rb:904:in `upsert_all'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/activerecord-7.2.2.1/lib/active_record/querying.rb:24:in `upsert_all'
/var/www/discourse/plugins/discourse-activity-pub/lib/discourse_activity_pub/bulk/process.rb:265:in `create_users_from_actors'
/var/www/discourse/plugins/discourse-activity-pub/lib/discourse_activity_pub/bulk/process.rb:156:in `process_users'
/var/www/discourse/plugins/discourse-activity-pub/lib/discourse_activity_pub/bulk/process.rb:41:in `perform'
/var/www/discourse/plugins/discourse-activity-pub/lib/discourse_activity_pub/bulk/process.rb:51:in `perform'
/var/www/discourse/plugins/discourse-activity-pub/lib/tasks/activity_pub.rake:129:in `block in <main>'
/usr/local/bin/bundle:25:in `load'
/usr/local/bin/bundle:25:in `<main>'

Caused by:
PG::UniqueViolation: ERROR:  duplicate key value violates unique constraint "unique_activity_pub_actor_models" (PG::UniqueViolation)
DETAIL:  Key (model_type, model_id)=(User, 939) already exists.
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/rack-mini-profiler-3.3.1/lib/patches/db/pg.rb:69:in `exec_params'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/rack-mini-profiler-3.3.1/lib/patches/db/pg.rb:69:in `exec_params'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/activerecord-7.2.2.1/lib/active_record/connection_adapters/postgresql_adapter.rb:894:in `block (2 levels) in exec_no_cache'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/activerecord-7.2.2.1/lib/active_record/connection_adapters/abstract_adapter.rb:1004:in `block in with_raw_connection'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/activesupport-7.2.2.1/lib/active_support/concurrency/null_lock.rb:9:in `synchronize'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/activerecord-7.2.2.1/lib/active_record/connection_adapters/abstract_adapter.rb:976:in `with_raw_connection'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/activerecord-7.2.2.1/lib/active_record/connection_adapters/postgresql_adapter.rb:893:in `block in exec_no_cache'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/activesupport-7.2.2.1/lib/active_support/notifications/instrumenter.rb:58:in `instrument'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/activerecord-7.2.2.1/lib/active_record/connection_adapters/abstract_adapter.rb:1119:in `log'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/activerecord-7.2.2.1/lib/active_record/connection_adapters/postgresql_adapter.rb:892:in `exec_no_cache'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/activerecord-7.2.2.1/lib/active_record/connection_adapters/postgresql_adapter.rb:872:in `execute_and_clear'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/activerecord-7.2.2.1/lib/active_record/connection_adapters/postgresql/database_statements.rb:66:in `internal_exec_query'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/activerecord-7.2.2.1/lib/active_record/connection_adapters/abstract/database_statements.rb:177:in `exec_insert_all'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/activerecord-7.2.2.1/lib/active_record/connection_adapters/abstract/query_cache.rb:27:in `exec_insert_all'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/activerecord-7.2.2.1/lib/active_record/insert_all.rb:54:in `execute'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/activerecord-7.2.2.1/lib/active_record/insert_all.rb:13:in `block in execute'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/activerecord-7.2.2.1/lib/active_record/connection_adapters/abstract/connection_pool.rb:415:in `with_connection'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/activerecord-7.2.2.1/lib/active_record/connection_handling.rb:296:in `with_connection'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/activerecord-7.2.2.1/lib/active_record/insert_all.rb:12:in `execute'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/activerecord-7.2.2.1/lib/active_record/relation.rb:904:in `upsert_all'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/activerecord-7.2.2.1/lib/active_record/querying.rb:24:in `upsert_all'
/var/www/discourse/plugins/discourse-activity-pub/lib/discourse_activity_pub/bulk/process.rb:265:in `create_users_from_actors'
/var/www/discourse/plugins/discourse-activity-pub/lib/discourse_activity_pub/bulk/process.rb:156:in `process_users'
/var/www/discourse/plugins/discourse-activity-pub/lib/discourse_activity_pub/bulk/process.rb:41:in `perform'
/var/www/discourse/plugins/discourse-activity-pub/lib/discourse_activity_pub/bulk/process.rb:51:in `perform'
/var/www/discourse/plugins/discourse-activity-pub/lib/tasks/activity_pub.rake:129:in `block in <main>'
/usr/local/bin/bundle:25:in `load'
/usr/local/bin/bundle:25:in `<main>'
Tasks: TOP => activity_pub:process
(See full trace by running task with --trace)

Thanks, I’ll check what might have caused the record duplication and circle back.