フォローアップ: プラグイン競合の割り当て

以前、Discourse の最新バージョンへのアップグレード時に問題が発生しました。これは、Assign プラグインと本番環境データに関する問題であり、@angus 氏によって特定され、プラグインを削除することで解決されました。

今後は、このプラグインを再導入したいと考えていますが、以前経験したゲームを停止させるエラーが再び発生する可能性を排除する必要があります。以下は、問題が発生していた際のログ抜粋に関する詳細です。

/var/www/discourse/plugins/discourse-assign/plugin.rb:284:in `block (2 levels) in activate!’

バックトレース:

> /var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rack-mini-profiler-1.0.2/lib/patches/db/pg.rb:69:in `async_exec_params'
> /var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rack-mini-profiler-1.0.2/lib/patches/db/pg.rb:69:in `exec_params'
> /var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.3/lib/active_record/connection_adapters/postgresql_adapter.rb:611:in `block (2 levels) in exec_no_cache'
> /var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activesupport-5.2.3/lib/active_support/dependencies/interlock.rb:48:in `block in permit_concurrent_loads'
> /var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activesupport-5.2.3/lib/active_support/concurrency/share_lock.rb:187:in `yield_shares'
> /var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activesupport-5.2.3/lib/active_support/dependencies/interlock.rb:47:in `permit_concurrent_loads'
> /var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.3/lib/active_record/connection_adapters/postgresql_adapter.rb:610:in `block in exec_no_cache'
> /var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.3/lib/active_record/connection_adapters/abstract_adapter.rb:581:in `block (2 levels) in log'
> /usr/local/lib/ruby/2.6.0/monitor.rb:230:in `mon_synchronize'
> /var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.3/lib/active_record/connection_adapters/abstract_adapter.rb:580:in `block in log'
> /var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activesupport-5.2.3/lib/active_support/notifications/instrumenter.rb:23:in `instrument'
> /var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.3/lib/active_record/connection_adapters/abstract_adapter.rb:571:in `log'
> /var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.3/lib/active_record/connection_adapters/postgresql_adapter.rb:609:in `exec_no_cache'
> /var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.3/lib/active_record/connection_adapters/postgresql_adapter.rb:596:in `execute_and_clear'
> /var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.3/lib/active_record/connection_adapters/postgresql/database_statements.rb:81:in `exec_query'
> /var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.3/lib/active_record/connection_adapters/abstract/database_statements.rb:478:in `select'
> /var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.3/lib/active_record/connection_adapters/abstract/database_statements.rb:70:in `select_all'
> /var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.3/lib/active_record/connection_adapters/abstract/query_cache.rb:104:in `block in select_all'
> /var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.3/lib/active_record/connection_adapters/abstract/query_cache.rb:127:in `block in cache_sql'
> /usr/local/lib/ruby/2.6.0/monitor.rb:230:in `mon_synchronize'
> /var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.3/lib/active_record/connection_adapters/abstract/query_cache.rb:113:in `cache_sql'
> /var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.3/lib/active_record/connection_adapters/abstract/query_cache.rb:104:in `select_all'
> /var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.3/lib/active_record/connection_adapters/abstract/database_statements.rb:77:in `select_one'
> /var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.3/lib/active_record/relation/finder_methods.rb:322:in `block in exists?'
> /var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.3/lib/active_record/relation.rb:584:in `skip_query_cache_if_necessary'
> /var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.3/lib/active_record/relation/finder_methods.rb:322:in `exists?'
> /var/www/discourse/plugins/discourse-assign/plugin.rb:69:in `block (2 levels) in activate!'
> /var/www/discourse/lib/plugin/instance.rb:188:in `public_send'
> /var/www/discourse/lib/plugin/instance.rb:188:in `block (2 levels) in add_to_class'
> /var/www/discourse/plugins/discourse-assign/plugin.rb:284:in `block (2 levels) in activate!'
> (eval):49:in `_fast_attributes'
> /var/www/discourse/vendor/bundle/ruby/2.6.0/gems/active_model_serializers-0.8.4/lib/active_model/serializer.rb:456:in `attributes'
> /var/www/discourse/vendor/bundle/ruby/2.6.0/gems/active_model_serializers-0.8.4/lib/active_model/serializer.rb:480:in `_serializable_hash'
> /var/www/discourse/vendor/bundle/ruby/2.6.0/gems/active_model_serializers-0.8.4/lib/active_model/serializer.rb:359:in `serializable_hash'
> /var/www/discourse/vendor/bundle/ruby/2.6.0/gems/active_model_serializers-0.8.4/lib/active_model/serializer.rb:347:in `as_json'
> /var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activesupport-5.2.3/lib/active_support/json/encoding.rb:22:in `encode'
> /var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activesupport-5.2.3/lib/active_support/json/encoding.rb:22:in `encode'
> /var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activesupport-5.2.3/lib/active_support/core_ext/object/json.rb:41:in `to_json'
> /var/www/discourse/vendor/bundle/ruby/2.6.0/gems/active_model_serializers-0.8.4/lib/active_model/serializer.rb:331:in `to_json'
> /var/www/discourse/vendor/bundle/ruby/2.6.0/gems/multi_json-1.13.1/lib/multi_json/adapters/oj.rb:40:in `dump'
> /var/www/discourse/vendor/bundle/ruby/2.6.0/gems/multi_json-1.13.1/lib/multi_json/adapters/oj.rb:40:in `dump'
> /var/www/discourse/vendor/bundle/ruby/2.6.0/gems/multi_json-1.13.1/lib/multi_json/adapter.rb:25:in `dump'
> /var/www/discourse/vendor/bundle/ruby/2.6.0/gems/multi_json-1.13.1/lib/multi_json.rb:139:in `dump'
> /var/www/discourse/app/controllers/application_controller.rb:535:in `preload_current_user_data'
> /var/www/discourse/app/controllers/application_controller.rb:354:in `preload_json'
> /var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activesupport-5.2.3/lib/active_support/callbacks.rb:426:in `block in make_lambda'
> /var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activesupport-5.2.3/lib/active_support/callbacks.rb:198:in `block (2 levels) in halting'
> /var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-5.2.3/lib/abstract_controller/callbacks.rb:34:in `block (2 levels) in <module:Callbacks>'
> /var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activesupport-5.2.3/lib/active_support/callbacks.rb:199:in `block in halting'
> /var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activesupport-5.2.3/lib/active_support/callbacks.rb:513:in `block in invoke_before'
> /var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activesupport-5.2.3/lib/active_support/callbacks.rb:513:in `each'
> /var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activesupport-5.2.3/lib/active_support/callbacks.rb:513:in `invoke_before'
> /var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activesupport-5.2.3/lib/active_support/callbacks.rb:131:in `run_callbacks'
> /var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-5.2.3/lib/abstract_controller/callbacks.rb:41:in `process_action'
> /var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-5.2.3/lib/action_controller/metal/rescue.rb:22:in `process_action'
> /var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-5.2.3/lib/action_controller/metal/instrumentation.rb:34:in `block in process_action'
> /var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activesupport-5.2.3/lib/active_support/notifications.rb:168:in `block in instrument'
> /var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activesupport-5.2.3/lib/active_support/notifications/instrumenter.rb:23:in `instrument'
> /var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activesupport-5.2.3/lib/active_support/notifications.rb:168:in `instrument'
> /var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-5.2.3/lib/action_controller/metal/instrumentation.rb:32:in `process_action'
> /var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-5.2.3/lib/action_controller/metal/params_wrapper.rb:256:in `process_action'
> /var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.3/lib/active_record/railties/controller_runtime.rb:24:in `process_action'
> /var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-5.2.3/lib/abstract_controller/base.rb:134:in `process'
> /var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionview-5.2.3/lib/action_view/rendering.rb:32:in `process'
> /var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rack-mini-profiler-1.0.2/lib/mini_profiler/profiling_methods.rb:78:in `block in profile_method'
> /var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-5.2.3/lib/action_controller/metal.rb:191:in `dispatch'
> /var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-5.2.3/lib/action_controller/metal.rb:252:in `dispatch'
> /var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-5.2.3/lib/action_dispatch/routing/route_set.rb:52:in `dispatch'
> /var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-5.2.3/lib/action_dispatch/routing/route_set.rb:34:in `serve'
> /var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-5.2.3/lib/action_dispatch/journey/router.rb:52:in `block in serve'
> /var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-5.2.3/lib/action_dispatch/journey/router.rb:35:in `each'
> /var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-5.2.3/lib/action_dispatch/journey/router.rb:35:in `serve'
> /var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-5.2.3/lib/action_dispatch/routing/route_set.rb:840:in `call'
> /var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rack-protection-2.0.5/lib/rack/protection/frame_options.rb:31:in `call'
> /var/www/discourse/lib/middleware/omniauth_bypass_middleware.rb:68:in `call'
> /var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rack-2.0.7/lib/rack/tempfile_reaper.rb:15:in `call'
> /var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rack-2.0.7/lib/rack/conditional_get.rb:25:in `call'
> /var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rack-2.0.7/lib/rack/head.rb:12:in `call'
> /var/www/discourse/lib/content_security_policy/middleware.rb:12:in `call'
> /var/www/discourse/lib/middleware/anonymous_cache.rb:220:in `call'
> /var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rack-2.0.7/lib/rack/session/abstract/id.rb:232:in `context'
> /var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rack-2.0.7/lib/rack/session/abstract/id.rb:226:in `call'
> /var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-5.2.3/lib/action_dispatch/middleware/cookies.rb:670:in `call'
> /var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-5.2.3/lib/action_dispatch/middleware/callbacks.rb:28:in `block in call'
> /var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activesupport-5.2.3/lib/active_support/callbacks.rb:98:in `run_callbacks'
> /var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-5.2.3/lib/action_dispatch/middleware/callbacks.rb:26:in `call'
> /var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-5.2.3/lib/action_dispatch/middleware/debug_exceptions.rb:61:in `call'
> /var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-5.2.3/lib/action_dispatch/middleware/show_exceptions.rb:33:in `call'
> /var/www/discourse/vendor/bundle/ruby/2.6.0/gems/logster-2.3.0/lib/logster/middleware/reporter.rb:30:in `call'
> /var/www/discourse/vendor/bundle/ruby/2.6.0/gems/railties-5.2.3/lib/rails/rack/logger.rb:38:in `call_app'
> /var/www/discourse/vendor/bundle/ruby/2.6.0/gems/railties-5.2.3/lib/rails/rack/logger.rb:28:in `call'
> /var/www/discourse/config/initializers/100-quiet_logger.rb:18:in `call'
> /var/www/discourse/config/initializers/100-silence_logger.rb:31:in `call'
> /var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-5.2.3/lib/action_dispatch/middleware/remote_ip.rb:81:in `call'
> /var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-5.2.3/lib/action_dispatch/middleware/request_id.rb:27:in `call'
> /var/www/discourse/lib/middleware/enforce_hostname.rb:17:in `call'
> /var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rack-2.0.7/lib/rack/method_override.rb:22:in `call'
> /var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-5.2.3/lib/action_dispatch/middleware/executor.rb:14:in `call'
> /var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rack-2.0.7/lib/rack/sendfile.rb:111:in `call'
> /var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rack-mini-profiler-1.0.2/lib/mini_profiler/profiler.rb:171:in `call'
> /var/www/discourse/vendor/bundle/ruby/2.6.0/gems/message_bus-2.2.2/lib/message_bus/rack/middleware.rb:57:in `call'
> /var/www/discourse/lib/middleware/request_tracker.rb:169:in `call'
> /var/www/discourse/vendor/bundle/ruby/2.6.0/gems/railties-5.2.3/lib/rails/engine.rb:524:in `call'
> /var/www/discourse/vendor/bundle/ruby/2.6.0/gems/railties-5.2.3/lib/rails/railtie.rb:190:in `public_send'
> /var/www/discourse/vendor/bundle/ruby/2.6.0/gems/railties-5.2.3/lib/rails/railtie.rb:190:in `method_missing'
> /var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rack-2.0.7/lib/rack/urlmap.rb:68:in `block in call'
> /var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rack-2.0.7/lib/rack/urlmap.rb:53:in `each'
> /var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rack-2.0.7/lib/rack/urlmap.rb:53:in `call'
> /var/www/discourse/vendor/bundle/ruby/2.6.0/gems/unicorn-5.5.1/lib/unicorn/http_server.rb:605:in `process_client'
> /var/www/discourse/vendor/bundle/ruby/2.6.0/gems/unicorn-5.5.1/lib/unicorn/http_server.rb:700:in `worker_loop'
> /var/www/discourse/vendor/bundle/ruby/2.6.0/gems/unicorn-5.5.1/lib/unicorn/http_server.rb:548:in `spawn_missing_workers'
> /var/www/discourse/vendor/bundle/ruby/2.6.0/gems/unicorn-5.5.1/lib/unicorn/http_server.rb:144:in `start'
> /var/www/discourse/vendor/bundle/ruby/2.6.0/gems/unicorn-5.5.1/bin/unicorn:128:in `<top (required)>'
> /var/www/discourse/vendor/bundle/ruby/2.6.0/bin/unicorn:23:in `load'
> /var/www/discourse/vendor/bundle/ruby/2.6.0/bin/unicorn:23:in `<main>'

情報:

> ActiveRecord::StatementInvalid (PG::InvalidTextRepresentation: ERROR: invalid input syntax for integer: "admins"
> LINE 1: …p_users"."user_id" = 15040 AND (groups.id in ('3','admins','…
> ^
> : SELECT 1 AS one FROM "groups" INNER JOIN "group_users" ON "groups"."id" = "group_users"."group_id" WHERE "group_users"."user_id" = 15040 AND (groups.id in ('3','admins','RDSE')) LIMIT 1)
> /var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rack-mini-profiler-1.0.2/lib/patches/db/pg.rb:69:in `async_exec_params'

進捗のために他に必要となる情報があればお知らせください。よろしくお願いいたします。

ごめんなさい、意味がわかりません。何をめぐる対立ですか?

「group id 3 admins」で正しいですか?

@Mittineague 今朝確認したところ、管理者のグループ ID はデフォルトのグループ ID であることが確かでした。

記載したログ情報はダウンタイム中のものです。Assign プラグインを一時的に削除したところ、即座に問題が解決し、Discourse を正常に再利用できるようになりました。

assign_allowed_on_groups サイト設定の値が不正な状態です。グループ名からグループ ID への移行が行われました。

(groups.id in (‘3’,‘admins’,'…

admins をグループ ID に置き換えることで、この問題を解決できます。

それをどのように変更すればよいでしょうか?

Discourse フォルダから、以下の手順を実行してください:

  • ./launcher enter app を実行してコンテナに进入
  • rails c を実行して Rails コンソールを起動

コンソール内で、このスクリプトを実行して問題を解決できます:

allowed_groups = SiteSetting.assign_allowed_on_groups.split('|')
allowed_groups.map! do |ag| 
  ag.to_i.to_s == ag ? ag : Group.select(:id).find_by(name: ag).id
end

SiteSetting.assign_allowed_on_groups = allowed_groups.join('|')

上記の推奨手順を実行しましたが、スクリプトを正常に実行できませんでした。以下はその試行の出力結果です。ご助言をいただければ幸いです :pray:

app:/var/www/discourse# rails c

[1] pry(main)> allowed_groups = SiteSetting.assign_allowed_on_groups.split('|')

NoMethodError: undefined method `assign_allowed_on_groups' for #<Class:0x0000563ec4670260>

from /var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.3/lib/active_record/dynamic_matchers.rb:22:in `method_missing'

[2] pry(main)> allowed_groups.map! do |ag|

[2] pry(main)* ag.to_i.to_s == ag ? ag : Group.select(:id).find_by(name: ag).id

[2] pry(main)* end

NoMethodError: undefined method `map!' for nil:NilClass

from (pry):2:in `__pry__'

[3] pry(main)> SiteSetting.assign_allowed_on_groups = allowed_groups.join('|')

NoMethodError: undefined method `join' for nil:NilClass

from (pry):5:in `__pry__'

Discourse assign の古いバージョンがインストールされているように見えますが… 最新の discourse assign を使用して tests-passed を実行していますか?

@sam について調べて、見つかったことをお知らせします :+1:

現在、Assign プラグインが削除されているため、@sam さん、最新版でプラグインを再インストールするのが最善の策だとお考えですか?

@sam @angus 今夜、Assign プラグインを再度再インストールしようとしたところ、サインイン後に完全に失敗しました。失敗のログをキャプチャしましたが、公開したくはないため、DM で共有することは可能です。


次にどう進めるべきか、ご提案はありますか?

安定版ブランチを使用していますか?競合を引き起こしている可能性のある他のプラグインはインストールされていますか?

Masterからプルしたので、そうだと思います。

以下のものだけです。私には目立つようなものはありません。

安定ブランチ(望ましくない方)に所属するには、何らかの作業を行う必要があります。app.yml に以下のような記述がありますか?

version: stable

もし stable に所属している場合、対応がより複雑になる可能性があります。

./discourse-doctor を実行してみるか、または再ビルドする前に git pull を行うことを確認してください。

57%20PM

これが私の App.yml で表示されているものです

Assign プラグインの進展を支援するための追加アイデアはありますか?@angus

@Jim.Morrison さん、こんにちは。

以下のコマンドをコンソールで実行して、その出力結果を教えてください。

DB.query_single(<<~SQL).first.to_s.split('|')
  SELECT site_settings.value FROM site_settings WHERE site_settings.name = 'assign_allowed_on_groups'
SQL

私のスクリプトが機能しなかったのは、プラグインが無効になっていたからだと思われます。

コンソールから詳細をダイレクトメッセージでお送りしました。ありがとうございます、@Romanさん

@Roman とこの件について何度かやり取りした結果、ついに解決できました!

Roman が記述したクエリを実行してデータ競合を解消し、Assign プラグインを追加してアプリを再ビルドしたところ、無事に成功しました!

この一連のトラブルを通じて、Roman は非常に大きな貢献をしてくれました。彼への称賛は尽きません!@Roman、この件で私と一緒に取り組んでいただき、本当にありがとうございます!