Home > Net >  How can I run a sidekiq worker a certain number of times per day, based on database column?
How can I run a sidekiq worker a certain number of times per day, based on database column?

Time:01-11

My Project model:

class Project < ApplicationRecord
  enum :number_of_samples, { once_per_day: 0, three_times_per_day: 1, hourly: 2 }, prefix: true
  
  belongs_to :project_owner, polymorphic: true
  has_many :metrics, dependent: :destroy
  has_one_attached :sitemap, dependent: :destroy

  validates :number_of_samples, presence: true
  validates :sitemap, presence: true, blob: { content_type: ['application/xml'], size_range: 1..(5.megabytes) }

  def attach_sitemap(sitemap_params)
    sitemap = ActiveStorage::Blob.create_and_upload!(
      io: sitemap_params[:io],
      filename: sitemap_params[:filename],
      content_type: sitemap_params[:content_type]
    )
    self.sitemap.attach(sitemap)
  end

  def sitemap_path
    ActiveStorage::Blob.service.path_for(sitemap.key)
  end
end

The sidekiq worker:

class PagespeedWorker
  include Sidekiq::Worker
  
  def perform
    puts 'Beginning Fetching...'
    projects = Project.all.order(created_at: :desc)
    projects.each do |project|
      sitemap_path = project.sitemap_path
      sitemap = SitemapParseService.call(sitemap_path)
      sitemap.each do |url|
        retrieve_data(url, 'desktop', project.id)
        retrieve_data(url, 'mobile', project.id)
      end
    end
    puts 'Fetching done!'
  end

  def retrieve_data(url, strategy, project_id)
    puts 'Pagespeed external call...'
    pagespeed_response = PagespeedService.call(url, strategy)
    puts 'Parsing Pagespeed response...'
    relevant_data = PagespeedParseService.call(pagespeed_response)
    puts 'Storing the relevant data...'
    PagespeedStore.call(relevant_data, strategy, url, project_id)
  end
end

Every project has a sitemap uploaded, with all the urls for a website.
For every url, there should be 2 external API calls to Pagespeed Insights, for desktop and mobile.
I want to be able to run the worker, based on the number_of_samples in the Project model.
It should run for every project, for every url in every project's sitemap, the number of times per day specified in the number_of_samples field.

CodePudding user response:

You can use the number_of_samples property to loop

Sample code

projects.each do |project|
  project.number_of_samples.times do
    sitemap_path = project.sitemap_path
    sitemap = SitemapParseService.call(sitemap_path)
    sitemap.each do |url|
      retrieve_data(url, 'desktop', project.id)
      retrieve_data(url, 'mobile', project.id)
    end
  end
end
  • Related