Feedback on the new Review Queue

You’re right. The review queue sort error happens because there are Akismet reviewables in the database after the plugin was removed. I see two possible solutions here:

  1. Provide a rake task to remove these rows from the database before the user decides to remove the plugin permanently.
  2. Apply a default scope to the Reviewable class that excludes these rows if the plugin is disabled.

What do you think?

4 Likes

One other thing, images seem to be invisible in the editor preview if you edit a queued topic/post.

2 Likes

Does it happen when the post is waiting for review? Or after rejecting it? As I said earlier, uploads of rejected queued posts are automatically removed by the system.

3 Likes

Yeah it’s when they are waiting in review @Roman_Rizzi, the images are invisible to me in the editor preview.

2 Likes

I think plugin uninstallation is rare, and the default scope thing is more likely to introduce bugs.

I think it would be reasonable if we added a rake task, then put it in the README under an “uninstallation” section with instructions to execute it to remove the old records. Let’s do that!

4 Likes

I’ve tried disabling ‘notify about queued posts after’ by setting it to 0 and also 2000000000. I’m still getting lots of frequent ‘x items need to be reviewed’ notification messages. :face_with_monocle:


1 Like

The system is sending them because there are pending items in the queue. The setting you changed is for queued posts reminders, set notify_about_flags_after to 0 instead.

6 Likes

This task is now available. You can remove all the plugin related records from the database by doing:

bundle exec rake akismet_uninstall:delete_reviewables

Make sure to have the plugin installed and have read the uninstallation section of the README:

7 Likes

Thanks @Roman_Rizzi - I can confirm that modifying notify_about_flags_after to 0 stopped the notifications :smiley:

Really appreciate adding the rake task for this! I’ll reinstall Akismet and run the rake task later today when traffic is at low peak, then update this post with the results.

4 Likes

Have any thoughts regarding this? @Roman_Rizzi @eviltrout

It seems that users who are having their posts go directly to the review queue can bypass quite a few rate limits for topic and post/reply creation.

Rate limit options that seem to be bypassable:
rate limit create topic, rate limit new user create topic, max topics per day, rate limit create post, rate limit new user create post, unique posts mins, max consecutive replies.

As well as bump prevention with the no bump plugin: Discourse-no-bump: prevent users from bumping topics

Send topics & posts directly to review queue options:
‘approve post count’ (new users needing their first topics/posts approved) as well as the individual category options of ‘Require moderator approval of all new topics’ and most likely (I’ve only tested the new topics option) ‘Require moderator approval of all new replies’.

1 Like

Yes, this is by design. If your post is reviewed and deemed acceptable it will be posted, regardless of limits.

7 Likes

Ahh, I see. Thanks for the explanation. Will just share my experiences with it for reference.

Without the limits being enforced, it’s allowing new users (approve post count) to freely flood the review queue with no or minimal limits while older trusted accounts are limited by the rate limits. Except when the category options for approving all topics or replies are enabled, then older trusted users have no or minimal limits too.

It’d be quite a lot of work, but fairly achievable to approve all new topics, as well as the initial topics/posts created by new users (if rate limited), but it’s close to unviable in my case when users can flood the queue.

Anyhow, thanks a lot for the clarification that this is by design. It’s very helpful. I think that I’ll revise my strategy and disable the options which send topics or posts directly to the review queue, reserving it mainly for flagged content. Then simply moderate the rate limited live submissions after the fact, should work nicely and be more fast paced for users too.

1 Like

So I went ahead and reinstalled Akismet and ran the rake task. My process was:

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

I received an error unfortunately, tried running it a few times:

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
(See full trace by running task with --trace)
1 Like

Could you try switching to the discourse user by running su discourse before executing the task?

4 Likes

Thanks @Roman_Rizzi! Much appreciated :slight_smile:

I tried again using su discourse before running the rake task and it worked perfectly. :tada:

The ‘Created At (reverse)’ sorting is working well now as well.

3 Likes

I have recently set invite only site setting and now there is an item in the review queue generated by system for a user account, marked as Needs Approval.

The strange thing is that this is an existing (4 years old) account with multiple posts and TL2, but it has not been active lately (last post was 2 years ago), but it has logged in today, after which the review flag was raised.

I have not used the Approve User yet, and the item is still in the review queue, but it seems that the account is enabled and able to use the forum (as it should).

It seems that the review queue is identifying recently reactivated account as new account and marking it for review when invite only is set?

Edit: this also happened now for a very recent account, created only days before this setting was enabled.

1 Like

I think I’ve seen this before when you switch to invite only. In some situations Discourse thinks you need to approve the user because they gained access to the site by signing up regularly. When that toggle is changed their record has no “Approved” flag set.

3 Likes

I’ve investigated this further, and the only thing these accounts (four in total) have in common is that they all logged in using one of the email login paths (via forgot_password or directly by email_login) after the invite_only was set.

2 Likes

Has there been any thoughts to adding suspend to review topics/posts flagged by Akismet? It has been suggested on our instance, simply because we’re SSO, so deleting members rarely does any good, the member can just re-login to their account on the primary provider and they are instantly logged into the forums to continue on their way. Suspending makes them work harder as they have to create a new account on the provider with a new email address.

I know, its a bit of a weird request, but one that my moderators ask about fairly frequently. Today, they manually go around the system to suspend the user, so it creates extra effort for them to do so, but is worth it because the user ultimately isn’t willing to throwaway another email address.

6 Likes

I think it would need to be a drop-down button, rather than adding a ton of additional buttons.

4 Likes