emipair-delayed_job 2.0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +2 -0
- data/MIT-LICENSE +20 -0
- data/README.textile +213 -0
- data/Rakefile +33 -0
- data/VERSION +1 -0
- data/benchmarks.rb +33 -0
- data/contrib/delayed_job.monitrc +14 -0
- data/contrib/delayed_job_multiple.monitrc +23 -0
- data/emipair-delayed_job.gemspec +25 -0
- data/generators/delayed_job/delayed_job_generator.rb +22 -0
- data/generators/delayed_job/templates/migration.rb +21 -0
- data/generators/delayed_job/templates/script +5 -0
- data/init.rb +1 -0
- data/lib/delayed/backend/active_record.rb +90 -0
- data/lib/delayed/backend/base.rb +111 -0
- data/lib/delayed/backend/data_mapper.rb +147 -0
- data/lib/delayed/backend/mongo_mapper.rb +110 -0
- data/lib/delayed/command.rb +109 -0
- data/lib/delayed/message_sending.rb +22 -0
- data/lib/delayed/performable_method.rb +62 -0
- data/lib/delayed/railtie.rb +10 -0
- data/lib/delayed/recipes.rb +31 -0
- data/lib/delayed/tasks.rb +15 -0
- data/lib/delayed/worker.rb +214 -0
- data/lib/delayed_job.rb +15 -0
- data/lib/passive_support.rb +4 -0
- data/lib/passive_support/basic_object.rb +16 -0
- data/lib/passive_support/core_ext.rb +8 -0
- data/lib/passive_support/core_ext/class.rb +1 -0
- data/lib/passive_support/core_ext/class/attribute_accessors.rb +57 -0
- data/lib/passive_support/core_ext/date.rb +10 -0
- data/lib/passive_support/core_ext/date/behavior.rb +42 -0
- data/lib/passive_support/core_ext/date/calculations.rb +241 -0
- data/lib/passive_support/core_ext/date/conversions.rb +107 -0
- data/lib/passive_support/core_ext/date_time.rb +12 -0
- data/lib/passive_support/core_ext/date_time/calculations.rb +126 -0
- data/lib/passive_support/core_ext/date_time/conversions.rb +107 -0
- data/lib/passive_support/core_ext/enumerable.rb +120 -0
- data/lib/passive_support/core_ext/kernel.rb +5 -0
- data/lib/passive_support/core_ext/kernel/agnostics.rb +11 -0
- data/lib/passive_support/core_ext/kernel/daemonizing.rb +7 -0
- data/lib/passive_support/core_ext/kernel/debugger.rb +16 -0
- data/lib/passive_support/core_ext/kernel/reporting.rb +59 -0
- data/lib/passive_support/core_ext/kernel/requires.rb +24 -0
- data/lib/passive_support/core_ext/module.rb +20 -0
- data/lib/passive_support/core_ext/module/aliasing.rb +74 -0
- data/lib/passive_support/core_ext/module/attr_accessor_with_default.rb +31 -0
- data/lib/passive_support/core_ext/module/attr_internal.rb +32 -0
- data/lib/passive_support/core_ext/module/delegation.rb +135 -0
- data/lib/passive_support/core_ext/module/inclusion.rb +30 -0
- data/lib/passive_support/core_ext/module/introspection.rb +90 -0
- data/lib/passive_support/core_ext/module/loading.rb +23 -0
- data/lib/passive_support/core_ext/module/model_naming.rb +25 -0
- data/lib/passive_support/core_ext/module/synchronization.rb +39 -0
- data/lib/passive_support/core_ext/numeric.rb +9 -0
- data/lib/passive_support/core_ext/numeric/bytes.rb +50 -0
- data/lib/passive_support/core_ext/numeric/conversions.rb +19 -0
- data/lib/passive_support/core_ext/numeric/time.rb +81 -0
- data/lib/passive_support/core_ext/object.rb +6 -0
- data/lib/passive_support/core_ext/object/blank.rb +76 -0
- data/lib/passive_support/core_ext/object/conversions.rb +15 -0
- data/lib/passive_support/core_ext/object/extending.rb +80 -0
- data/lib/passive_support/core_ext/object/instance_variables.rb +74 -0
- data/lib/passive_support/core_ext/object/misc.rb +90 -0
- data/lib/passive_support/core_ext/object/singleton_class.rb +13 -0
- data/lib/passive_support/core_ext/string.rb +1 -0
- data/lib/passive_support/core_ext/string/constantize.rb +7 -0
- data/lib/passive_support/core_ext/time.rb +46 -0
- data/lib/passive_support/core_ext/time/behavior.rb +13 -0
- data/lib/passive_support/core_ext/time/calculations.rb +313 -0
- data/lib/passive_support/core_ext/time/conversions.rb +90 -0
- data/lib/passive_support/core_ext/time/zones.rb +86 -0
- data/lib/passive_support/duration.rb +100 -0
- data/lib/passive_support/ordered_hash.rb +158 -0
- data/rails/init.rb +5 -0
- data/recipes/delayed_job.rb +1 -0
- data/spec/backend/active_record_job_spec.rb +46 -0
- data/spec/backend/data_mapper_job_spec.rb +16 -0
- data/spec/backend/mongo_mapper_job_spec.rb +94 -0
- data/spec/backend/shared_backend_spec.rb +268 -0
- data/spec/delayed_method_spec.rb +58 -0
- data/spec/performable_method_spec.rb +42 -0
- data/spec/sample_jobs.rb +25 -0
- data/spec/setup/active_record.rb +33 -0
- data/spec/setup/data_mapper.rb +24 -0
- data/spec/setup/mongo_mapper.rb +17 -0
- data/spec/spec_helper.rb +19 -0
- data/spec/story_spec.rb +17 -0
- data/spec/worker_spec.rb +225 -0
- data/tasks/jobs.rake +1 -0
- metadata +323 -0
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
module PassiveSupport #:nodoc:
|
|
2
|
+
module CoreExtensions #:nodoc:
|
|
3
|
+
module Time #:nodoc:
|
|
4
|
+
module Zones
|
|
5
|
+
def self.included(base) #:nodoc:
|
|
6
|
+
base.extend(ClassMethods) if base == ::Time # i.e., don't include class methods in DateTime
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
module ClassMethods
|
|
10
|
+
attr_accessor :zone_default
|
|
11
|
+
|
|
12
|
+
# Returns the TimeZone for the current request, if this has been set (via Time.zone=).
|
|
13
|
+
# If <tt>Time.zone</tt> has not been set for the current request, returns the TimeZone specified in <tt>config.time_zone</tt>.
|
|
14
|
+
def zone
|
|
15
|
+
Thread.current[:time_zone] || zone_default
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# Sets <tt>Time.zone</tt> to a TimeZone object for the current request/thread.
|
|
19
|
+
#
|
|
20
|
+
# This method accepts any of the following:
|
|
21
|
+
#
|
|
22
|
+
# * A Rails TimeZone object.
|
|
23
|
+
# * An identifier for a Rails TimeZone object (e.g., "Eastern Time (US & Canada)", <tt>-5.hours</tt>).
|
|
24
|
+
# * A TZInfo::Timezone object.
|
|
25
|
+
# * An identifier for a TZInfo::Timezone object (e.g., "America/New_York").
|
|
26
|
+
#
|
|
27
|
+
# Here's an example of how you might set <tt>Time.zone</tt> on a per request basis -- <tt>current_user.time_zone</tt>
|
|
28
|
+
# just needs to return a string identifying the user's preferred TimeZone:
|
|
29
|
+
#
|
|
30
|
+
# class ApplicationController < ActionController::Base
|
|
31
|
+
# before_filter :set_time_zone
|
|
32
|
+
#
|
|
33
|
+
# def set_time_zone
|
|
34
|
+
# Time.zone = current_user.time_zone
|
|
35
|
+
# end
|
|
36
|
+
# end
|
|
37
|
+
def zone=(time_zone)
|
|
38
|
+
Thread.current[:time_zone] = get_zone(time_zone)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# Allows override of <tt>Time.zone</tt> locally inside supplied block; resets <tt>Time.zone</tt> to existing value when done.
|
|
42
|
+
def use_zone(time_zone)
|
|
43
|
+
old_zone, ::Time.zone = ::Time.zone, get_zone(time_zone)
|
|
44
|
+
yield
|
|
45
|
+
ensure
|
|
46
|
+
::Time.zone = old_zone
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
# Returns <tt>Time.zone.now</tt> when <tt>config.time_zone</tt> is set, otherwise just returns <tt>Time.now</tt>.
|
|
50
|
+
def current
|
|
51
|
+
::Time.zone_default ? ::Time.zone.now : ::Time.now
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
private
|
|
55
|
+
def get_zone(time_zone)
|
|
56
|
+
return time_zone if time_zone.nil? || time_zone.is_a?(TimeZone)
|
|
57
|
+
# lookup timezone based on identifier (unless we've been passed a TZInfo::Timezone)
|
|
58
|
+
unless time_zone.respond_to?(:period_for_local)
|
|
59
|
+
time_zone = TimeZone[time_zone] || TZInfo::Timezone.get(time_zone) rescue nil
|
|
60
|
+
end
|
|
61
|
+
# Return if a TimeZone instance, or wrap in a TimeZone instance if a TZInfo::Timezone
|
|
62
|
+
if time_zone
|
|
63
|
+
time_zone.is_a?(TimeZone) ? time_zone : TimeZone.create(time_zone.name, nil, time_zone)
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
# Returns the simultaneous time in <tt>Time.zone</tt>.
|
|
69
|
+
#
|
|
70
|
+
# Time.zone = 'Hawaii' # => 'Hawaii'
|
|
71
|
+
# Time.utc(2000).in_time_zone # => Fri, 31 Dec 1999 14:00:00 HST -10:00
|
|
72
|
+
#
|
|
73
|
+
# This method is similar to Time#localtime, except that it uses <tt>Time.zone</tt> as the local zone
|
|
74
|
+
# instead of the operating system's time zone.
|
|
75
|
+
#
|
|
76
|
+
# You can also pass in a TimeZone instance or string that identifies a TimeZone as an argument,
|
|
77
|
+
# and the conversion will be based on that zone instead of <tt>Time.zone</tt>.
|
|
78
|
+
#
|
|
79
|
+
# Time.utc(2000).in_time_zone('Alaska') # => Fri, 31 Dec 1999 15:00:00 AKST -09:00
|
|
80
|
+
def in_time_zone(zone = ::Time.zone)
|
|
81
|
+
PassiveSupport::TimeWithZone.new(utc? ? self : getutc, ::Time.__send__(:get_zone, zone))
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
end
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
require 'passive_support/basic_object'
|
|
2
|
+
|
|
3
|
+
module PassiveSupport
|
|
4
|
+
# Provides accurate date and time measurements using Date#advance and
|
|
5
|
+
# Time#advance, respectively. It mainly supports the methods on Numeric,
|
|
6
|
+
# such as in this example:
|
|
7
|
+
#
|
|
8
|
+
# 1.month.ago # equivalent to Time.now.advance(:months => -1)
|
|
9
|
+
class Duration < BasicObject
|
|
10
|
+
attr_accessor :value, :parts
|
|
11
|
+
|
|
12
|
+
def initialize(value, parts) #:nodoc:
|
|
13
|
+
@value, @parts = value, parts
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
# Adds another Duration or a Numeric to this Duration. Numeric values
|
|
17
|
+
# are treated as seconds.
|
|
18
|
+
def +(other)
|
|
19
|
+
if Duration === other
|
|
20
|
+
Duration.new(value + other.value, @parts + other.parts)
|
|
21
|
+
else
|
|
22
|
+
Duration.new(value + other, @parts + [[:seconds, other]])
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# Subtracts another Duration or a Numeric from this Duration. Numeric
|
|
27
|
+
# values are treated as seconds.
|
|
28
|
+
def -(other)
|
|
29
|
+
self + (-other)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def -@ #:nodoc:
|
|
33
|
+
Duration.new(-value, parts.map { |type,number| [type, -number] })
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def is_a?(klass) #:nodoc:
|
|
37
|
+
klass == Duration || super
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# Returns true if <tt>other</tt> is also a Duration instance with the
|
|
41
|
+
# same <tt>value</tt>, or if <tt>other == value</tt>.
|
|
42
|
+
def ==(other)
|
|
43
|
+
if Duration === other
|
|
44
|
+
other.value == value
|
|
45
|
+
else
|
|
46
|
+
other == value
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def self.===(other) #:nodoc:
|
|
51
|
+
other.is_a?(Duration) rescue super
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
# Calculates a new Time or Date that is as far in the future
|
|
55
|
+
# as this Duration represents.
|
|
56
|
+
def since(time = ::Time.current)
|
|
57
|
+
sum(1, time)
|
|
58
|
+
end
|
|
59
|
+
alias :from_now :since
|
|
60
|
+
|
|
61
|
+
# Calculates a new Time or Date that is as far in the past
|
|
62
|
+
# as this Duration represents.
|
|
63
|
+
def ago(time = ::Time.current)
|
|
64
|
+
sum(-1, time)
|
|
65
|
+
end
|
|
66
|
+
alias :until :ago
|
|
67
|
+
|
|
68
|
+
def inspect #:nodoc:
|
|
69
|
+
consolidated = parts.inject(::Hash.new(0)) { |h,part| h[part.first] += part.last; h }
|
|
70
|
+
parts = [:years, :months, :days, :minutes, :seconds].map do |length|
|
|
71
|
+
n = consolidated[length]
|
|
72
|
+
"#{n} #{n == 1 ? length.to_s.singularize : length.to_s}" if n.nonzero?
|
|
73
|
+
end.compact
|
|
74
|
+
parts = ["0 seconds"] if parts.empty?
|
|
75
|
+
parts.to_sentence(:locale => :en)
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
protected
|
|
79
|
+
|
|
80
|
+
def sum(sign, time = ::Time.current) #:nodoc:
|
|
81
|
+
parts.inject(time) do |t,(type,number)|
|
|
82
|
+
if t.acts_like?(:time) || t.acts_like?(:date)
|
|
83
|
+
if type == :seconds
|
|
84
|
+
t.since(sign * number)
|
|
85
|
+
else
|
|
86
|
+
t.advance(type => sign * number)
|
|
87
|
+
end
|
|
88
|
+
else
|
|
89
|
+
raise ::ArgumentError, "expected a time or date, got #{time.inspect}"
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
private
|
|
95
|
+
|
|
96
|
+
def method_missing(method, *args, &block) #:nodoc:
|
|
97
|
+
value.send(method, *args)
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
end
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
require 'yaml'
|
|
2
|
+
|
|
3
|
+
YAML.add_builtin_type("omap") do |type, val|
|
|
4
|
+
PassiveSupport::OrderedHash[val.map(&:to_a).map(&:first)]
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
# OrderedHash is namespaced to prevent conflicts with other implementations
|
|
8
|
+
module PassiveSupport
|
|
9
|
+
class OrderedHash < ::Hash #:nodoc:
|
|
10
|
+
def to_yaml_type
|
|
11
|
+
"!tag:yaml.org,2002:omap"
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def to_yaml(opts = {})
|
|
15
|
+
YAML.quick_emit(self, opts) do |out|
|
|
16
|
+
out.seq(taguri, to_yaml_style) do |seq|
|
|
17
|
+
each do |k, v|
|
|
18
|
+
seq.add(k => v)
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# Hash is ordered in Ruby 1.9!
|
|
25
|
+
if RUBY_VERSION < '1.9'
|
|
26
|
+
def initialize(*args, &block)
|
|
27
|
+
super
|
|
28
|
+
@keys = []
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def self.[](*args)
|
|
32
|
+
ordered_hash = new
|
|
33
|
+
|
|
34
|
+
if (args.length == 1 && args.first.is_a?(Array))
|
|
35
|
+
args.first.each do |key_value_pair|
|
|
36
|
+
next unless (key_value_pair.is_a?(Array))
|
|
37
|
+
ordered_hash[key_value_pair[0]] = key_value_pair[1]
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
return ordered_hash
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
unless (args.size % 2 == 0)
|
|
44
|
+
raise ArgumentError.new("odd number of arguments for Hash")
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
args.each_with_index do |val, ind|
|
|
48
|
+
next if (ind % 2 != 0)
|
|
49
|
+
ordered_hash[val] = args[ind + 1]
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
ordered_hash
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def initialize_copy(other)
|
|
56
|
+
super
|
|
57
|
+
# make a deep copy of keys
|
|
58
|
+
@keys = other.keys
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def []=(key, value)
|
|
62
|
+
@keys << key if !has_key?(key)
|
|
63
|
+
super
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def delete(key)
|
|
67
|
+
if has_key? key
|
|
68
|
+
index = @keys.index(key)
|
|
69
|
+
@keys.delete_at index
|
|
70
|
+
end
|
|
71
|
+
super
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def delete_if
|
|
75
|
+
super
|
|
76
|
+
sync_keys!
|
|
77
|
+
self
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def reject!
|
|
81
|
+
super
|
|
82
|
+
sync_keys!
|
|
83
|
+
self
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def reject(&block)
|
|
87
|
+
dup.reject!(&block)
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def keys
|
|
91
|
+
@keys.dup
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def values
|
|
95
|
+
@keys.collect { |key| self[key] }
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def to_hash
|
|
99
|
+
self
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
def to_a
|
|
103
|
+
@keys.map { |key| [ key, self[key] ] }
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
def each_key
|
|
107
|
+
@keys.each { |key| yield key }
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
def each_value
|
|
111
|
+
@keys.each { |key| yield self[key]}
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
def each
|
|
115
|
+
@keys.each {|key| yield [key, self[key]]}
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
alias_method :each_pair, :each
|
|
119
|
+
|
|
120
|
+
def clear
|
|
121
|
+
super
|
|
122
|
+
@keys.clear
|
|
123
|
+
self
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
def shift
|
|
127
|
+
k = @keys.first
|
|
128
|
+
v = delete(k)
|
|
129
|
+
[k, v]
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
def merge!(other_hash)
|
|
133
|
+
other_hash.each {|k,v| self[k] = v }
|
|
134
|
+
self
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
def merge(other_hash)
|
|
138
|
+
dup.merge!(other_hash)
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
# When replacing with another hash, the initial order of our keys must come from the other hash -ordered or not.
|
|
142
|
+
def replace(other)
|
|
143
|
+
super
|
|
144
|
+
@keys = other.keys
|
|
145
|
+
self
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
def inspect
|
|
149
|
+
"#<OrderedHash #{super}>"
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
private
|
|
153
|
+
def sync_keys!
|
|
154
|
+
@keys.delete_if {|k| !has_key?(k)}
|
|
155
|
+
end
|
|
156
|
+
end
|
|
157
|
+
end
|
|
158
|
+
end
|
data/rails/init.rb
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib', 'delayed', 'recipes'))
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'backend/shared_backend_spec'
|
|
3
|
+
require 'delayed/backend/active_record'
|
|
4
|
+
|
|
5
|
+
describe Delayed::Backend::ActiveRecord::Job do
|
|
6
|
+
before(:all) do
|
|
7
|
+
@backend = Delayed::Backend::ActiveRecord::Job
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
before(:each) do
|
|
11
|
+
Delayed::Backend::ActiveRecord::Job.delete_all
|
|
12
|
+
SimpleJob.runs = 0
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
after do
|
|
16
|
+
Time.zone = nil
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
it_should_behave_like 'a backend'
|
|
20
|
+
|
|
21
|
+
context "db_time_now" do
|
|
22
|
+
it "should return time in current time zone if set" do
|
|
23
|
+
Time.zone = 'Eastern Time (US & Canada)'
|
|
24
|
+
%w(EST EDT).should include(Delayed::Job.db_time_now.zone)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
it "should return UTC time if that is the AR default" do
|
|
28
|
+
Time.zone = nil
|
|
29
|
+
ActiveRecord::Base.default_timezone = :utc
|
|
30
|
+
Delayed::Backend::ActiveRecord::Job.db_time_now.zone.should == 'UTC'
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
it "should return local time if that is the AR default" do
|
|
34
|
+
Time.zone = 'Central Time (US & Canada)'
|
|
35
|
+
ActiveRecord::Base.default_timezone = :local
|
|
36
|
+
%w(CST CDT).should include(Delayed::Backend::ActiveRecord::Job.db_time_now.zone)
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
describe "after_fork" do
|
|
41
|
+
it "should call reconnect on the connection" do
|
|
42
|
+
ActiveRecord::Base.connection.should_receive(:reconnect!)
|
|
43
|
+
Delayed::Backend::ActiveRecord::Job.after_fork
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'backend/shared_backend_spec'
|
|
3
|
+
require 'delayed/backend/data_mapper'
|
|
4
|
+
|
|
5
|
+
describe Delayed::Backend::DataMapper::Job do
|
|
6
|
+
before(:all) do
|
|
7
|
+
@backend = Delayed::Backend::DataMapper::Job
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
before(:each) do
|
|
11
|
+
# reset database before each example is run
|
|
12
|
+
DataMapper.auto_migrate!
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
it_should_behave_like 'a backend'
|
|
16
|
+
end
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'backend/shared_backend_spec'
|
|
3
|
+
require 'delayed/backend/mongo_mapper'
|
|
4
|
+
|
|
5
|
+
describe Delayed::Backend::MongoMapper::Job do
|
|
6
|
+
before(:all) do
|
|
7
|
+
@backend = Delayed::Backend::MongoMapper::Job
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
before(:each) do
|
|
11
|
+
MongoMapper.database.collections.each(&:remove)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
it_should_behave_like 'a backend'
|
|
15
|
+
|
|
16
|
+
describe "indexes" do
|
|
17
|
+
it "should have combo index on priority and run_at" do
|
|
18
|
+
@backend.collection.index_information.detect { |index| index[0] == 'priority_1_run_at_1' }.should_not be_nil
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
it "should have index on locked_by" do
|
|
22
|
+
@backend.collection.index_information.detect { |index| index[0] == 'locked_by_1' }.should_not be_nil
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
describe "delayed method" do
|
|
27
|
+
class MongoStoryReader
|
|
28
|
+
def read(story)
|
|
29
|
+
"Epilog: #{story.tell}"
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
class MongoStory
|
|
34
|
+
include ::MongoMapper::Document
|
|
35
|
+
key :text, String
|
|
36
|
+
|
|
37
|
+
def tell
|
|
38
|
+
text
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
it "should ignore not found errors because they are permanent" do
|
|
43
|
+
story = MongoStory.create :text => 'Once upon a time...'
|
|
44
|
+
job = story.send_later(:tell)
|
|
45
|
+
story.destroy
|
|
46
|
+
lambda { job.invoke_job }.should_not raise_error
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
it "should store the object as string" do
|
|
50
|
+
story = MongoStory.create :text => 'Once upon a time...'
|
|
51
|
+
job = story.send_later(:tell)
|
|
52
|
+
|
|
53
|
+
job.payload_object.class.should == Delayed::PerformableMethod
|
|
54
|
+
job.payload_object.object.should == "LOAD;MongoStory;#{story.id}"
|
|
55
|
+
job.payload_object.method.should == :tell
|
|
56
|
+
job.payload_object.args.should == []
|
|
57
|
+
job.payload_object.perform.should == 'Once upon a time...'
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
it "should store arguments as string" do
|
|
61
|
+
story = MongoStory.create :text => 'Once upon a time...'
|
|
62
|
+
job = MongoStoryReader.new.send_later(:read, story)
|
|
63
|
+
job.payload_object.class.should == Delayed::PerformableMethod
|
|
64
|
+
job.payload_object.method.should == :read
|
|
65
|
+
job.payload_object.args.should == ["LOAD;MongoStory;#{story.id}"]
|
|
66
|
+
job.payload_object.perform.should == 'Epilog: Once upon a time...'
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
describe "before_fork" do
|
|
71
|
+
after do
|
|
72
|
+
MongoMapper.connection.connect_to_master
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
it "should disconnect" do
|
|
76
|
+
lambda do
|
|
77
|
+
Delayed::Backend::MongoMapper::Job.before_fork
|
|
78
|
+
end.should change { !!MongoMapper.connection.connected? }.from(true).to(false)
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
describe "after_fork" do
|
|
83
|
+
before do
|
|
84
|
+
MongoMapper.connection.close
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
it "should call reconnect" do
|
|
88
|
+
lambda do
|
|
89
|
+
Delayed::Backend::MongoMapper::Job.after_fork
|
|
90
|
+
end.should change { !!MongoMapper.connection.connected? }.from(false).to(true)
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
end
|