mirror of
https://github.com/endofunky/sidetiq.git
synced 2022-11-09 13:53:30 -05:00
Initial commit.
This commit is contained in:
commit
08b76a3737
22 changed files with 553 additions and 0 deletions
9
.gitignore
vendored
Normal file
9
.gitignore
vendored
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
lib/*.bundle
|
||||||
|
coverage
|
||||||
|
rdoc
|
||||||
|
doc
|
||||||
|
.yardoc
|
||||||
|
.bundle
|
||||||
|
Gemfile.lock
|
||||||
|
pkg
|
||||||
|
tmp
|
14
Gemfile
Normal file
14
Gemfile
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
source 'https://rubygems.org'
|
||||||
|
|
||||||
|
group :development do
|
||||||
|
gem 'rake'
|
||||||
|
gem 'rake-compiler'
|
||||||
|
end
|
||||||
|
|
||||||
|
group :test do
|
||||||
|
gem 'simplecov'
|
||||||
|
gem 'mocha'
|
||||||
|
end
|
||||||
|
|
||||||
|
gemspec
|
||||||
|
|
20
LICENSE
Normal file
20
LICENSE
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
Copyright (C) 2012 by Tobias Svensson <tobias@musicglue.com>
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
||||||
|
|
90
README.md
Normal file
90
README.md
Normal file
|
@ -0,0 +1,90 @@
|
||||||
|
Sidetiq
|
||||||
|
=======
|
||||||
|
|
||||||
|
Recurring jobs for [Sidekiq](http://mperham.github.com/sidekiq/).
|
||||||
|
|
||||||
|
## DESCRIPTION
|
||||||
|
|
||||||
|
Sidetiq provides a simple API for defining recurring workers for Sidekiq.
|
||||||
|
|
||||||
|
- Flexible DSL based on [ice_cube](http://seejohnrun.github.com/ice_cube/)
|
||||||
|
- High-resolution timer using `clock_gettime(3)` (or `mach_absolute_time()` on
|
||||||
|
Apple Mac OS X), allowing for accurate sub-second clock ticks.
|
||||||
|
|
||||||
|
## DEPENDENCIES
|
||||||
|
|
||||||
|
- [Sidekiq](http://mperham.github.com/sidekiq/)
|
||||||
|
- [ice_cube](http://seejohnrun.github.com/ice_cube/)
|
||||||
|
|
||||||
|
## INSTALLATION
|
||||||
|
|
||||||
|
The best way to install Sidetiq is with RubyGems:
|
||||||
|
|
||||||
|
$ [sudo] gem install sidetiq
|
||||||
|
|
||||||
|
If you're installing from source, you can use [Bundler](http://gembundler.com/)
|
||||||
|
to pick up all the gems ([more info](http://gembundler.com/bundle_install.html)):
|
||||||
|
|
||||||
|
$ bundle install
|
||||||
|
|
||||||
|
## GETTING STARTED
|
||||||
|
|
||||||
|
Defining recurring jobs is simple:
|
||||||
|
|
||||||
|
```ruby
|
||||||
|
class MyWorker
|
||||||
|
include Sidekiq::Worker
|
||||||
|
include Sidetiq::Schedulable
|
||||||
|
|
||||||
|
# Every other month on the first monday and last tuesday at 12 o'clock.
|
||||||
|
tiq { monthly(2).day_of_week(1 => [1], 2 => [-1]).hour_of_day(12) }
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
|
It also is possible to define multiple scheduling rules for a worker:
|
||||||
|
|
||||||
|
```ruby
|
||||||
|
class MyWorker
|
||||||
|
include Sidekiq::Worker
|
||||||
|
include Sidetiq::Schedulable
|
||||||
|
|
||||||
|
tiq do
|
||||||
|
# Every third year in March
|
||||||
|
yearly(3).month_of_year(:march)
|
||||||
|
|
||||||
|
# Every fourth year in Februrary
|
||||||
|
yearly(2).month_of_year(:februrary)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
|
The first time the tiq method is called, Sidetiq will automatically spin up
|
||||||
|
it's clock thread and enqueue jobs for their next occurrence using
|
||||||
|
`#perform_at`. Note that by default Sidekiq only polls every 15 seconds.
|
||||||
|
|
||||||
|
If workers are spread across multiple machines multiple jobs might be enqueued
|
||||||
|
at the same time. This can be avoided by using a locking library for Sidekiq,
|
||||||
|
such as [sidekiq-unique-jobs](https://github.com/form26/sidekiq-unique-jobs).
|
||||||
|
|
||||||
|
## CONTRIBUTE
|
||||||
|
|
||||||
|
If you'd like to contribute to Sidetiq, start by forking my repo on GitHub:
|
||||||
|
|
||||||
|
[http://github.com/tobiassvn/sidetiq](http://github.com/tobiassvn/sidetiq)
|
||||||
|
|
||||||
|
To get all of the dependencies, install the gem first. The best way to get
|
||||||
|
your changes merged back into core is as follows:
|
||||||
|
|
||||||
|
1. Clone down your fork
|
||||||
|
1. Create a thoughtfully named topic branch to contain your change
|
||||||
|
1. Write some code
|
||||||
|
1. Add tests and make sure everything still passes by running `rake`
|
||||||
|
1. If you are adding new functionality, document it in the README
|
||||||
|
1. Do not change the version number, I will do that on my end
|
||||||
|
1. If necessary, rebase your commits into logical chunks, without errors
|
||||||
|
1. Push the branch up to GitHub
|
||||||
|
1. Send a pull request to the tobiassvn/sidetiq project.
|
||||||
|
|
||||||
|
## LICENSE
|
||||||
|
|
||||||
|
Sidetiq is released under the MIT License. See LICENSE for further details.
|
11
Rakefile
Normal file
11
Rakefile
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
require 'bundler/gem_tasks'
|
||||||
|
require 'rake/testtask'
|
||||||
|
require 'rake/extensiontask'
|
||||||
|
|
||||||
|
Rake::ExtensionTask.new('sidetiq_ext')
|
||||||
|
|
||||||
|
Rake::TestTask.new do |t|
|
||||||
|
t.pattern = 'test/**/test_*.rb'
|
||||||
|
end
|
||||||
|
|
||||||
|
task default: :test
|
19
examples/simple.rb
Normal file
19
examples/simple.rb
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
require 'sidetiq'
|
||||||
|
|
||||||
|
# We're only loading this so we don't actually have to connect to redis.
|
||||||
|
require 'sidekiq/testing'
|
||||||
|
|
||||||
|
class ExampleWorker
|
||||||
|
include Sidekiq::Worker
|
||||||
|
include Sidetiq::Schedulable
|
||||||
|
|
||||||
|
def self.perform_at(time)
|
||||||
|
puts "Enqueued to run at #{time}"
|
||||||
|
end
|
||||||
|
|
||||||
|
# Run every 2 seconds
|
||||||
|
tiq { secondly(2) }
|
||||||
|
end
|
||||||
|
|
||||||
|
puts "Hit C-c to quit."
|
||||||
|
sleep 1000000
|
4
ext/sidetiq_ext/extconf.rb
Normal file
4
ext/sidetiq_ext/extconf.rb
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
require 'rbconfig'
|
||||||
|
require 'mkmf'
|
||||||
|
create_makefile('sidetiq_ext')
|
||||||
|
|
97
ext/sidetiq_ext/sidetiq_ext.c
Normal file
97
ext/sidetiq_ext/sidetiq_ext.c
Normal file
|
@ -0,0 +1,97 @@
|
||||||
|
#include <ruby.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include "sidetiq_ext.h"
|
||||||
|
|
||||||
|
#ifdef __APPLE__
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <sys/resource.h>
|
||||||
|
#include <mach/mach.h>
|
||||||
|
#include <mach/clock.h>
|
||||||
|
#include <mach/mach_time.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sched.h>
|
||||||
|
#else
|
||||||
|
#include <time.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
VALUE msidetiq;
|
||||||
|
VALUE esidetiq_error;
|
||||||
|
VALUE csidetiq_clock;
|
||||||
|
|
||||||
|
#ifdef __APPLE__
|
||||||
|
static mach_timebase_info_data_t clock_gettime_inf;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
CLOCK_REALTIME,
|
||||||
|
CLOCK_MONOTONIC,
|
||||||
|
CLOCK_PROCESS_CPUTIME_ID,
|
||||||
|
CLOCK_THREAD_CPUTIME_ID
|
||||||
|
} clockid_t;
|
||||||
|
|
||||||
|
int clock_gettime(clockid_t clk_id, struct timespec *tp)
|
||||||
|
{
|
||||||
|
kern_return_t ret;
|
||||||
|
clock_serv_t clk;
|
||||||
|
clock_id_t clk_serv_id;
|
||||||
|
mach_timespec_t tm;
|
||||||
|
uint64_t start, end, delta, nano;
|
||||||
|
int retval = -1;
|
||||||
|
|
||||||
|
switch (clk_id) {
|
||||||
|
case CLOCK_REALTIME:
|
||||||
|
case CLOCK_MONOTONIC:
|
||||||
|
clk_serv_id = clk_id == CLOCK_REALTIME ? CALENDAR_CLOCK : SYSTEM_CLOCK;
|
||||||
|
if (KERN_SUCCESS == (ret = host_get_clock_service(mach_host_self(), clk_serv_id, &clk))) {
|
||||||
|
if (KERN_SUCCESS == (ret = clock_get_time(clk, &tm))) {
|
||||||
|
tp->tv_sec = tm.tv_sec;
|
||||||
|
tp->tv_nsec = tm.tv_nsec;
|
||||||
|
retval = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (KERN_SUCCESS != ret) {
|
||||||
|
errno = EINVAL;
|
||||||
|
retval = -1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case CLOCK_PROCESS_CPUTIME_ID:
|
||||||
|
case CLOCK_THREAD_CPUTIME_ID:
|
||||||
|
start = mach_absolute_time();
|
||||||
|
if (clk_id == CLOCK_PROCESS_CPUTIME_ID) {
|
||||||
|
getpid();
|
||||||
|
} else {
|
||||||
|
sched_yield();
|
||||||
|
}
|
||||||
|
end = mach_absolute_time();
|
||||||
|
delta = end - start;
|
||||||
|
if (0 == clock_gettime_inf.denom) {
|
||||||
|
mach_timebase_info(&clock_gettime_inf);
|
||||||
|
}
|
||||||
|
nano = delta * clock_gettime_inf.numer / clock_gettime_inf.denom;
|
||||||
|
tp->tv_sec = nano * 1e-9;
|
||||||
|
tp->tv_nsec = nano - (tp->tv_sec * 1e9);
|
||||||
|
retval = 0;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
errno = EINVAL;
|
||||||
|
retval = -1;
|
||||||
|
}
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static VALUE sidetiq_gettime(VALUE self)
|
||||||
|
{
|
||||||
|
struct timespec time;
|
||||||
|
assert(clock_gettime(CLOCK_REALTIME, &time) == 0);
|
||||||
|
return rb_time_nano_new(time.tv_sec, time.tv_nsec);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Init_sidetiq_ext()
|
||||||
|
{
|
||||||
|
msidetiq = rb_define_module("Sidetiq");
|
||||||
|
esidetiq_error = rb_define_class_under(msidetiq, "Error", rb_eStandardError);
|
||||||
|
csidetiq_clock = rb_define_class_under(msidetiq, "Clock", rb_cObject);
|
||||||
|
rb_define_method(csidetiq_clock, "gettime", sidetiq_gettime, 0);
|
||||||
|
}
|
||||||
|
|
19
ext/sidetiq_ext/sidetiq_ext.h
Normal file
19
ext/sidetiq_ext/sidetiq_ext.h
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
#ifndef __SIDETIQ_EXT_H__
|
||||||
|
#define __SIDETIQ_EXT_H__
|
||||||
|
#include <ruby.h>
|
||||||
|
|
||||||
|
typedef uint64_t sidetiq_time_t;
|
||||||
|
|
||||||
|
void Init_sidetiq_ext();
|
||||||
|
static VALUE sidetiq_gettime(VALUE self);
|
||||||
|
|
||||||
|
/* module Sidetiq */
|
||||||
|
extern VALUE msidetiq;
|
||||||
|
|
||||||
|
/* class Sidetiq::Error < StandardError */
|
||||||
|
extern VALUE esidetiq_error;
|
||||||
|
|
||||||
|
/* class Sidetiq::Clock */
|
||||||
|
extern VALUE csidetiq_clock;
|
||||||
|
|
||||||
|
#endif
|
19
lib/sidetiq.rb
Normal file
19
lib/sidetiq.rb
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
# stdlib
|
||||||
|
require 'singleton'
|
||||||
|
require 'monitor'
|
||||||
|
require 'ostruct'
|
||||||
|
|
||||||
|
# gems
|
||||||
|
require 'sidekiq'
|
||||||
|
require 'ice_cube'
|
||||||
|
|
||||||
|
# c extensions
|
||||||
|
require 'sidetiq_ext'
|
||||||
|
|
||||||
|
# internal
|
||||||
|
require 'sidetiq/config'
|
||||||
|
require 'sidetiq/clock'
|
||||||
|
require 'sidetiq/schedule'
|
||||||
|
require 'sidetiq/schedulable'
|
||||||
|
require 'sidetiq/version'
|
||||||
|
|
14
lib/sidetiq/class_methods.rb
Normal file
14
lib/sidetiq/class_methods.rb
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
module Sidetiq
|
||||||
|
module Schedulable
|
||||||
|
module ClassMethods
|
||||||
|
def tiq(&block)
|
||||||
|
Sidetiq::Scheduler.instance.instance_eval(&block)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.included(klass)
|
||||||
|
klass.extend(Sidetiq::Schedulable::ClassMethods)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
55
lib/sidetiq/clock.rb
Normal file
55
lib/sidetiq/clock.rb
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
module Sidetiq
|
||||||
|
configure do |config|
|
||||||
|
config.priority = Thread.current.priority
|
||||||
|
config.resolution = 0.2
|
||||||
|
end
|
||||||
|
|
||||||
|
class Clock
|
||||||
|
include Singleton
|
||||||
|
include MonitorMixin
|
||||||
|
|
||||||
|
attr_reader :schedules
|
||||||
|
|
||||||
|
def initialize
|
||||||
|
super
|
||||||
|
@schedules = {}
|
||||||
|
start!
|
||||||
|
end
|
||||||
|
|
||||||
|
def schedule_for(worker)
|
||||||
|
schedules[worker] ||= Sidetiq::Schedule.new
|
||||||
|
end
|
||||||
|
|
||||||
|
def tick
|
||||||
|
@tick = gettime
|
||||||
|
|
||||||
|
synchronize do
|
||||||
|
schedules.each do |worker, schedule|
|
||||||
|
if schedule.schedule_next?(@tick)
|
||||||
|
occurrence = schedule.next_occurrence
|
||||||
|
Sidekiq.logger.info "Sidetiq::Clock enqueue #{worker.name} (at: #{occurrence.to_s})"
|
||||||
|
worker.perform_at(occurrence)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def start!
|
||||||
|
Sidekiq.logger.info "Sidetiq::Clock start"
|
||||||
|
thr = Thread.start { clock { tick } }
|
||||||
|
thr.abort_on_exception = true
|
||||||
|
thr.priority = Sidetiq.config.resolution
|
||||||
|
end
|
||||||
|
|
||||||
|
def clock
|
||||||
|
loop do
|
||||||
|
yield
|
||||||
|
Thread.pass
|
||||||
|
sleep Sidetiq.config.resolution
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
14
lib/sidetiq/config.rb
Normal file
14
lib/sidetiq/config.rb
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
module Sidetiq
|
||||||
|
class << self
|
||||||
|
attr_writer :config
|
||||||
|
|
||||||
|
def configure
|
||||||
|
yield config
|
||||||
|
end
|
||||||
|
|
||||||
|
def config
|
||||||
|
@config ||= OpenStruct.new
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
19
lib/sidetiq/schedulable.rb
Normal file
19
lib/sidetiq/schedulable.rb
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
module Sidetiq
|
||||||
|
module Schedulable
|
||||||
|
module ClassMethods
|
||||||
|
def tiq(&block)
|
||||||
|
clock = Sidetiq::Clock.instance
|
||||||
|
worker = block.send(:binding).eval('self')
|
||||||
|
|
||||||
|
clock.synchronize do
|
||||||
|
clock.schedule_for(worker).instance_eval(&block)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.included(klass)
|
||||||
|
klass.extend(Sidetiq::Schedulable::ClassMethods)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
22
lib/sidetiq/schedule.rb
Normal file
22
lib/sidetiq/schedule.rb
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
module Sidetiq
|
||||||
|
class Schedule < IceCube::Schedule
|
||||||
|
def method_missing(meth, *args, &block)
|
||||||
|
if IceCube::Rule.respond_to?(meth)
|
||||||
|
rule = IceCube::Rule.send(meth, *args, &block)
|
||||||
|
add_recurrence_rule(rule)
|
||||||
|
rule
|
||||||
|
else
|
||||||
|
super
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def schedule_next?(time)
|
||||||
|
if @last_scheduled != (no = next_occurrence(time))
|
||||||
|
@last_scheduled = no
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
10
lib/sidetiq/version.rb
Normal file
10
lib/sidetiq/version.rb
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
module Sidetiq
|
||||||
|
module VERSION
|
||||||
|
MAJOR = 0
|
||||||
|
MINOR = 1
|
||||||
|
PATCH = 0
|
||||||
|
|
||||||
|
STRING = [MAJOR, MINOR, PATCH].compact.join('.')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
24
sidetiq.gemspec
Normal file
24
sidetiq.gemspec
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
# -*- encoding: utf-8 -*-
|
||||||
|
lib = File.expand_path(File.join('..', 'lib'), __FILE__)
|
||||||
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
||||||
|
require 'sidetiq/version'
|
||||||
|
|
||||||
|
Gem::Specification.new do |gem|
|
||||||
|
gem.name = "sidetiq"
|
||||||
|
gem.version = Sidetiq::VERSION::STRING
|
||||||
|
gem.authors = ["Tobias Svensson"]
|
||||||
|
gem.email = ["tob@tobiassvensson.co.uk"]
|
||||||
|
gem.description = "High-resolution job scheduler for Sidekiq"
|
||||||
|
gem.summary = gem.description
|
||||||
|
gem.homepage = "http://github.com/tobiassvn/sidetiq"
|
||||||
|
gem.license = "MIT"
|
||||||
|
|
||||||
|
gem.files = `git ls-files`.split($/)
|
||||||
|
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
||||||
|
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
||||||
|
gem.require_paths = ["lib"]
|
||||||
|
gem.extensions = ['ext/sidetiq_ext/extconf.rb']
|
||||||
|
|
||||||
|
gem.add_dependency 'sidekiq'
|
||||||
|
gem.add_dependency 'ice_cube'
|
||||||
|
end
|
16
test/helper.rb
Normal file
16
test/helper.rb
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
require 'simplecov'
|
||||||
|
SimpleCov.start { add_filter "/test/" }
|
||||||
|
require 'minitest/autorun'
|
||||||
|
require 'mocha/setup'
|
||||||
|
require 'sidetiq'
|
||||||
|
require 'sidekiq/testing'
|
||||||
|
|
||||||
|
# Stub out Clock#start! so we don't actually loop
|
||||||
|
module Sidetiq
|
||||||
|
class Clock
|
||||||
|
def start!; end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Keep the test output clean
|
||||||
|
Sidekiq.logger = Logger.new(nil)
|
12
test/test_clock.rb
Normal file
12
test/test_clock.rb
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
require_relative 'helper'
|
||||||
|
|
||||||
|
class TestClock < MiniTest::Unit::TestCase
|
||||||
|
def test_gettime_seconds
|
||||||
|
assert_equal Sidetiq::Clock.instance.gettime.tv_sec, Time.now.tv_sec
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_gettime_nsec
|
||||||
|
refute_nil Sidetiq::Clock.instance.gettime.tv_nsec
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
7
test/test_errors.rb
Normal file
7
test/test_errors.rb
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
require_relative 'helper'
|
||||||
|
|
||||||
|
class TestErrors < MiniTest::Unit::TestCase
|
||||||
|
def test_error_superclass
|
||||||
|
assert_equal StandardError, Sidetiq::Error.superclass
|
||||||
|
end
|
||||||
|
end
|
37
test/test_sidetiq.rb
Normal file
37
test/test_sidetiq.rb
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
require_relative 'helper'
|
||||||
|
|
||||||
|
class TestSidetiq < MiniTest::Unit::TestCase
|
||||||
|
class Worker
|
||||||
|
include Sidekiq::Worker
|
||||||
|
include Sidetiq::Schedulable
|
||||||
|
|
||||||
|
tiq do
|
||||||
|
daily.hour_of_day(0)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def clock
|
||||||
|
@clock ||= Sidetiq::Clock.instance
|
||||||
|
end
|
||||||
|
|
||||||
|
def tick
|
||||||
|
clock.tick
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_scheduling
|
||||||
|
assert_equal 0, Worker.jobs.size # sanity
|
||||||
|
|
||||||
|
clock.stubs(:gettime).returns(Time.now + (24 * 60 * 60))
|
||||||
|
tick
|
||||||
|
assert_equal 1, Worker.jobs.size
|
||||||
|
|
||||||
|
clock.stubs(:gettime).returns(Time.now + (2 * 24 * 60 * 60))
|
||||||
|
tick
|
||||||
|
assert_equal 2, Worker.jobs.size
|
||||||
|
|
||||||
|
clock.stubs(:gettime).returns(Time.now + (2 * 24 * 60 * 60 + 1))
|
||||||
|
tick
|
||||||
|
assert_equal 2, Worker.jobs.size
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
21
test/test_version.rb
Normal file
21
test/test_version.rb
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
require_relative 'helper'
|
||||||
|
|
||||||
|
class TestVersion < MiniTest::Unit::TestCase
|
||||||
|
def test_major
|
||||||
|
assert_instance_of Fixnum, Sidetiq::VERSION::MAJOR
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_minor
|
||||||
|
assert_instance_of Fixnum, Sidetiq::VERSION::MINOR
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_patch
|
||||||
|
assert_instance_of Fixnum, Sidetiq::VERSION::PATCH
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_string
|
||||||
|
assert_equal Sidetiq::VERSION::STRING, [Sidetiq::VERSION::MAJOR,
|
||||||
|
Sidetiq::VERSION::MINOR, Sidetiq::VERSION::PATCH].compact.join('.')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue