Project

jobler

0.0
No release in over 3 years
Generate pages or files in the background
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
 Dependencies

Runtime

>= 6.0.0
 Project Readme

Jobler

Jobler helps you generate large reports or very large and slow pages through background jobs.

Install

Add it to your Gemfile and bundle it:

gem "jobler"

Install the migrations and run them:

rake railties:install:migrations
rake db:migrate

Add it to your routes:

mount Jobler::Engine => "/jobler"

Autoload the "Joblers" you are going to write through application.rb:

config.autoload_paths << Rails.root.join("app", "joblers")

Add a ApplicationJobler to follow the ApplicationController and ApplicationRecord pattern:

class ApplicationJobler < Jobler::BaseJobler
end

Jobler is going to queue its jobs through the ActiveJob queue called :jobler, so make sure a worker is listening to that queue. This is done like this in Sidekiq:

bundle exec sidekiq --queue default --queue jobler --queue mailers

Usage

Write a new Jobler located in "app/joblers":

class MyJobler < ApplicationJobler
  # This method will be executed in the background
  def execute!
    my_temp_file = Tempfile.new

    # Do some heavy lifting code wise...

    create_result!(name: "my-file", temp_file: my_temp_file)
  end

  # This method will be called from the web when the execute is completed and successful
  def result
    Jobler::FileDownload.new(
      file_name: "some-file.zip",
      temp_file: temp_file_for_result(name: "my-file")
    )
  end
end

You can do something like this in your controller:

class MyController < Jobler::BaseController
  def some_action
    scheduler = Jobler::JobScheduler.create! jobler_type: "MyJobler", job_args: {
      current_user_id: current_user.id,
      query_parameters: request.query_parameters
    }

    redirect_to jobler.job_path(scheduler.job)
  end
end

This will show a wait page and them a complete page with a download link, once the job is completed.

Rendering views

First add a special controller that your Jobler's can use:

class ApplicationJoblerController < ApplicationController
end

Then call render from within the execute method:

class TestRenderJobler < Jobler::BaseJobler
  def execute!
    create_result!(
      name: "render",
      content: render(:show)
    )
  end

  def result
    Jobler::RedirectTo.new(url: "/jobler_jobs/jobs/#{job.to_param}")
  end
end

This will render the view located at "app/joblers/test_render_jobler/show.*"

You should then create a controller something like this:

class JoblerJobsController < ApplicationController
  def show
    @job = Jobler::Job.find_by!(slug: params[:id])
    @result = @job.results.find_by!(name: "render")
  end
end

And a view in "app/views/jobler_jobs/show.html.erb":

<%= @result.result.force_encoding("utf-8").html_safe %>

You should also add a route like this:

Rails.application.routes.draw do
  resources :jobler_jobs, only: :show
end

Progress bar

In order to utilize the progress bar and return some feedback on the progress to the user, you can implement a couple of calls to do that:

class MyJobler < ApplicationJobler
  def execute!
    progress_total collection.size
    
    collection.find_each do |model|
      increment_progress!
    end
  end
end

You can also call it from a view, if you a doing a render like this:

<% jobler.increment_progress! %>

You can also specify a custom value if it isn't 1:

<% jobler.increment_progress!(value: 5.0) %>

License

This project rocks and uses MIT-LICENSE.