delayed_job_recurring_mongoid_uriji 0.3.8

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: ceea8a2cd6361eefbbb68c3ac8cc549447608a71
4
+ data.tar.gz: a08114c53fc9a2312d5a7caedac85ce32207ab02
5
+ SHA512:
6
+ metadata.gz: b36f2c72cdfccd56057b0b1393b7d8dd584420979f867b94429e5b81c09429decb1c7f9388266969330638e1dc4b51a39210b53bcf1b848e39cfa05a55abac21
7
+ data.tar.gz: e78eb4f0d0c62a021a9b5fe061439c52d339fdabee9ab5efb7e3d1e26568c3495fd1e264c788877449357a67c4fed4ad27a32624392435a949b9cb4e69785f6a
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2014 Amitree
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,104 @@
1
+ # delayed\_job\_recurring\_mongoid
2
+ [![Build Status](https://travis-ci.org/amitree/delayed_job_recurring.svg)](https://travis-ci.org/amitree/delayed_job_recurring)
3
+
4
+ Extends delayed\_job to support recurring jobs.
5
+
6
+ ## Usage
7
+
8
+ Add it to your Gemfile:
9
+
10
+ ```ruby
11
+ gem 'delayed_job_recurring'
12
+ ```
13
+
14
+ Then define a task class. We like the concept of
15
+ [interactors](http://eng.joingrouper.com/blog/2014/03/03/rails-the-missing-parts-interactors),
16
+ so we put our task classes in `app/interactors`. You could also put them in `lib` or even `app/models`.
17
+
18
+ ```ruby
19
+ class MyTask
20
+ include Delayed::RecurringJob
21
+ run_every 1.day
22
+ run_at '11:00am'
23
+ timezone 'US/Pacific'
24
+ queue 'slow-jobs'
25
+ def perform
26
+ # Do some work here!
27
+ end
28
+ end
29
+ ```
30
+
31
+ Finally, schedule it:
32
+
33
+ ```ruby
34
+ MyTask.schedule! # run every day at 11am Pacific time (accounting for daylight savings)
35
+ ```
36
+
37
+ The best practice is to add your `MyTask.schedule!` lines to a rake file, e.g.
38
+
39
+ ```ruby
40
+ # lib/tasks/recurring_jobs.rake
41
+
42
+ namespace :recurring do
43
+ task init: :environment do
44
+ MyTask.schedule!
45
+ MyOtherTask.schedule!
46
+
47
+ if Rails.env.production?
48
+ MyProductionOnlyTask.schedule!
49
+ end
50
+ end
51
+ end
52
+ ```
53
+
54
+ and invoke this job by running `rake recurring:init` on each deployment.
55
+
56
+ Alternatively, if your app only has one instance running, you can put your
57
+ `schedule!` calls into an initializer, and then your jobs will be automatically
58
+ scheduled when your app starts. However, if you have more than one instance of
59
+ your app running in production, this will lead to a race condition and you will
60
+ end up with duplicate recurring jobs in the queue.
61
+
62
+ ## ActiveJob
63
+
64
+ Note: your task class should **not** inherit from ActiveJob::Base.
65
+
66
+ ## Advanced usage
67
+
68
+ ### Passing options to schedule
69
+
70
+ ```ruby
71
+ MyTask.schedule(run_at: '12:00')
72
+ ```
73
+
74
+ ### Running at multiples times each day
75
+
76
+ ```ruby
77
+ MyTask.schedule(run_every: 1.day, run_at: ['11:00', '6:00pm'])
78
+ ```
79
+
80
+ ### Running on specific days of the week
81
+
82
+ ```ruby
83
+ MyTask.schedule(run_every: 1.week, run_at: ['sunday 8:00am', 'wednesday 8:00am'])
84
+ ```
85
+
86
+ ### Scheduling multiple jobs of same class
87
+
88
+ By default, before scheduling a new job, the old jobs scheduled with the same class will be unscheduled.
89
+
90
+ To schedule multiple jobs with same class, pass an unique matching param `job_matching_param` and value for that matching param in each job as below:
91
+
92
+ ```ruby
93
+ MyTask.schedule(run_at: '12:00', job_matching_param: 'schedule_id', schedule_id: 2)
94
+ ```
95
+
96
+ This allows you to schedule multiple jobs with same class if value of the unique matching param(which is `schedule_id` in above example) is different in each job.
97
+
98
+ ## Thanks!
99
+
100
+ Many thanks to @ginjo and @kares for their work! This code was derived from https://gist.github.com/ginjo/3688965.
101
+
102
+ ## Contributing
103
+
104
+ [![Open Source Helpers](https://www.codetriage.com/amitree/delayed_job_recurring/badges/users.svg)](https://www.codetriage.com/amitree/delayed_job_recurring)
@@ -0,0 +1,210 @@
1
+ # Delayed::RecurringJob
2
+ module Delayed
3
+ module RecurringJob
4
+ def self.included(base)
5
+ base.extend(ClassMethods)
6
+ base.class_eval do
7
+ @@logger = Delayed::Worker.logger
8
+ cattr_reader :logger
9
+ end
10
+ end
11
+
12
+ def failure
13
+ schedule!
14
+ end
15
+
16
+ def success
17
+ schedule!
18
+ end
19
+
20
+ # Schedule this "repeating" job
21
+ def schedule! options = {}
22
+ options = options.dup
23
+
24
+ if run_every = options.delete(:run_every)
25
+ options[:run_interval] = serialize_duration(run_every)
26
+ end
27
+
28
+ @schedule_options = options.reverse_merge(@schedule_options || {}).reverse_merge(
29
+ run_at: self.class.run_at,
30
+ timezone: self.class.timezone,
31
+ run_interval: serialize_duration(self.class.run_every),
32
+ priority: self.class.priority,
33
+ queue: self.class.queue
34
+ )
35
+ enqueue_opts = { priority: @schedule_options[:priority], run_at: next_run_time }
36
+ enqueue_opts[:queue] = @schedule_options[:queue] if @schedule_options[:queue]
37
+
38
+ self.class.jobs(@schedule_options).destroy_all
39
+
40
+ if Gem.loaded_specs['delayed_job'].version.to_s.first.to_i < 3
41
+ Delayed::Job.enqueue self, enqueue_opts[:priority], enqueue_opts[:run_at]
42
+ else
43
+ Delayed::Job.enqueue self, enqueue_opts
44
+ end
45
+ end
46
+
47
+ def next_run_time
48
+ times = @schedule_options[:run_at]
49
+ times = [times] unless times.is_a? Array
50
+ times = times.map{|time| parse_time(time, @schedule_options[:timezone])}
51
+ times = times.map{|time| time.in_time_zone @schedule_options[:timezone]} if @schedule_options[:timezone]
52
+
53
+ interval = deserialize_duration(@schedule_options[:run_interval])
54
+
55
+ until next_time = next_future_time(times)
56
+ times.map!{ |time| time + interval }
57
+ end
58
+
59
+ # Update @schedule_options to avoid growing number of calculations each time
60
+ @schedule_options[:run_at] = times
61
+
62
+ next_time
63
+ end
64
+
65
+ private
66
+ # We don't want the run_interval to be serialized as a number of seconds.
67
+ # 1.day is not the same as 86400 (not all days are 86400 seconds long!)
68
+ def serialize_duration(duration)
69
+ case duration
70
+ when ActiveSupport::Duration
71
+ {value: duration.value, parts: duration.parts}
72
+ else
73
+ duration
74
+ end
75
+ end
76
+
77
+ def deserialize_duration(serialized)
78
+ case serialized
79
+ when Hash
80
+ ActiveSupport::Duration.new(serialized[:value], serialized[:parts])
81
+ else
82
+ serialized
83
+ end
84
+ end
85
+
86
+ def parse_time(time, timezone)
87
+ case time
88
+ when String
89
+ time_with_zone = get_timezone(timezone).parse(time)
90
+ parts = Date._parse(time, false)
91
+ wday = parts.fetch(:wday, time_with_zone.wday)
92
+ time_with_zone + (wday - time_with_zone.wday).days
93
+ else
94
+ time
95
+ end
96
+ end
97
+
98
+ def get_timezone(zone)
99
+ if zone
100
+ ActiveSupport::TimeZone.new(zone)
101
+ else
102
+ Time.zone
103
+ end
104
+ end
105
+
106
+ def next_future_time(times)
107
+ times.select{|time| time > Time.now}.min
108
+ end
109
+
110
+ module ClassMethods
111
+ def run_at(*times)
112
+ if times.length == 0
113
+ @run_at || run_every.from_now
114
+ else
115
+ if @run_at_inherited
116
+ @run_at = []
117
+ @run_at_inherited = nil
118
+ end
119
+ @run_at ||= []
120
+ @run_at.concat times
121
+ end
122
+ end
123
+
124
+ def run_every(interval = nil)
125
+ if interval.nil?
126
+ @run_interval || 1.hour
127
+ else
128
+ @run_interval = interval
129
+ end
130
+ end
131
+
132
+ def timezone(zone = nil)
133
+ if zone.nil?
134
+ @tz
135
+ else
136
+ @tz = zone
137
+ end
138
+ end
139
+
140
+ def priority(priority = nil)
141
+ if priority.nil?
142
+ @priority
143
+ else
144
+ @priority = priority
145
+ end
146
+ end
147
+
148
+ def queue(*args)
149
+ if args.length == 0
150
+ @queue
151
+ else
152
+ @queue = args.first
153
+ end
154
+ end
155
+
156
+ # Show all jobs for this schedule
157
+ def jobs(options = {})
158
+ options = options.with_indifferent_access
159
+ # Construct dynamic query with 'job_matching_param' if present
160
+ query = {'$or' => [{handler: /--- !ruby\/object:#{name}[\s+]/}, {handler: /--- !ruby\/object:#{name}$/}]}
161
+ if options[:job_matching_param].present?
162
+ matching_key = options[:job_matching_param]
163
+ matching_value = options[matching_key]
164
+ matching_yaml = yaml_quote(matching_value)
165
+ query = {'$and' => [query, handler: /#{matching_key}: #{matching_yaml}/]}
166
+ end
167
+
168
+ ::Delayed::Job.where(query)
169
+ end
170
+
171
+ # Remove all jobs for this schedule (Stop the schedule)
172
+ def unschedule(options = {})
173
+ jobs(options).each{|j| j.destroy}
174
+ end
175
+
176
+ # Main interface to start this schedule (adds it to the jobs table).
177
+ # Pass in a time to run the first job (nil runs the first job at run_interval from now).
178
+ def schedule(options = {})
179
+ schedule!(options) unless scheduled?(options)
180
+ end
181
+
182
+ def schedule!(options = {})
183
+ return unless Delayed::Worker.delay_jobs
184
+ unschedule(options)
185
+ new.schedule!(options)
186
+ end
187
+
188
+ def scheduled?(options = {})
189
+ jobs(options).count > 0
190
+ end
191
+
192
+ def inherited(subclass)
193
+ [:@run_at, :@run_interval, :@tz, :@priority].each do |var|
194
+ next unless instance_variable_defined? var
195
+ subclass.instance_variable_set var, self.instance_variable_get(var)
196
+ subclass.instance_variable_set "#{var}_inherited", true
197
+ end
198
+ end
199
+
200
+ private
201
+ def yaml_quote(value)
202
+ # In order to ensure matching indentation, place the element inside a
203
+ # two-level hash (the first level mimicking 'schedule_options', the second
204
+ # for #{job_matching_param}), and strip out the leading "---\n:a:\n :a: "
205
+ # but keep the trailing newline.
206
+ ({a: {a: value}}).to_yaml[14..-1]
207
+ end
208
+ end # ClassMethods
209
+ end # RecurringJob
210
+ end # Delayed
@@ -0,0 +1,3 @@
1
+ require 'delayed_job'
2
+ require 'delayed_job_mongoid'
3
+ require 'delayed/recurring_job'
metadata ADDED
@@ -0,0 +1,174 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: delayed_job_recurring_mongoid_uriji
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.3.8
5
+ platform: ruby
6
+ authors:
7
+ - Tony Novak
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2018-11-12 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rails
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '='
46
+ - !ruby/object:Gem::Version
47
+ version: 3.6.0
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '='
53
+ - !ruby/object:Gem::Version
54
+ version: 3.6.0
55
+ - !ruby/object:Gem::Dependency
56
+ name: rspec-rails
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - '='
60
+ - !ruby/object:Gem::Version
61
+ version: 3.6.1
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - '='
67
+ - !ruby/object:Gem::Version
68
+ version: 3.6.1
69
+ - !ruby/object:Gem::Dependency
70
+ name: sqlite3
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '1.3'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '1.3'
83
+ - !ruby/object:Gem::Dependency
84
+ name: database_cleaner
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '1.3'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '1.3'
97
+ - !ruby/object:Gem::Dependency
98
+ name: timecop
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: 0.7.1
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: 0.7.1
111
+ - !ruby/object:Gem::Dependency
112
+ name: delayed_job
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '3.0'
118
+ type: :runtime
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '3.0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: delayed_job_mongoid
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: '2.0'
132
+ type: :runtime
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ version: '2.0'
139
+ description: Extends delayed_job_mongoid to support recurring jobs, including timezone
140
+ support
141
+ email: engineering@amitree.com
142
+ executables: []
143
+ extensions: []
144
+ extra_rdoc_files: []
145
+ files:
146
+ - LICENSE
147
+ - README.md
148
+ - lib/delayed/recurring_job.rb
149
+ - lib/delayed_job_recurring_mongoid_uriji.rb
150
+ homepage: https://github.com/riverdrakar/delayed_job_recurring
151
+ licenses:
152
+ - MIT
153
+ metadata: {}
154
+ post_install_message:
155
+ rdoc_options: []
156
+ require_paths:
157
+ - lib
158
+ required_ruby_version: !ruby/object:Gem::Requirement
159
+ requirements:
160
+ - - ">"
161
+ - !ruby/object:Gem::Version
162
+ version: '1.9'
163
+ required_rubygems_version: !ruby/object:Gem::Requirement
164
+ requirements:
165
+ - - ">="
166
+ - !ruby/object:Gem::Version
167
+ version: '0'
168
+ requirements: []
169
+ rubyforge_project:
170
+ rubygems_version: 2.6.14
171
+ signing_key:
172
+ specification_version: 4
173
+ summary: Recurring jobs for delayed_job_mongoid
174
+ test_files: []