Feedback on the new Review Queue (2019)

Вы правы. Ошибка сортировки очереди рецензий возникает из-за того, что в базе данных остаются записи для рецензирования от плагина Akismet после его удаления. Я вижу два возможных решения:

  1. Предоставить задачу Rake для удаления этих записей из базы данных до того, как пользователь решит навсегда удалить плагин.
  2. Применить область действия по умолчанию к классу Reviewable, которая исключает эти записи, если плагин отключен.

Что вы думаете?

4 лайка

Ещё один момент: при редактировании темы/поста из очереди изображения в предпросмотре редактора кажутся невидимыми.

2 лайка

Это происходит, пока пост ожидает проверки? Или после его отклонения? Как я уже говорил ранее, загрузка отклонённых постов из очереди автоматически удаляется системой.

3 лайка

Да, это когда они находятся в ожидании проверки, @Roman. В предпросмотре редактора изображения для меня невидимы.

2 лайка

Я считаю, что удаление плагинов — редкая ситуация, а механизм области видимости по умолчанию с большей вероятностью приведёт к появлению ошибок.

Будет разумно добавить задачу Rake и разместить её в README в разделе «Удаление» с инструкциями по её выполнению для очистки старых записей. Давайте так и сделаем!

4 лайка

Я пробовал отключить «уведомлять о постх в очереди после», установив значение 0, а также 2000000000. Но я всё ещё получаю множество частых уведомлений «x элементов требуют проверки». :face_with_monocle:


1 лайк

Система отправляет их, потому что в очереди есть ожидающие элементы. Настройка, которую вы изменили, относится к напоминаниям о постах в очереди. Вместо этого установите notify_about_flags_after в 0.

6 лайков

Эта задача теперь доступна. Вы можете удалить все записи, связанные с плагином, из базы данных, выполнив:

bundle exec rake akismet_uninstall:delete_reviewables

Убедитесь, что плагин установлен, и ознакомьтесь с разделом «Удаление» в README:

7 лайков

Спасибо, @Roman! Могу подтвердить, что изменение параметра notify_about_flags_after на 0 остановило уведомления :smiley:

Очень благодарен за добавление rake-задачи для этого! Я переустановлю Akismet и запущу rake-задачу позже сегодня, когда трафик будет на минимуме, а затем обновлю этот пост с результатами.

4 лайка

Есть какие-то мысли по этому поводу? @Roman @eviltrout

Похоже, что пользователи, чьи сообщения сразу попадают в очередь на проверку, могут обойти довольно много ограничений по частоте действий при создании тем и сообщений/ответов.

Параметры ограничений по частоте, которые, как кажется, можно обойти:
ограничение на создание тем, ограничение на создание тем новыми пользователями, максимальное количество тем в день, ограничение на создание сообщений, ограничение на создание сообщений новыми пользователями, минимальный интервал между уникальными сообщениями, максимальное количество последовательных ответов.

А также предотвращение поднятия тем с помощью плагина no bump: Discourse No Bump - #26

Параметры для отправки тем и сообщений сразу в очередь на проверку:
«approve post count» (новые пользователи, которым требуется одобрение их первых тем/сообщений), а также индивидуальные параметры категорий «Требовать одобрения модератором всех новых тем» и, скорее всего (я тестировал только вариант для новых тем), «Требовать одобрения модератором всех новых ответов».

1 лайк

Да, это сделано намеренно. Если ваше сообщение будет проверено и признано приемлемым, оно будет опубликовано, независимо от ограничений.

7 лайков

Ах, я понял. Спасибо за объяснение. Просто поделюсь своим опытом для справки.

Без принудительного соблюдения лимитов новые пользователи (с одобрением по количеству постов) могут свободно заваливать очередь на модерацию с нулевыми или минимальными ограничениями, в то время как старые доверенные аккаунты ограничены лимитами скорости. Исключение — когда включены опции категории для одобрения всех тем или ответов, тогда и старые доверенные пользователи также не имеют ограничений или имеют минимальные.

Это потребовало бы довольно много работы, но было бы вполне реализуемо одобрять все новые темы, а также начальные темы/посты, созданные новыми пользователями (если они ограничены по скорости). Однако в моём случае это почти невозможно, если пользователи могут заваливать очередь.

В любом случае, большое спасибо за разъяснение, что это сделано намеренно. Это очень помогло. Думаю, я пересмотрю свою стратегию и отключу опции, которые отправляют темы или посты напрямую в очередь на модерацию, оставив её в основном для помеченного контента. Тогда просто модерировать ограниченные по скорости живые публикации постфактум будет работать отлично и будет более динамичным для пользователей.

1 лайк

Итак, я переустановил Akismet и запустил задачу rake. Мой процесс был следующим:

cd /var/discourse
./launcher enter app
bundle exec rake akismet_uninstall:delete_reviewables

К сожалению, я получил ошибку и попробовал запустить это несколько раз:

rake aborted!
ActiveRecord::NoDatabaseError: FATAL:  Peer authentication failed for user "discourse"
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.3.1/lib/active_record/connection_adapters/postgresql_adapter.rb:50:in `rescue in postgresql_connection'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.3.1/lib/active_record/connection_adapters/postgresql_adapter.rb:33:in `postgresql_connection'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.3.1/lib/active_record/connection_adapters/abstract/connection_pool.rb:887:in `new_connection'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.3.1/lib/active_record/connection_adapters/abstract/connection_pool.rb:931:in `checkout_new_connection'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.3.1/lib/active_record/connection_adapters/abstract/connection_pool.rb:910:in `try_to_checkout_new_connection'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.3.1/lib/active_record/connection_adapters/abstract/connection_pool.rb:871:in `acquire_connection'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.3.1/lib/active_record/connection_adapters/abstract/connection_pool.rb:593:in `checkout'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.3.1/lib/active_record/connection_adapters/abstract/connection_pool.rb:437:in `connection'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.3.1/lib/active_record/connection_adapters/abstract/connection_pool.rb:1119:in `retrieve_connection'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.3.1/lib/active_record/connection_handling.rb:221:in `retrieve_connection'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.3.1/lib/active_record/connection_handling.rb:189:in `connection'
/var/www/discourse/lib/site_settings/db_provider.rb:61:in `table_exists?'
/var/www/discourse/lib/site_settings/db_provider.rb:16:in `all'
/var/www/discourse/lib/site_settings/defaults_provider.rb:29:in `db_all'
/var/www/discourse/lib/site_setting_extension.rb:287:in `block in refresh!'
/var/www/discourse/lib/site_setting_extension.rb:284:in `synchronize'
/var/www/discourse/lib/site_setting_extension.rb:284:in `refresh!'
/var/www/discourse/lib/site_setting_extension.rb:505:in `block in setup_methods'
/var/www/discourse/config/initializers/004-message_bus.rb:120:in `<main>'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/bootsnap-1.4.6/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:55:in `load'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/bootsnap-1.4.6/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:55:in `load'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activesupport-6.0.3.1/lib/active_support/dependencies.rb:318:in `block in load'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activesupport-6.0.3.1/lib/active_support/dependencies.rb:291:in `load_dependency'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activesupport-6.0.3.1/lib/active_support/dependencies.rb:318:in `load'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/railties-6.0.3.1/lib/rails/engine.rb:666:in `block in load_config_initializer'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activesupport-6.0.3.1/lib/active_support/notifications.rb:182:in `instrument'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/railties-6.0.3.1/lib/rails/engine.rb:665:in `load_config_initializer'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/railties-6.0.3.1/lib/rails/engine.rb:625:in `block (2 levels) in <class:Engine>'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/railties-6.0.3.1/lib/rails/engine.rb:624:in `each'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/railties-6.0.3.1/lib/rails/engine.rb:624:in `block in <class:Engine>'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/railties-6.0.3.1/lib/rails/initializable.rb:32:in `instance_exec'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/railties-6.0.3.1/lib/rails/initializable.rb:32:in `run'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/railties-6.0.3.1/lib/rails/initializable.rb:61:in `block in run_initializers'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/railties-6.0.3.1/lib/rails/initializable.rb:50:in `each'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/railties-6.0.3.1/lib/rails/initializable.rb:50:in `tsort_each_child'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/railties-6.0.3.1/lib/rails/initializable.rb:60:in `run_initializers'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/railties-6.0.3.1/lib/rails/application.rb:363:in `initialize!'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/railties-6.0.3.1/lib/rails/railtie.rb:190:in `public_send'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/railties-6.0.3.1/lib/rails/railtie.rb:190:in `method_missing'
/var/www/discourse/config/environment.rb:7:in `<main>'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/bootsnap-1.4.6/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:23:in `require'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/bootsnap-1.4.6/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:23:in `block in require_with_bootsnap_lfi'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/bootsnap-1.4.6/lib/bootsnap/load_path_cache/loaded_features_index.rb:92:in `register'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/bootsnap-1.4.6/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:22:in `require_with_bootsnap_lfi'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/bootsnap-1.4.6/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:31:in `require'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/zeitwerk-2.3.0/lib/zeitwerk/kernel.rb:23:in `require'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activesupport-6.0.3.1/lib/active_support/dependencies.rb:324:in `block in require'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activesupport-6.0.3.1/lib/active_support/dependencies.rb:291:in `load_dependency'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activesupport-6.0.3.1/lib/active_support/dependencies.rb:324:in `require'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/railties-6.0.3.1/lib/rails/application.rb:339:in `require_environment!'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/railties-6.0.3.1/lib/rails/application.rb:523:in `block in run_tasks_blocks'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rake-13.0.1/exe/rake:27:in `<top (required)>'
/usr/local/bin/bundle:23:in `load'
/usr/local/bin/bundle:23:in `<main>'

Caused by:
PG::ConnectionBad: FATAL:  Peer authentication failed for user "discourse"
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/pg-1.2.3/lib/pg.rb:58:in `initialize'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/pg-1.2.3/lib/pg.rb:58:in `new'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/pg-1.2.3/lib/pg.rb:58:in `connect'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.3.1/lib/active_record/connection_adapters/postgresql_adapter.rb:46:in `postgresql_connection'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.3.1/lib/active_record/connection_adapters/abstract/connection_pool.rb:887:in `new_connection'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.3.1/lib/active_record/connection_adapters/abstract/connection_pool.rb:931:in `checkout_new_connection'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.3.1/lib/active_record/connection_adapters/abstract/connection_pool.rb:910:in `try_to_checkout_new_connection'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.3.1/lib/active_record/connection_adapters/abstract/connection_pool.rb:871:in `acquire_connection'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.3.1/lib/active_record/connection_adapters/abstract/connection_pool.rb:593:in `checkout'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.3.1/lib/active_record/connection_adapters/abstract/connection_pool.rb:437:in `connection'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.3.1/lib/active_record/connection_adapters/abstract/connection_pool.rb:1119:in `retrieve_connection'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.3.1/lib/active_record/connection_handling.rb:221:in `retrieve_connection'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activerecord-6.0.3.1/lib/active_record/connection_handling.rb:189:in `connection'
/var/www/discourse/lib/site_settings/db_provider.rb:61:in `table_exists?'
/var/www/discourse/lib/site_settings/db_provider.rb:16:in `all'
/var/www/discourse/lib/site_settings/defaults_provider.rb:29:in `db_all'
/var/www/discourse/lib/site_setting_extension.rb:287:in `block in refresh!'
/var/www/discourse/lib/site_setting_extension.rb:284:in `synchronize'
/var/www/discourse/lib/site_setting_extension.rb:284:in `refresh!'
/var/www/discourse/lib/site_setting_extension.rb:505:in `block in setup_methods'
/var/www/discourse/config/initializers/004-message_bus.rb:120:in `<main>'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/bootsnap-1.4.6/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:55:in `load'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/bootsnap-1.4.6/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:55:in `load'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activesupport-6.0.3.1/lib/active_support/dependencies.rb:318:in `block in load'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activesupport-6.0.3.1/lib/active_support/dependencies.rb:291:in `load_dependency'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activesupport-6.0.3.1/lib/active_support/dependencies.rb:318:in `load'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/railties-6.0.3.1/lib/rails/engine.rb:666:in `block in load_config_initializer'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activesupport-6.0.3.1/lib/active_support/notifications.rb:182:in `instrument'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/railties-6.0.3.1/lib/rails/engine.rb:665:in `load_config_initializer'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/railties-6.0.3.1/lib/rails/engine.rb:625:in `block (2 levels) in <class:Engine>'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/railties-6.0.3.1/lib/rails/engine.rb:624:in `each'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/railties-6.0.3.1/lib/rails/engine.rb:624:in `block in <class:Engine>'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/railties-6.0.3.1/lib/rails/initializable.rb:32:in `instance_exec'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/railties-6.0.3.1/lib/rails/initializable.rb:32:in `run'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/railties-6.0.3.1/lib/rails/initializable.rb:61:in `block in run_initializers'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/railties-6.0.3.1/lib/rails/initializable.rb:50:in `each'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/railties-6.0.3.1/lib/rails/initializable.rb:50:in `tsort_each_child'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/railties-6.0.3.1/lib/rails/initializable.rb:60:in `run_initializers'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/railties-6.0.3.1/lib/rails/application.rb:363:in `initialize!'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/railties-6.0.3.1/lib/rails/railtie.rb:190:in `public_send'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/railties-6.0.3.1/lib/rails/railtie.rb:190:in `method_missing'
/var/www/discourse/config/environment.rb:7:in `<main>'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/bootsnap-1.4.6/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:23:in `require'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/bootsnap-1.4.6/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:23:in `block in require_with_bootsnap_lfi'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/bootsnap-1.4.6/lib/bootsnap/load_path_cache/loaded_features_index.rb:92:in `register'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/bootsnap-1.4.6/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:22:in `require_with_bootsnap_lfi'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/bootsnap-1.4.6/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:31:in `require'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/zeitwerk-2.3.0/lib/zeitwerk/kernel.rb:23:in `require'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activesupport-6.0.3.1/lib/active_support/dependencies.rb:324:in `block in require'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activesupport-6.0.3.1/lib/active_support/dependencies.rb:291:in `load_dependency'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activesupport-6.0.3.1/lib/active_support/dependencies.rb:324:in `require'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/railties-6.0.3.1/lib/rails/application.rb:339:in `require_environment!'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/railties-6.0.3.1/lib/rails/application.rb:523:in `block in run_tasks_blocks'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rake-13.0.1/exe/rake:27:in `<top (required)>'
/usr/local/bin/bundle:23:in `load'
/usr/local/bin/bundle:23:in `<main>'
Tasks: TOP => akismet_uninstall:delete_reviewables => environment
(Полный трассировочный стек можно получить, запустив задачу с флагом --trace)
1 лайк

Попробуйте переключиться на пользователя discourse, выполнив команду su discourse, прежде чем запускать задачу.

4 лайка

Спасибо, @Roman! Очень ценю :slight_smile:

Я снова попробовал, выполнив su discourse перед запуском задачи rake, и всё сработало отлично. :tada:

Сортировка «Дата создания (по убыванию)» теперь тоже работает корректно.

3 лайка

Я недавно установил параметр сайта «только по приглашениям», и теперь в очереди на проверку, сгенерированной системой для учётной записи пользователя, появился элемент, помеченный как «Требует одобрения».

Странно то, что это существующая учётная запись (ей 4 года) с несколькими сообщениями и уровнем доверия TL2, но она не была активна в последнее время (последнее сообщение было 2 года назад). Однако сегодня пользователь вошёл в систему, после чего была поднята флаг на проверку.

Я ещё не использовал функцию «Одобрить пользователя», и элемент всё ещё находится в очереди на проверку, но, похоже, учётная запись активирована и может использовать форум (как и должно быть).

Кажется, очередь на проверку определяет недавно реактивированные учётные записи как новые и помечает их на проверку, когда установлен параметр «только по приглашениям»?

Редакция: это также произошло сейчас для очень новой учётной записи, созданной всего за несколько дней до включения этого параметра.

1 лайк

Кажется, я видел это раньше, когда вы переключаетесь на режим «только по приглашениям». В некоторых ситуациях Discourse считает, что пользователя нужно утвердить, потому что он получил доступ к сайту через обычную регистрацию. Когда этот переключатель меняется, в его записи не установлен флаг «Утверждён».

3 лайка

Я провёл дополнительное расследование и выяснил, что единственное, что объединяет эти учётные записи (всего четыре), — это то, что все они вошли в систему через один из путей входа по электронной почте (через forgot_password или напрямую через email_login) после того, как был установлен режим invite_only.

2 лайка

Были ли какие-либо размышления о добавлении опции приостановки для тем/постов в очереди, помеченных Akismet? Это предложение поступило на нашем экземпляре, просто потому что у нас используется SSO, поэтому удаление участников редко приносит пользу: участник может просто снова войти в свою учётную запись у основного провайдера и мгновенно получить доступ к форуму, чтобы продолжить свои дела. Приостановка же усложняет им задачу, так как им придётся создать новую учётную запись у провайдера с новым адресом электронной почты.

Я знаю, что это немного странная просьба, но о ней мои модераторы спрашивают довольно часто. Сегодня они вручную обходят систему, чтобы приостановить пользователя, что создаёт для них дополнительную работу, но это того стоит, поскольку пользователь в конечном итоге не готов отказаться от ещё одного адреса электронной почты.

6 лайков

Думаю, это должен быть раскрывающийся список, а не множество дополнительных кнопок.

4 лайка