Code Monkey home page Code Monkey logo

sidekiq_portal's Introduction

Sidekiq::Portal Gem Version Build Status

hackaton slides: link

meetup slides: link

meetup video: link

Sidekiq::Portal - scheduled jobs runner for your test environments, which execution process must occur during the Timecop.travel(...) operations according to the scheduler config.

Each job starts at the time it was supposed to start according to the scheduler plan - the internal Time.current expression will give you exactly the scheduler-planned time.

Supports ActiveJob backend (Sidekiq::Worker coming soon). Works with sidekiq-scheduler-based job configs (sidekiq-cron coming soon).

Realized as an instance, but have a global-based implementation too.

Table of contents

Installation

  • in your Gemfile
gem 'sidekiq', '>= 5' # runtime dependency
gem 'timecop', '~> 0.9' # runtime dependency

group :test do
  gem 'rspec'
  gem 'sidekiq_portal'
end
  • run shell command:
bundle install
  • spec_helper.rb:
require 'timecop' # runtime dependency
require 'sidekiq' # runtime dependency
require 'sidekiq/api'
require 'sidekiq/testing'

require 'sidekiq_portal'

Configuration

  • default_timezone - global time zone for your jobs (UTC by default);
  • retry_count - Sidekiq's built-in retry mechanism simulation (0 by default);
  • retry_on - retry only on a set of exceptions ([StandardError] by default);
  • scheduler_config - sidekiq-scheduler-based scheduler configuration ({} by default (non-configured));
  • Sidekiq::Portal.reload!(&configuration) - reload portal configurations;

In your spec_helper.rb:

# portal configuration
Sidekiq::Portal.setup! do |config|
  config.default_timezone = 'UTC' # 'UTC' by default
  config.retry_count = 3 # 0 by default
  config.retry_on = [StandardError] # [StandardError] by default

  # pre-defined sidekiq-scheduler configs (Rails example)
  config.scheduler_config = Rails.application.config_for(:sidekiq)[:schedule]

  # manual sidekiq-scheduler configs
  config.scheduler_config = {
    LoolJob: { every: '15m' },
    kek_job: { cron: '0 * * * * *', class: :KekJob }
  }
end

# global state clearing logic
RSpec.configure do |config|
  config.before { Sidekiq::Worker.clear_all }
  config.after  { Timecop.return }
  config.after  { Sidekiq::Portal.reload! }
end

And in your tests:

RSpec.describe 'Some spec' do
  specify 'magic?' do
    Timecop.travel(Time.current + 2.hours) # magic begins here ๐Ÿ˜ˆ
  end
end

Example

  • Job class:
class HookExampleJob < ApplicationJob
  def perform
    GLOBAL_HOOK_INTERCEPTOR << Time.current # intercept current time
  end
end
  • Sidekiq::Scheduler config:
:schedule:
  HookExample:
    every: '15m'
  • HookExampleJob spec:
RSpec.describe 'HookExampleJob sheduler plan' do
  specify 'scheduled?' do
    stub_const('GLOBAL_HOOK_INTERCEPTOR', [])
    expect(GLOBAL_HOOK_INTERCEPTOR.count).to eq(0) # => true

    # do some magic ๐Ÿ˜ˆ
    Timecop.travel(Time.current + 2.hours)

    expect(GLOBAL_HOOK_INTERCEPTOR.count).to eq(8) # => true (๐Ÿ˜ˆ magic)

    puts GLOBAL_HOOK_INTERCEPTOR # ๐Ÿ˜ˆ
    # => outputs:
    # 2019-12-24 03:05:39 +0300 (+15m) (Time.current from HookExampleJob#perform)
    # 2019-12-24 03:20:39 +0300 (+15m)
    # 2019-12-24 03:35:39 +0300 (+15m)
    # 2019-12-24 03:50:39 +0300 (+15m)
    # 2019-12-24 04:05:39 +0300 (+15m)
    # 2019-12-24 04:20:39 +0300 (+15m)
    # 2019-12-24 04:35:39 +0300 (+15m)
    # 2019-12-24 04:50:39 +0300 (+15m)
  end
end

Roadmap

  • Sidekiq::Testing.portal! test mode with support for :inline and :fake; (Sidekiq::Testing.inline! and Sidekiq::Testing.fake respectively);
  • support for ActiveSupport::TimeZone instances in default_timezone config;
  • rspec matchers;
  • #reload! should use previously defined settings?;
  • support for Sidekiq::Worker job backend;
  • support for Sidekiq::Cron scheduler plans;
  • more specs;
  • documentation and examples for instance-based portals (Sidekiq::Portal.new(&configuration));
  • configurable job execution randomization (for jobs which should be invoked at the same time) (randomized invocation and not - at the same time or not);
  • configurable in-line invocations (with job list config);
  • configurable and conditional portal invocation (run over all specs or only over the one or etc) (suitable for unit tests);
  • support for Ruby 2.7;
  • Time as external dependency;
  • getting rid of ActiveSupport's Time-related core extensions;
  • better specs;

License

Released under MIT License.

Authors

Rustam Ibragimov

sidekiq_portal's People

Contributors

0exp avatar khalilgharbaoui avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.