Commit 46ba67eb2b514c47f5b3de7e4ddffaf4ab2d30d9

Authored by Victor Costa
1 parent 09952f2a

Process ranking in an async job

lib/proposals_discussion_plugin.rb
... ... @@ -52,4 +52,7 @@ class ProposalsDiscussionPlugin < Noosfero::Plugin
52 52 [ProposalsDiscussionPlugin::API]
53 53 end
54 54  
  55 + # schedule ranking job in initialization process
  56 + ProposalsDiscussionPlugin::RankingJob.new.schedule
  57 +
55 58 end
... ...
lib/proposals_discussion_plugin/api.rb
... ... @@ -5,13 +5,9 @@ class ProposalsDiscussionPlugin::API < Grape::API
5 5 paginate per_page: 10, max_per_page: 20
6 6 get ':id/ranking' do
7 7 article = find_article(environment.articles, params[:id])
8   - ranking = Rails.cache.fetch("#{article.cache_key}/proposals_ranking", expires_in: 30.minutes) do
9   - #FIXME call update_ranking in an async job
10   - article.update_ranking
11   - {:proposals => article.ranking, :updated_at => DateTime.now}
12   - end
13   - ranking[:proposals] = paginate ranking[:proposals]
14   - ranking
  8 + current_page = paginate(article.ranking)
  9 + #FIXME find a better way to get updated_at date
  10 + {:proposals => current_page, :updated_at => current_page.blank? ? DateTime.now : current_page.first.updated_at}
15 11 end
16 12  
17 13 post ':id/propose' do
... ...
lib/proposals_discussion_plugin/ranking_job.rb 0 → 100644
... ... @@ -0,0 +1,36 @@
  1 +class ProposalsDiscussionPlugin::RankingJob
  2 +
  3 + def perform
  4 + ProposalsDiscussionPlugin::Topic.find_each do |topic|
  5 + ProposalsDiscussionPlugin::RankingJob::TopicRankingJob.new(topic.id).schedule
  6 + end
  7 + schedule(30.minutes.from_now)
  8 + end
  9 +
  10 + def schedule(run_at = nil)
  11 + Delayed::Job.enqueue(self, {:run_at => run_at}) unless self.class.find_job.exists?
  12 + end
  13 +
  14 + def self.find_job
  15 + Delayed::Job.by_handler("--- !ruby/object:ProposalsDiscussionPlugin::RankingJob {}\n")
  16 + end
  17 +
  18 +
  19 + class TopicRankingJob < Struct.new(:topic_id)
  20 +
  21 + def perform
  22 + topic = ProposalsDiscussionPlugin::Topic.find_by_id(topic_id)
  23 + topic.update_ranking if topic.present?
  24 + end
  25 +
  26 + def schedule
  27 + Delayed::Job.enqueue(self) unless find_job.exists?
  28 + end
  29 +
  30 + def find_job
  31 + Delayed::Job.by_handler("--- !ruby/struct:ProposalsDiscussionPlugin::RankingJob::TopicRankingJob\ntopic_id: #{topic_id}\n")
  32 + end
  33 +
  34 + end
  35 +
  36 +end
... ...
test/unit/api_test.rb
... ... @@ -30,10 +30,12 @@ class APITest &lt; ActiveSupport::TestCase
30 30 2.times { Vote.create!(:voteable => proposal3, :voter => nil, :vote => 1) }
31 31  
32 32 proposal1.update_attribute(:hits, 5)
  33 + process_delayed_job_queue
33 34  
34 35 get "/api/v1/proposals_discussion_plugin/#{topic.id}/ranking?#{params.to_query}"
35 36 json = JSON.parse(last_response.body)
36 37 assert_equal [proposal2.abstract, proposal3.abstract, proposal1.abstract], json['proposals'].map {|p| p['abstract']}
  38 + assert json['updated_at'].to_datetime <= Time.now
37 39 end
38 40  
39 41 should 'suggest article children' do
... ...
test/unit/ranking_job_test.rb 0 → 100644
... ... @@ -0,0 +1,56 @@
  1 +require_relative '../test_helper'
  2 +
  3 +class RankingJobTest < ActiveSupport::TestCase
  4 +
  5 + def setup
  6 + @job = ProposalsDiscussionPlugin::RankingJob.new
  7 + @topic = fast_create(ProposalsDiscussionPlugin::Topic)
  8 + @proposal = fast_create(ProposalsDiscussionPlugin::Proposal, :parent_id => topic.id)
  9 + end
  10 +
  11 + attr_accessor :job, :topic, :proposal
  12 +
  13 + should 'create ranking job in initialization' do
  14 + assert job.class.find_job.exists?
  15 + end
  16 +
  17 + should 'do not create duplicated ranking job' do
  18 + job.schedule
  19 + job.schedule
  20 + assert_equal 1, job.class.find_job.count
  21 + end
  22 +
  23 + should 'schedule topic jobs when performed' do
  24 + job.perform
  25 + assert ProposalsDiscussionPlugin::RankingJob::TopicRankingJob.new(topic.id).find_job.exists?
  26 + end
  27 +
  28 + should 'reschedule job when performed' do
  29 + process_delayed_job_queue
  30 + job.perform
  31 + new_job = job.class.find_job.first
  32 + assert new_job.present?
  33 + assert new_job.run_at > 20.minutes.from_now
  34 + end
  35 +
  36 + should 'schedule topic job' do
  37 + topic_job = ProposalsDiscussionPlugin::RankingJob::TopicRankingJob.new(topic.id)
  38 + topic_job.schedule
  39 + assert topic_job.find_job.exists?
  40 + end
  41 +
  42 + should 'do not schedule duplicated topic job' do
  43 + topic_job = ProposalsDiscussionPlugin::RankingJob::TopicRankingJob.new(topic.id)
  44 + topic_job.schedule
  45 + topic_job.schedule
  46 + assert_equal 1, topic_job.find_job.count
  47 + end
  48 +
  49 + should 'perform topic job' do
  50 + job.schedule
  51 + assert_equal 0, topic.ranking.count
  52 + process_delayed_job_queue
  53 + assert_equal 1, topic.ranking.count
  54 + end
  55 +
  56 +end
... ...