Ich versuche, Benutzerkonten zusammenzuführen

Ich bin auf ein Problem gestoßen und dachte, ich teile meine Erkenntnisse hier, falls sie jemandem helfen, der es ebenfalls erlebt.

In meinem Fall hing der Account-Merge-Vorgang ewig mit dem Dialog “Merge progress” (Merge-Fortschritt), der zwischen den Meldungen “Changing post ownership…” (Ändere Beitragseigentümer…) und “Updating username…” (Aktualisiere Benutzernamen…) hin und her wechselte.

Beim Betrachten der Staff Action Logs (/admin/logs/staff_action_logs) konnte ich sehen, dass, obwohl die Eigentümerschaft vieler Beiträge unmittelbar nach dem Auslösen des Merges übertragen wurde, keine weiteren Aktionen stattfanden. Dies beweist, dass der Vorgang wirklich feststeckte und nicht nur sehr lange dauerte, um alle Beiträge zu bearbeiten.

Als ich die Error Logs (/logs/) überprüfte, sah ich, dass periodisch ein Fehler vom Typ “Job exception: topic” auftrat, mit folgendem Backtrace:

/var/www/discourse/app/services/post_owner_changer.rb:12:in `block in initialize'
/var/www/discourse/app/services/post_owner_changer.rb:11:in `each'
/var/www/discourse/app/services/post_owner_changer.rb:11:in `initialize'
/var/www/discourse/app/services/user_merger.rb:84:in `new'
/var/www/discourse/app/services/user_merger.rb:84:in `change_post_owner'
/var/www/discourse/app/services/user_merger.rb:72:in `block in move_posts'
/var/www/discourse/app/services/user_merger.rb:70:in `each'
/var/www/discourse/app/services/user_merger.rb:70:in `move_posts'
/var/www/discourse/app/services/user_merger.rb:14:in `merge!'
/var/www/discourse/app/jobs/regular/merge_user.rb:15:in `execute'
/var/www/discourse/app/jobs/base.rb:316:in `block (2 levels) in perform'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/rails_multisite-6.1.0/lib/rails_multisite/connection_management/null_instance.rb:49:in `with_connection'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/rails_multisite-6.1.0/lib/rails_multisite/connection_management.rb:21:in `with_connection'
/var/www/discourse/app/jobs/base.rb:303:in `block in perform'
/var/www/discourse/app/jobs/base.rb:299:in `each'
/var/www/discourse/app/jobs/base.rb:299:in `perform'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/processor.rb:220:in `execute_job'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/processor.rb:185:in `block (4 levels) in process'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/middleware/chain.rb:180:in `traverse'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/middleware/chain.rb:183:in `block in traverse'
/var/www/discourse/lib/sidekiq/discourse_event.rb:6:in `call'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/middleware/chain.rb:182:in `traverse'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/middleware/chain.rb:183:in `block in traverse'
/var/www/discourse/lib/sidekiq/pausable.rb:131:in `call'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/middleware/chain.rb:182:in `traverse'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/middleware/chain.rb:183:in `block in traverse'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/job/interrupt_handler.rb:9:in `call'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/middleware/chain.rb:182:in `traverse'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/middleware/chain.rb:183:in `block in traverse'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/metrics/tracking.rb:26:in `track'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/metrics/tracking.rb:134:in `call'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/middleware/chain.rb:182:in `traverse'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/middleware/chain.rb:173:in `invoke'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/processor.rb:184:in `block (3 levels) in process'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/processor.rb:145:in `block (6 levels) in dispatch'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/job_retry.rb:118:in `local'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/processor.rb:144:in `block (5 levels) in dispatch'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/config.rb:39:in `block in <class:Config>'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/processor.rb:139:in `block (4 levels) in dispatch'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/processor.rb:281:in `stats'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/processor.rb:134:in `block (3 levels) in dispatch'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/job_logger.rb:15:in `call'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/processor.rb:133:in `block (2 levels) in dispatch'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/job_retry.rb:85:in `global'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/processor.rb:132:in `block in dispatch'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/job_logger.rb:40:in `prepare'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/processor.rb:131:in `dispatch'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/processor.rb:183:in `block (2 levels) in process'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/processor.rb:182:in `handle_interrupt'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/processor.rb:182:in `block in process'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/processor.rb:181:in `handle_interrupt'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/processor.rb:181:in `process'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/processor.rb:86:in `process_one'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/processor.rb:76:in `run'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/component.rb:10:in `watchdog'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/component.rb:19:in `block in safe_thread'

und die Umgebung wie folgt:

hostname    [...]
process_id    701
application_version    3146142c2ed2c880d53b2f8c136af9f46df99b59
current_db    default
current_hostname    forum.arduino.cc
job    Jobs::MergeUser
problem_db    default
time    8:15 am
opts
user_id    42
target_user_id    123
current_user_id    456
current_site_id    default

Ich stellte schließlich fest, dass das Hängen durch das “verwaiste” Beiträge des “Von”-Accounts verursacht wurde. Mit “verwaist” meine ich, dass ein Datenbankeintrag für den Beitrag existierte, aber kein Eintrag für das Thema, das mit diesem Beitrag verbunden war.

Sie können das Vorhandensein von “verwaisten Beiträgen” im Account eines bestimmten Benutzers überprüfen, indem Sie diese Data Explorer Abfrage ausführen:

-- [params]
-- integer :user_id

SELECT
  posts.id,
  posts.topic_id
FROM
  posts
WHERE
  posts.user_id = :user_id
  AND posts.topic_id NOT IN (
    SELECT
      topics.id
    FROM
      topics
  )

Nachdem die verwaisten Beiträge aus der Datenbank entfernt wurden (dank der Hilfe des Discourse-Teams, da wir einen Hosting-Plan nutzen), konnte ich den Account-Merge-Vorgang erfolgreich abschließen.

3 „Gefällt mir“