-
Notifications
You must be signed in to change notification settings - Fork 197
How to set rankings (and reputation in general) using a background job?
Rank rules can be run in the background, for instance running a small rake task as part of a cron job. Create a file lib/tasks/cron.rake
like:
task :daily_cron_job => :environment do
Merit::RankRules.new.check_rank_rules
end
Then run rake daily_cron_job
as part of a daily cron job (or hourly,however you need), and it will compute rankings regularly.
Or you can use Crono Gem, which would simplify this process. You can add this rule to an active job and run using Crono like so:
app/jobs/check_merit_rules_job.rb
class CheckMeritRankRulesJob < ActiveJob::Base
def perform
ActiveRecord::Base.connection_pool.with_connection do
Merit::RankRules.new.check_rank_rules
end
end
end
config/cronotab.rb
Crono.perform(CheckMeritRankRulesJob).every 5.minutes #configure time
Note: If you are using Crono make sure the ActiveJob perform block doesn't take any arguments.(Merit doesn't need arguments anyway)
The rankings are ran on the a whole database scope and not only on some entries, and because they tend to need more information/computing that would take too long to compute as part of an HTTP request.
If you configure merit to not check badge/point rules on each request (checks_on_each_request
) you'll need to check them in the background. The configuration for this is available in merit initializer file config/initializers/merit.rb
Behind the scenes, merit uses an after_filter on every meritable controller action and logs it into merit_actions table which makes it flexible to process Badge/Point rules later. You can read related code here L10
The call for checking unprocessed jobs is:
Merit::Action.check_unprocessed
Therefore, it makes it very flexible to run merit rules through a background job. Here is how you can configure Merit to use a background job (Same as rankings)
app/jobs/check_unprocessed_merit_rules_job.rb
class CheckUnprocessedMeritRulesJob < ActiveJob::Base
def perform
ActiveRecord::Base.connection_pool.with_connection do
Merit::Action.check_unprocessed
end
end
end
config/cronotab.rb
Crono.perform(CheckUnprocessedMeritRulesJob).every 5.minutes #configure time as it fits your app needs
A little tip on performance: Use redis sorted sets to store points and rankings for each user and whenever ranking/points updates after computation use redis pub/sub to push updates in realtime without compromising performance.