cloudwatch_scheduler 0.1.0
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.
- checksums.yaml +7 -0
- data/.gitignore +15 -0
- data/.rspec +2 -0
- data/.rubocop.yml +89 -0
- data/.travis.yml +8 -0
- data/Appraisals +8 -0
- data/Gemfile +12 -0
- data/Guardfile +70 -0
- data/README.md +79 -0
- data/Rakefile +6 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/cloudwatch_scheduler.gemspec +28 -0
- data/gemfiles/rails_4.2.gemfile +14 -0
- data/gemfiles/rails_4.2.gemfile.lock +209 -0
- data/gemfiles/rails_5.0.gemfile +14 -0
- data/gemfiles/rails_5.0.gemfile.lock +213 -0
- data/lib/cloudwatch_scheduler/configuration.rb +38 -0
- data/lib/cloudwatch_scheduler/engine.rb +22 -0
- data/lib/cloudwatch_scheduler/job.rb +14 -0
- data/lib/cloudwatch_scheduler/provisioner.rb +117 -0
- data/lib/cloudwatch_scheduler/task.rb +69 -0
- data/lib/cloudwatch_scheduler/tasks/setup.rake +13 -0
- data/lib/cloudwatch_scheduler/version.rb +3 -0
- data/lib/cloudwatch_scheduler.rb +19 -0
- metadata +151 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 2a274f2f21104f2b1be5dc1ef1bfc663a97d4641
|
4
|
+
data.tar.gz: 45e256394378397e208f67fe6bd3091a366cf838
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 160a54b0c376e707fe3458aaa0568a66c57cbb5e89d0621bfc31f3bd9f14380684fc6ee5d37cd4d572e2e2efa2961af47e59b83fc9d927fd1c4dc04fdca35fbf
|
7
|
+
data.tar.gz: c0b463e6b2040da8fbcb004dbd6cc9cc8fee8612953925bc603fcf5ef81fd87286e9fde249c0f2f1f3cba43d09a4063053760133889927495b4a06f55c4bd55a
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.rubocop.yml
ADDED
@@ -0,0 +1,89 @@
|
|
1
|
+
Rails:
|
2
|
+
Enabled: true
|
3
|
+
|
4
|
+
AllCops:
|
5
|
+
DisplayCopNames: true
|
6
|
+
DisplayStyleGuide: true
|
7
|
+
|
8
|
+
Include:
|
9
|
+
- "**/Rakefile"
|
10
|
+
- "**/config.ru"
|
11
|
+
Exclude:
|
12
|
+
- "vendor/**/*"
|
13
|
+
- "spec/fixtures/**/*"
|
14
|
+
- "bin/**/*"
|
15
|
+
- "script/**/*"
|
16
|
+
Metrics/LineLength:
|
17
|
+
Max: 120
|
18
|
+
Rails/Date:
|
19
|
+
Enabled: false
|
20
|
+
Rails/TimeZone:
|
21
|
+
Enabled: false
|
22
|
+
AllCops:
|
23
|
+
TargetRubyVersion: 2.3
|
24
|
+
Style/AndOr:
|
25
|
+
EnforcedStyle: conditionals
|
26
|
+
Style/CaseIndentation:
|
27
|
+
IndentOneStep: true
|
28
|
+
Style/Documentation:
|
29
|
+
Enabled: false
|
30
|
+
Style/EachWithObject:
|
31
|
+
Enabled: false
|
32
|
+
Style/ExtraSpacing:
|
33
|
+
Exclude:
|
34
|
+
- "config/routes.rb"
|
35
|
+
Style/HashSyntax:
|
36
|
+
Exclude:
|
37
|
+
- "lib/tasks/**/*"
|
38
|
+
Style/MultilineOperationIndentation:
|
39
|
+
EnforcedStyle: indented
|
40
|
+
Style/NumericLiterals:
|
41
|
+
Enabled: false
|
42
|
+
Style/PercentLiteralDelimiters:
|
43
|
+
PreferredDelimiters:
|
44
|
+
"%w": "[]"
|
45
|
+
"%W": "[]"
|
46
|
+
"%i": "[]"
|
47
|
+
"%I": "[]"
|
48
|
+
"%r": "()"
|
49
|
+
Style/SignalException:
|
50
|
+
EnforcedStyle: semantic
|
51
|
+
Style/SingleLineBlockParams:
|
52
|
+
Enabled: false
|
53
|
+
Style/StringLiterals:
|
54
|
+
EnforcedStyle: double_quotes
|
55
|
+
Style/MultilineMethodCallIndentation:
|
56
|
+
Exclude:
|
57
|
+
- "spec/**/*.rb"
|
58
|
+
|
59
|
+
|
60
|
+
# Rubocop's global exclude seems to fail to exclude the bin/ dir, so set all
|
61
|
+
# the cops that are failing manually, since most of these files are
|
62
|
+
# auto-generated anyways. Also, if the rules also appear above, we need to copy
|
63
|
+
# the same attrs, because YAML won't merge, only overwrite.
|
64
|
+
|
65
|
+
Style/StringLiterals:
|
66
|
+
EnforcedStyle: double_quotes
|
67
|
+
Exclude:
|
68
|
+
- "bin/**/*"
|
69
|
+
Style/FrozenStringLiteralComment:
|
70
|
+
Exclude:
|
71
|
+
- "bin/**/*"
|
72
|
+
Style/LeadingCommentSpace:
|
73
|
+
Exclude:
|
74
|
+
- "bin/**/*"
|
75
|
+
Style/SpaceInsideParens:
|
76
|
+
Exclude:
|
77
|
+
- "bin/**/*"
|
78
|
+
Style/AlignParameters:
|
79
|
+
Exclude:
|
80
|
+
- "bin/**/*"
|
81
|
+
Style/ExtraSpacing:
|
82
|
+
Exclude:
|
83
|
+
- "bin/**/*"
|
84
|
+
Exclude:
|
85
|
+
- "config/routes.rb"
|
86
|
+
Lint/PercentStringArray:
|
87
|
+
Exclude:
|
88
|
+
# SecureHeaders needs the single quotes in `%w[https: 'self']`
|
89
|
+
- config/initializers/secure_headers.rb
|
data/.travis.yml
ADDED
data/Appraisals
ADDED
data/Gemfile
ADDED
data/Guardfile
ADDED
@@ -0,0 +1,70 @@
|
|
1
|
+
# A sample Guardfile
|
2
|
+
# More info at https://github.com/guard/guard#readme
|
3
|
+
|
4
|
+
## Uncomment and set this to only include directories you want to watch
|
5
|
+
# directories %w(app lib config test spec features) \
|
6
|
+
# .select{|d| Dir.exists?(d) ? d : UI.warning("Directory #{d} does not exist")}
|
7
|
+
|
8
|
+
## Note: if you are using the `directories` clause above and you are not
|
9
|
+
## watching the project directory ('.'), then you will want to move
|
10
|
+
## the Guardfile to a watched dir and symlink it back, e.g.
|
11
|
+
#
|
12
|
+
# $ mkdir config
|
13
|
+
# $ mv Guardfile config/
|
14
|
+
# $ ln -s config/Guardfile .
|
15
|
+
#
|
16
|
+
# and, you'll have to watch "config/Guardfile" instead of "Guardfile"
|
17
|
+
|
18
|
+
# Note: The cmd option is now required due to the increasing number of ways
|
19
|
+
# rspec may be run, below are examples of the most common uses.
|
20
|
+
# * bundler: 'bundle exec rspec'
|
21
|
+
# * bundler binstubs: 'bin/rspec'
|
22
|
+
# * spring: 'bin/rspec' (This will use spring if running and you have
|
23
|
+
# installed the spring binstubs per the docs)
|
24
|
+
# * zeus: 'zeus rspec' (requires the server to be started separately)
|
25
|
+
# * 'just' rspec: 'rspec'
|
26
|
+
|
27
|
+
guard :rspec, cmd: "bundle exec rspec", failed_mode: :focus do
|
28
|
+
require "guard/rspec/dsl"
|
29
|
+
dsl = Guard::RSpec::Dsl.new(self)
|
30
|
+
|
31
|
+
# Feel free to open issues for suggestions and improvements
|
32
|
+
|
33
|
+
# RSpec files
|
34
|
+
rspec = dsl.rspec
|
35
|
+
watch(rspec.spec_helper) { rspec.spec_dir }
|
36
|
+
watch(rspec.spec_support) { rspec.spec_dir }
|
37
|
+
watch(rspec.spec_files)
|
38
|
+
|
39
|
+
# Ruby files
|
40
|
+
ruby = dsl.ruby
|
41
|
+
dsl.watch_spec_files_for(ruby.lib_files)
|
42
|
+
|
43
|
+
# Rails files
|
44
|
+
rails = dsl.rails(view_extensions: %w(erb haml slim))
|
45
|
+
dsl.watch_spec_files_for(rails.app_files)
|
46
|
+
dsl.watch_spec_files_for(rails.views)
|
47
|
+
|
48
|
+
watch(rails.controllers) do |m|
|
49
|
+
[
|
50
|
+
rspec.spec.call("routing/#{m[1]}_routing"),
|
51
|
+
rspec.spec.call("controllers/#{m[1]}_controller"),
|
52
|
+
rspec.spec.call("acceptance/#{m[1]}")
|
53
|
+
]
|
54
|
+
end
|
55
|
+
|
56
|
+
# Rails config changes
|
57
|
+
watch(rails.spec_helper) { rspec.spec_dir }
|
58
|
+
watch(rails.routes) { "#{rspec.spec_dir}/routing" }
|
59
|
+
watch(rails.app_controller) { "#{rspec.spec_dir}/controllers" }
|
60
|
+
|
61
|
+
# Capybara features specs
|
62
|
+
watch(rails.view_dirs) { |m| rspec.spec.call("features/#{m[1]}") }
|
63
|
+
watch(rails.layouts) { |m| rspec.spec.call("features/#{m[1]}") }
|
64
|
+
|
65
|
+
# Turnip features and steps
|
66
|
+
watch(%r{^spec/acceptance/(.+)\.feature$})
|
67
|
+
watch(%r{^spec/acceptance/steps/(.+)_steps\.rb$}) do |m|
|
68
|
+
Dir[File.join("**/#{m[1]}.feature")][0] || "spec/acceptance"
|
69
|
+
end
|
70
|
+
end
|
data/README.md
ADDED
@@ -0,0 +1,79 @@
|
|
1
|
+
# CloudwatchScheduler
|
2
|
+
|
3
|
+
Are you using Rails 4.2+ and ActiveJob with the [Shoryuken
|
4
|
+
driver][shoryuken-driver] to use SQS? Do you have recurring jobs that you kick
|
5
|
+
off periodically with the [amazing Clockwork gem][clockwork]? Tired of paying
|
6
|
+
for a Heroku dyno just to run the clockwork instance? Then *CloudwatchScheduler* is just
|
7
|
+
the gem for you!
|
8
|
+
|
9
|
+
CloudwatchScheduler uses [AWS Cloudwatch scheduled event rules][cloudwatch-events] to
|
10
|
+
push a message on the cloudwatch_scheduler queue according to the schedule you provide,
|
11
|
+
using a simple DSL similar to the Clockwork DSL you're already familiar with.
|
12
|
+
The rules are free, and the messages cost a few billionths of a cent each,
|
13
|
+
saving you over $25/mo in Heroku dyno costs! Wow!!
|
14
|
+
|
15
|
+
And thats not all! It will automatically provision the Cloudwatch Events and Queues via a simple rake task! Amazing!
|
16
|
+
|
17
|
+
## Installation
|
18
|
+
|
19
|
+
Add this line to your application's Gemfile:
|
20
|
+
|
21
|
+
```ruby
|
22
|
+
gem 'cloudwatch_scheduler'
|
23
|
+
```
|
24
|
+
|
25
|
+
And then execute:
|
26
|
+
|
27
|
+
$ bundle
|
28
|
+
|
29
|
+
Or install it yourself as:
|
30
|
+
|
31
|
+
$ gem install cloudwatch_scheduler
|
32
|
+
|
33
|
+
## Usage
|
34
|
+
|
35
|
+
Make yourself a `config/cloudwatch_scheduler.rb` file:
|
36
|
+
|
37
|
+
```ruby
|
38
|
+
require "cloudwatch_scheduler"
|
39
|
+
|
40
|
+
CloudwatchScheduler do |config|
|
41
|
+
|
42
|
+
# 4am every day
|
43
|
+
task "spawn_analytics_jobs", cron: "0 4 * * ? *" do
|
44
|
+
return if Rails.application.config.deploy_env.sandbox?
|
45
|
+
AnalyticsSpawnerJob.perform_later
|
46
|
+
end
|
47
|
+
|
48
|
+
task "capture_pg_stats", every: 5.minutes do
|
49
|
+
PgHero.capture_query_stats
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
```
|
54
|
+
|
55
|
+
Then do `rake cloudwatch_scheduler:setup`, and CloudwatchScheduler will provision the events and
|
56
|
+
cloudwatch_scheduler queue. Then, start your Shoruken workers as normal, and the
|
57
|
+
`CloudwatchScheduler::Job` will get those events, and perform the tasks defined.
|
58
|
+
|
59
|
+
## Development
|
60
|
+
|
61
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run
|
62
|
+
`rake spec` to run the tests. You can also run `bin/console` for an interactive
|
63
|
+
prompt that will allow you to experiment.
|
64
|
+
|
65
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To
|
66
|
+
release a new version, update the version number in `version.rb`, and then run
|
67
|
+
`bundle exec rake release`, which will create a git tag for the version, push
|
68
|
+
git commits and tags, and push the `.gem` file to
|
69
|
+
[rubygems.org](https://rubygems.org).
|
70
|
+
|
71
|
+
## Contributing
|
72
|
+
|
73
|
+
Bug reports and pull requests are welcome on GitHub at
|
74
|
+
https://github.com/paul/cloudwatch_scheduler.
|
75
|
+
|
76
|
+
[shoryuken-driver]: https://github.com/phstc/shoryuken/wiki/Rails-Integration-Active-Job
|
77
|
+
[clockwork]: https://github.com/tomykaira/clockwork
|
78
|
+
[cloudwatch-events]: http://docs.aws.amazon.com/AmazonCloudWatch/latest/DeveloperGuide/ScheduledEvents.html
|
79
|
+
|
data/Rakefile
ADDED
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "cloudwatch_scheduler"
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
+
# require "pry"
|
11
|
+
# Pry.start
|
12
|
+
|
13
|
+
require "irb"
|
14
|
+
IRB.start
|
data/bin/setup
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'cloudwatch_scheduler/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "cloudwatch_scheduler"
|
8
|
+
spec.version = CloudwatchScheduler::VERSION
|
9
|
+
spec.authors = ["Paul Sadauskas"]
|
10
|
+
spec.email = ["psadauskas@gmail.com"]
|
11
|
+
|
12
|
+
spec.summary = %q{Use AWS CloudWatch events to trigger recurring jobs.}
|
13
|
+
spec.description = %q{Use Cloudwatch Events to kick off recurring SQS ActiveJob jobs.}
|
14
|
+
spec.homepage = "https://github.com/paul/cloudwatch_scheduler"
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
17
|
+
spec.bindir = "exe"
|
18
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_dependency "aws-sdk", "~> 2.2"
|
22
|
+
spec.add_dependency "rails", ">= 4.2.0"
|
23
|
+
spec.add_dependency "shoryuken", "~> 2.0"
|
24
|
+
|
25
|
+
spec.add_development_dependency "bundler", "~> 1.12"
|
26
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
27
|
+
spec.add_development_dependency "rspec", "~> 3.0"
|
28
|
+
end
|
@@ -0,0 +1,209 @@
|
|
1
|
+
PATH
|
2
|
+
remote: ../
|
3
|
+
specs:
|
4
|
+
cloudwatch_scheduler (0.1.0)
|
5
|
+
aws-sdk (~> 2.2)
|
6
|
+
rails (>= 4.2.0)
|
7
|
+
shoryuken (~> 2.0)
|
8
|
+
|
9
|
+
GEM
|
10
|
+
remote: https://rubygems.org/
|
11
|
+
specs:
|
12
|
+
actionmailer (4.2.7)
|
13
|
+
actionpack (= 4.2.7)
|
14
|
+
actionview (= 4.2.7)
|
15
|
+
activejob (= 4.2.7)
|
16
|
+
mail (~> 2.5, >= 2.5.4)
|
17
|
+
rails-dom-testing (~> 1.0, >= 1.0.5)
|
18
|
+
actionpack (4.2.7)
|
19
|
+
actionview (= 4.2.7)
|
20
|
+
activesupport (= 4.2.7)
|
21
|
+
rack (~> 1.6)
|
22
|
+
rack-test (~> 0.6.2)
|
23
|
+
rails-dom-testing (~> 1.0, >= 1.0.5)
|
24
|
+
rails-html-sanitizer (~> 1.0, >= 1.0.2)
|
25
|
+
actionview (4.2.7)
|
26
|
+
activesupport (= 4.2.7)
|
27
|
+
builder (~> 3.1)
|
28
|
+
erubis (~> 2.7.0)
|
29
|
+
rails-dom-testing (~> 1.0, >= 1.0.5)
|
30
|
+
rails-html-sanitizer (~> 1.0, >= 1.0.2)
|
31
|
+
activejob (4.2.7)
|
32
|
+
activesupport (= 4.2.7)
|
33
|
+
globalid (>= 0.3.0)
|
34
|
+
activemodel (4.2.7)
|
35
|
+
activesupport (= 4.2.7)
|
36
|
+
builder (~> 3.1)
|
37
|
+
activerecord (4.2.7)
|
38
|
+
activemodel (= 4.2.7)
|
39
|
+
activesupport (= 4.2.7)
|
40
|
+
arel (~> 6.0)
|
41
|
+
activesupport (4.2.7)
|
42
|
+
i18n (~> 0.7)
|
43
|
+
json (~> 1.7, >= 1.7.7)
|
44
|
+
minitest (~> 5.1)
|
45
|
+
thread_safe (~> 0.3, >= 0.3.4)
|
46
|
+
tzinfo (~> 1.1)
|
47
|
+
appraisal (2.1.0)
|
48
|
+
bundler
|
49
|
+
rake
|
50
|
+
thor (>= 0.14.0)
|
51
|
+
arel (6.0.3)
|
52
|
+
awesome_print (1.7.0)
|
53
|
+
aws-sdk (2.4.4)
|
54
|
+
aws-sdk-resources (= 2.4.4)
|
55
|
+
aws-sdk-core (2.4.4)
|
56
|
+
jmespath (~> 1.0)
|
57
|
+
aws-sdk-resources (2.4.4)
|
58
|
+
aws-sdk-core (= 2.4.4)
|
59
|
+
builder (3.2.2)
|
60
|
+
celluloid (0.17.3)
|
61
|
+
celluloid-essentials
|
62
|
+
celluloid-extras
|
63
|
+
celluloid-fsm
|
64
|
+
celluloid-pool
|
65
|
+
celluloid-supervision
|
66
|
+
timers (>= 4.1.1)
|
67
|
+
celluloid-essentials (0.20.5)
|
68
|
+
timers (>= 4.1.1)
|
69
|
+
celluloid-extras (0.20.5)
|
70
|
+
timers (>= 4.1.1)
|
71
|
+
celluloid-fsm (0.20.5)
|
72
|
+
timers (>= 4.1.1)
|
73
|
+
celluloid-pool (0.20.5)
|
74
|
+
timers (>= 4.1.1)
|
75
|
+
celluloid-supervision (0.20.6)
|
76
|
+
timers (>= 4.1.1)
|
77
|
+
coderay (1.1.1)
|
78
|
+
concurrent-ruby (1.0.2)
|
79
|
+
diff-lcs (1.2.5)
|
80
|
+
erubis (2.7.0)
|
81
|
+
ffi (1.9.14)
|
82
|
+
formatador (0.2.5)
|
83
|
+
globalid (0.3.7)
|
84
|
+
activesupport (>= 4.1.0)
|
85
|
+
guard (2.14.0)
|
86
|
+
formatador (>= 0.2.4)
|
87
|
+
listen (>= 2.7, < 4.0)
|
88
|
+
lumberjack (~> 1.0)
|
89
|
+
nenv (~> 0.1)
|
90
|
+
notiffany (~> 0.0)
|
91
|
+
pry (>= 0.9.12)
|
92
|
+
shellany (~> 0.0)
|
93
|
+
thor (>= 0.18.1)
|
94
|
+
guard-compat (1.2.1)
|
95
|
+
guard-rspec (4.7.3)
|
96
|
+
guard (~> 2.1)
|
97
|
+
guard-compat (~> 1.1)
|
98
|
+
rspec (>= 2.99.0, < 4.0)
|
99
|
+
hitimes (1.2.4)
|
100
|
+
i18n (0.7.0)
|
101
|
+
jmespath (1.3.1)
|
102
|
+
json (1.8.3)
|
103
|
+
listen (3.1.5)
|
104
|
+
rb-fsevent (~> 0.9, >= 0.9.4)
|
105
|
+
rb-inotify (~> 0.9, >= 0.9.7)
|
106
|
+
ruby_dep (~> 1.2)
|
107
|
+
loofah (2.0.3)
|
108
|
+
nokogiri (>= 1.5.9)
|
109
|
+
lumberjack (1.0.10)
|
110
|
+
mail (2.6.4)
|
111
|
+
mime-types (>= 1.16, < 4)
|
112
|
+
method_source (0.8.2)
|
113
|
+
mime-types (3.1)
|
114
|
+
mime-types-data (~> 3.2015)
|
115
|
+
mime-types-data (3.2016.0521)
|
116
|
+
mini_portile2 (2.1.0)
|
117
|
+
minitest (5.9.0)
|
118
|
+
nenv (0.3.0)
|
119
|
+
nokogiri (1.6.8)
|
120
|
+
mini_portile2 (~> 2.1.0)
|
121
|
+
pkg-config (~> 1.1.7)
|
122
|
+
notiffany (0.1.1)
|
123
|
+
nenv (~> 0.1)
|
124
|
+
shellany (~> 0.0)
|
125
|
+
pkg-config (1.1.7)
|
126
|
+
pry (0.10.4)
|
127
|
+
coderay (~> 1.1.0)
|
128
|
+
method_source (~> 0.8.1)
|
129
|
+
slop (~> 3.4)
|
130
|
+
rack (1.6.4)
|
131
|
+
rack-test (0.6.3)
|
132
|
+
rack (>= 1.0)
|
133
|
+
rails (4.2.7)
|
134
|
+
actionmailer (= 4.2.7)
|
135
|
+
actionpack (= 4.2.7)
|
136
|
+
actionview (= 4.2.7)
|
137
|
+
activejob (= 4.2.7)
|
138
|
+
activemodel (= 4.2.7)
|
139
|
+
activerecord (= 4.2.7)
|
140
|
+
activesupport (= 4.2.7)
|
141
|
+
bundler (>= 1.3.0, < 2.0)
|
142
|
+
railties (= 4.2.7)
|
143
|
+
sprockets-rails
|
144
|
+
rails-deprecated_sanitizer (1.0.3)
|
145
|
+
activesupport (>= 4.2.0.alpha)
|
146
|
+
rails-dom-testing (1.0.7)
|
147
|
+
activesupport (>= 4.2.0.beta, < 5.0)
|
148
|
+
nokogiri (~> 1.6.0)
|
149
|
+
rails-deprecated_sanitizer (>= 1.0.1)
|
150
|
+
rails-html-sanitizer (1.0.3)
|
151
|
+
loofah (~> 2.0)
|
152
|
+
railties (4.2.7)
|
153
|
+
actionpack (= 4.2.7)
|
154
|
+
activesupport (= 4.2.7)
|
155
|
+
rake (>= 0.8.7)
|
156
|
+
thor (>= 0.18.1, < 2.0)
|
157
|
+
rake (10.5.0)
|
158
|
+
rb-fsevent (0.9.7)
|
159
|
+
rb-inotify (0.9.7)
|
160
|
+
ffi (>= 0.5.0)
|
161
|
+
rspec (3.5.0)
|
162
|
+
rspec-core (~> 3.5.0)
|
163
|
+
rspec-expectations (~> 3.5.0)
|
164
|
+
rspec-mocks (~> 3.5.0)
|
165
|
+
rspec-core (3.5.2)
|
166
|
+
rspec-support (~> 3.5.0)
|
167
|
+
rspec-expectations (3.5.0)
|
168
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
169
|
+
rspec-support (~> 3.5.0)
|
170
|
+
rspec-mocks (3.5.0)
|
171
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
172
|
+
rspec-support (~> 3.5.0)
|
173
|
+
rspec-support (3.5.0)
|
174
|
+
ruby_dep (1.3.1)
|
175
|
+
shellany (0.0.1)
|
176
|
+
shoryuken (2.0.11)
|
177
|
+
aws-sdk-core (~> 2)
|
178
|
+
celluloid (~> 0.16)
|
179
|
+
slop (3.6.0)
|
180
|
+
sprockets (3.7.0)
|
181
|
+
concurrent-ruby (~> 1.0)
|
182
|
+
rack (> 1, < 3)
|
183
|
+
sprockets-rails (3.1.1)
|
184
|
+
actionpack (>= 4.0)
|
185
|
+
activesupport (>= 4.0)
|
186
|
+
sprockets (>= 3.0.0)
|
187
|
+
thor (0.19.1)
|
188
|
+
thread_safe (0.3.5)
|
189
|
+
timers (4.1.1)
|
190
|
+
hitimes
|
191
|
+
tzinfo (1.2.2)
|
192
|
+
thread_safe (~> 0.1)
|
193
|
+
|
194
|
+
PLATFORMS
|
195
|
+
ruby
|
196
|
+
|
197
|
+
DEPENDENCIES
|
198
|
+
appraisal
|
199
|
+
awesome_print
|
200
|
+
bundler (~> 1.12)
|
201
|
+
guard
|
202
|
+
guard-rspec
|
203
|
+
cloudwatch_scheduler!
|
204
|
+
rails (~> 4.2.0)
|
205
|
+
rake (~> 10.0)
|
206
|
+
rspec (~> 3.0)
|
207
|
+
|
208
|
+
BUNDLED WITH
|
209
|
+
1.12.5
|
@@ -0,0 +1,213 @@
|
|
1
|
+
PATH
|
2
|
+
remote: ../
|
3
|
+
specs:
|
4
|
+
cloudwatch_scheduler (0.1.0)
|
5
|
+
aws-sdk (~> 2.2)
|
6
|
+
rails (>= 4.2.0)
|
7
|
+
shoryuken (~> 2.0)
|
8
|
+
|
9
|
+
GEM
|
10
|
+
remote: https://rubygems.org/
|
11
|
+
specs:
|
12
|
+
actioncable (5.0.0)
|
13
|
+
actionpack (= 5.0.0)
|
14
|
+
nio4r (~> 1.2)
|
15
|
+
websocket-driver (~> 0.6.1)
|
16
|
+
actionmailer (5.0.0)
|
17
|
+
actionpack (= 5.0.0)
|
18
|
+
actionview (= 5.0.0)
|
19
|
+
activejob (= 5.0.0)
|
20
|
+
mail (~> 2.5, >= 2.5.4)
|
21
|
+
rails-dom-testing (~> 2.0)
|
22
|
+
actionpack (5.0.0)
|
23
|
+
actionview (= 5.0.0)
|
24
|
+
activesupport (= 5.0.0)
|
25
|
+
rack (~> 2.0)
|
26
|
+
rack-test (~> 0.6.3)
|
27
|
+
rails-dom-testing (~> 2.0)
|
28
|
+
rails-html-sanitizer (~> 1.0, >= 1.0.2)
|
29
|
+
actionview (5.0.0)
|
30
|
+
activesupport (= 5.0.0)
|
31
|
+
builder (~> 3.1)
|
32
|
+
erubis (~> 2.7.0)
|
33
|
+
rails-dom-testing (~> 2.0)
|
34
|
+
rails-html-sanitizer (~> 1.0, >= 1.0.2)
|
35
|
+
activejob (5.0.0)
|
36
|
+
activesupport (= 5.0.0)
|
37
|
+
globalid (>= 0.3.6)
|
38
|
+
activemodel (5.0.0)
|
39
|
+
activesupport (= 5.0.0)
|
40
|
+
activerecord (5.0.0)
|
41
|
+
activemodel (= 5.0.0)
|
42
|
+
activesupport (= 5.0.0)
|
43
|
+
arel (~> 7.0)
|
44
|
+
activesupport (5.0.0)
|
45
|
+
concurrent-ruby (~> 1.0, >= 1.0.2)
|
46
|
+
i18n (~> 0.7)
|
47
|
+
minitest (~> 5.1)
|
48
|
+
tzinfo (~> 1.1)
|
49
|
+
appraisal (2.1.0)
|
50
|
+
bundler
|
51
|
+
rake
|
52
|
+
thor (>= 0.14.0)
|
53
|
+
arel (7.1.1)
|
54
|
+
awesome_print (1.7.0)
|
55
|
+
aws-sdk (2.4.4)
|
56
|
+
aws-sdk-resources (= 2.4.4)
|
57
|
+
aws-sdk-core (2.4.4)
|
58
|
+
jmespath (~> 1.0)
|
59
|
+
aws-sdk-resources (2.4.4)
|
60
|
+
aws-sdk-core (= 2.4.4)
|
61
|
+
builder (3.2.2)
|
62
|
+
celluloid (0.17.3)
|
63
|
+
celluloid-essentials
|
64
|
+
celluloid-extras
|
65
|
+
celluloid-fsm
|
66
|
+
celluloid-pool
|
67
|
+
celluloid-supervision
|
68
|
+
timers (>= 4.1.1)
|
69
|
+
celluloid-essentials (0.20.5)
|
70
|
+
timers (>= 4.1.1)
|
71
|
+
celluloid-extras (0.20.5)
|
72
|
+
timers (>= 4.1.1)
|
73
|
+
celluloid-fsm (0.20.5)
|
74
|
+
timers (>= 4.1.1)
|
75
|
+
celluloid-pool (0.20.5)
|
76
|
+
timers (>= 4.1.1)
|
77
|
+
celluloid-supervision (0.20.6)
|
78
|
+
timers (>= 4.1.1)
|
79
|
+
coderay (1.1.1)
|
80
|
+
concurrent-ruby (1.0.2)
|
81
|
+
diff-lcs (1.2.5)
|
82
|
+
erubis (2.7.0)
|
83
|
+
ffi (1.9.14)
|
84
|
+
formatador (0.2.5)
|
85
|
+
globalid (0.3.7)
|
86
|
+
activesupport (>= 4.1.0)
|
87
|
+
guard (2.14.0)
|
88
|
+
formatador (>= 0.2.4)
|
89
|
+
listen (>= 2.7, < 4.0)
|
90
|
+
lumberjack (~> 1.0)
|
91
|
+
nenv (~> 0.1)
|
92
|
+
notiffany (~> 0.0)
|
93
|
+
pry (>= 0.9.12)
|
94
|
+
shellany (~> 0.0)
|
95
|
+
thor (>= 0.18.1)
|
96
|
+
guard-compat (1.2.1)
|
97
|
+
guard-rspec (4.7.3)
|
98
|
+
guard (~> 2.1)
|
99
|
+
guard-compat (~> 1.1)
|
100
|
+
rspec (>= 2.99.0, < 4.0)
|
101
|
+
hitimes (1.2.4)
|
102
|
+
i18n (0.7.0)
|
103
|
+
jmespath (1.3.1)
|
104
|
+
listen (3.1.5)
|
105
|
+
rb-fsevent (~> 0.9, >= 0.9.4)
|
106
|
+
rb-inotify (~> 0.9, >= 0.9.7)
|
107
|
+
ruby_dep (~> 1.2)
|
108
|
+
loofah (2.0.3)
|
109
|
+
nokogiri (>= 1.5.9)
|
110
|
+
lumberjack (1.0.10)
|
111
|
+
mail (2.6.4)
|
112
|
+
mime-types (>= 1.16, < 4)
|
113
|
+
method_source (0.8.2)
|
114
|
+
mime-types (3.1)
|
115
|
+
mime-types-data (~> 3.2015)
|
116
|
+
mime-types-data (3.2016.0521)
|
117
|
+
mini_portile2 (2.1.0)
|
118
|
+
minitest (5.9.0)
|
119
|
+
nenv (0.3.0)
|
120
|
+
nio4r (1.2.1)
|
121
|
+
nokogiri (1.6.8)
|
122
|
+
mini_portile2 (~> 2.1.0)
|
123
|
+
pkg-config (~> 1.1.7)
|
124
|
+
notiffany (0.1.1)
|
125
|
+
nenv (~> 0.1)
|
126
|
+
shellany (~> 0.0)
|
127
|
+
pkg-config (1.1.7)
|
128
|
+
pry (0.10.4)
|
129
|
+
coderay (~> 1.1.0)
|
130
|
+
method_source (~> 0.8.1)
|
131
|
+
slop (~> 3.4)
|
132
|
+
rack (2.0.1)
|
133
|
+
rack-test (0.6.3)
|
134
|
+
rack (>= 1.0)
|
135
|
+
rails (5.0.0)
|
136
|
+
actioncable (= 5.0.0)
|
137
|
+
actionmailer (= 5.0.0)
|
138
|
+
actionpack (= 5.0.0)
|
139
|
+
actionview (= 5.0.0)
|
140
|
+
activejob (= 5.0.0)
|
141
|
+
activemodel (= 5.0.0)
|
142
|
+
activerecord (= 5.0.0)
|
143
|
+
activesupport (= 5.0.0)
|
144
|
+
bundler (>= 1.3.0, < 2.0)
|
145
|
+
railties (= 5.0.0)
|
146
|
+
sprockets-rails (>= 2.0.0)
|
147
|
+
rails-dom-testing (2.0.1)
|
148
|
+
activesupport (>= 4.2.0, < 6.0)
|
149
|
+
nokogiri (~> 1.6.0)
|
150
|
+
rails-html-sanitizer (1.0.3)
|
151
|
+
loofah (~> 2.0)
|
152
|
+
railties (5.0.0)
|
153
|
+
actionpack (= 5.0.0)
|
154
|
+
activesupport (= 5.0.0)
|
155
|
+
method_source
|
156
|
+
rake (>= 0.8.7)
|
157
|
+
thor (>= 0.18.1, < 2.0)
|
158
|
+
rake (10.5.0)
|
159
|
+
rb-fsevent (0.9.7)
|
160
|
+
rb-inotify (0.9.7)
|
161
|
+
ffi (>= 0.5.0)
|
162
|
+
rspec (3.5.0)
|
163
|
+
rspec-core (~> 3.5.0)
|
164
|
+
rspec-expectations (~> 3.5.0)
|
165
|
+
rspec-mocks (~> 3.5.0)
|
166
|
+
rspec-core (3.5.2)
|
167
|
+
rspec-support (~> 3.5.0)
|
168
|
+
rspec-expectations (3.5.0)
|
169
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
170
|
+
rspec-support (~> 3.5.0)
|
171
|
+
rspec-mocks (3.5.0)
|
172
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
173
|
+
rspec-support (~> 3.5.0)
|
174
|
+
rspec-support (3.5.0)
|
175
|
+
ruby_dep (1.3.1)
|
176
|
+
shellany (0.0.1)
|
177
|
+
shoryuken (2.0.11)
|
178
|
+
aws-sdk-core (~> 2)
|
179
|
+
celluloid (~> 0.16)
|
180
|
+
slop (3.6.0)
|
181
|
+
sprockets (3.7.0)
|
182
|
+
concurrent-ruby (~> 1.0)
|
183
|
+
rack (> 1, < 3)
|
184
|
+
sprockets-rails (3.1.1)
|
185
|
+
actionpack (>= 4.0)
|
186
|
+
activesupport (>= 4.0)
|
187
|
+
sprockets (>= 3.0.0)
|
188
|
+
thor (0.19.1)
|
189
|
+
thread_safe (0.3.5)
|
190
|
+
timers (4.1.1)
|
191
|
+
hitimes
|
192
|
+
tzinfo (1.2.2)
|
193
|
+
thread_safe (~> 0.1)
|
194
|
+
websocket-driver (0.6.4)
|
195
|
+
websocket-extensions (>= 0.1.0)
|
196
|
+
websocket-extensions (0.1.2)
|
197
|
+
|
198
|
+
PLATFORMS
|
199
|
+
ruby
|
200
|
+
|
201
|
+
DEPENDENCIES
|
202
|
+
appraisal
|
203
|
+
awesome_print
|
204
|
+
bundler (~> 1.12)
|
205
|
+
guard
|
206
|
+
guard-rspec
|
207
|
+
cloudwatch_scheduler!
|
208
|
+
rails (~> 5.0.0)
|
209
|
+
rake (~> 10.0)
|
210
|
+
rspec (~> 3.0)
|
211
|
+
|
212
|
+
BUNDLED WITH
|
213
|
+
1.12.5
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require "active_support/core_ext/numeric/time"
|
2
|
+
|
3
|
+
module CloudwatchScheduler
|
4
|
+
class Configuration
|
5
|
+
|
6
|
+
attr_accessor :queue_name,
|
7
|
+
:queue_visibility_timeout,
|
8
|
+
:queue_max_receive_count,
|
9
|
+
:use_dead_letter_queue
|
10
|
+
|
11
|
+
attr_reader :tasks
|
12
|
+
|
13
|
+
def initialize
|
14
|
+
@tasks = {}
|
15
|
+
set_defaults
|
16
|
+
end
|
17
|
+
|
18
|
+
def configure(&config)
|
19
|
+
instance_exec(self, &config)
|
20
|
+
self
|
21
|
+
end
|
22
|
+
|
23
|
+
def task(name, **kwargs, &task)
|
24
|
+
@tasks[name] = Task.new(name, **kwargs, &task)
|
25
|
+
end
|
26
|
+
|
27
|
+
def set_defaults
|
28
|
+
@queue_visibility_timeout = 1.minute
|
29
|
+
@queue_max_receive_count = 2
|
30
|
+
@use_dead_letter_queue = true
|
31
|
+
end
|
32
|
+
|
33
|
+
def queue_name
|
34
|
+
@queue_name ||= CloudwatchScheduler::Job.queue_name
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
|
2
|
+
module CloudwatchScheduler
|
3
|
+
class Engine < Rails::Engine
|
4
|
+
initializer "cloudwatch_scheduler.setup_job" do
|
5
|
+
# Have to do this in initializer rather than require time because it
|
6
|
+
# inherits from ApplicationJob
|
7
|
+
require "cloudwatch_scheduler/job"
|
8
|
+
|
9
|
+
# Explicitly register this worker, because Shoryuken expects the message
|
10
|
+
# attributes to specify the job class, and these jobs are produced by
|
11
|
+
# Cloudwatch Events, which provide no way to set message attributes
|
12
|
+
Shoryuken.worker_registry.register_worker(
|
13
|
+
CloudwatchScheduler::Job.queue_name,
|
14
|
+
ActiveJob::QueueAdapters::ShoryukenAdapter::JobWrapper
|
15
|
+
)
|
16
|
+
end
|
17
|
+
|
18
|
+
rake_tasks do
|
19
|
+
load "cloudwatch_scheduler/tasks/setup.rake"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module CloudwatchScheduler
|
2
|
+
class Job < ::ApplicationJob
|
3
|
+
queue_as :cloudwatch_scheduler
|
4
|
+
|
5
|
+
def initialize(config: CloudwatchScheduler.global)
|
6
|
+
@config = config
|
7
|
+
end
|
8
|
+
|
9
|
+
def perform(job_to_spawn)
|
10
|
+
@config.tasks[job_to_spawn].invoke
|
11
|
+
end
|
12
|
+
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,117 @@
|
|
1
|
+
require "aws-sdk"
|
2
|
+
|
3
|
+
module CloudwatchScheduler
|
4
|
+
class Provisioner
|
5
|
+
|
6
|
+
attr_reader :config
|
7
|
+
|
8
|
+
def initialize(config, sqs_client: Aws::SQS::Client.new,
|
9
|
+
cwe_client: Aws::CloudWatchEvents::Client.new)
|
10
|
+
@config = config
|
11
|
+
@sqs_client, @cwe_client = sqs_client, cwe_client
|
12
|
+
end
|
13
|
+
|
14
|
+
def provision
|
15
|
+
create_queue!
|
16
|
+
create_events!
|
17
|
+
end
|
18
|
+
|
19
|
+
def create_queue!
|
20
|
+
attributes = { "VisibilityTimeout" => config.queue_visibility_timeout.to_s }
|
21
|
+
@queue_url = sqs.create_queue(queue_name: queue_name, attributes: attributes).queue_url
|
22
|
+
|
23
|
+
if config.use_dead_letter_queue
|
24
|
+
dlq_name = queue_name + "-failures"
|
25
|
+
dlq_url = sqs.create_queue(queue_name: dlq_name).queue_url
|
26
|
+
dlq_arn = sqs.get_queue_attributes(queue_url: dlq_url, attribute_names: ["QueueArn"]).attributes["QueueArn"]
|
27
|
+
|
28
|
+
redrive_attrs = {
|
29
|
+
maxReceiveCount: config.queue_max_receive_count.to_s,
|
30
|
+
deadLetterTargetArn: dlq_arn
|
31
|
+
}.to_json
|
32
|
+
|
33
|
+
attributes = {"RedrivePolicy" => redrive_attrs}
|
34
|
+
|
35
|
+
sqs.set_queue_attributes(queue_url: queue_url, attributes: attributes)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def create_events!
|
40
|
+
rule_arns = config.tasks.map do |_name, task|
|
41
|
+
rule_arn = cwe.put_rule(
|
42
|
+
name: task.rule_name,
|
43
|
+
schedule_expression: task.rule_schedule_expression,
|
44
|
+
state: "ENABLED",
|
45
|
+
description: "CloudwatchScheduler task defined at #{task.code.source_location}"
|
46
|
+
).rule_arn
|
47
|
+
|
48
|
+
cwe.put_targets(
|
49
|
+
rule: task.rule_name,
|
50
|
+
targets: [
|
51
|
+
{
|
52
|
+
id: task.rule_name + "Target",
|
53
|
+
arn: queue_arn,
|
54
|
+
input: task.event_data.to_json
|
55
|
+
}
|
56
|
+
]
|
57
|
+
)
|
58
|
+
|
59
|
+
rule_arn
|
60
|
+
end
|
61
|
+
|
62
|
+
policy = {
|
63
|
+
"Version": "2012-10-17",
|
64
|
+
"Id": "#{queue_arn}/SQSDefaultPolicy",
|
65
|
+
"Statement": rule_arns.map { |rule_arn|
|
66
|
+
{
|
67
|
+
"Sid": "TrustCWESendingToSQS",
|
68
|
+
"Effect": "Allow",
|
69
|
+
"Principal": {
|
70
|
+
"AWS": "*"
|
71
|
+
},
|
72
|
+
"Action": "sqs:SendMessage",
|
73
|
+
"Resource": queue_arn,
|
74
|
+
"Condition": {
|
75
|
+
"ArnEquals": {
|
76
|
+
"aws:SourceArn": rule_arn
|
77
|
+
}
|
78
|
+
}
|
79
|
+
}
|
80
|
+
}
|
81
|
+
}
|
82
|
+
|
83
|
+
sqs.set_queue_attributes(
|
84
|
+
queue_url: queue_url,
|
85
|
+
attributes: {
|
86
|
+
"Policy" => policy.to_json
|
87
|
+
}
|
88
|
+
)
|
89
|
+
end
|
90
|
+
|
91
|
+
private
|
92
|
+
|
93
|
+
def queue_name
|
94
|
+
config.queue_name
|
95
|
+
end
|
96
|
+
|
97
|
+
def queue_url
|
98
|
+
@queue_url ||= sqs.get_queue_url(queue_name: queue_name).queue_url
|
99
|
+
end
|
100
|
+
|
101
|
+
def queue_arn
|
102
|
+
@queue_arn ||=
|
103
|
+
sqs
|
104
|
+
.get_queue_attributes(queue_url: queue_url, attribute_names: ["QueueArn"])
|
105
|
+
.attributes["QueueArn"]
|
106
|
+
end
|
107
|
+
|
108
|
+
def cwe
|
109
|
+
@cwe_client
|
110
|
+
end
|
111
|
+
|
112
|
+
def sqs
|
113
|
+
@sqs_client
|
114
|
+
end
|
115
|
+
|
116
|
+
end
|
117
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
require 'active_support/core_ext/digest/uuid'
|
2
|
+
|
3
|
+
module CloudwatchScheduler
|
4
|
+
class Task
|
5
|
+
attr_reader :name, :code
|
6
|
+
|
7
|
+
def initialize(name, every: nil, cron: nil, &code)
|
8
|
+
@name = name
|
9
|
+
@every, @cron = every, cron
|
10
|
+
fail "You must specify one of every: or cron:" unless [@every, @cron].any?
|
11
|
+
@code = code
|
12
|
+
end
|
13
|
+
|
14
|
+
def invoke
|
15
|
+
code.call
|
16
|
+
end
|
17
|
+
|
18
|
+
def job_id
|
19
|
+
Digest::UUID.uuid_v5(Digest::UUID::DNS_NAMESPACE, name)
|
20
|
+
end
|
21
|
+
|
22
|
+
# {"job_class":"PollActionJob","job_id":"d319ca2e-235f-492b-ab9d-a76d35490ae9",
|
23
|
+
# "queue_name":"scalar-production-poller","priority":null,"arguments":[433],
|
24
|
+
# "locale":"en"}
|
25
|
+
def event_data
|
26
|
+
{
|
27
|
+
job_class: CloudwatchScheduler::Job.name,
|
28
|
+
job_id: job_id,
|
29
|
+
queue_name: CloudwatchScheduler::Job.queue_name,
|
30
|
+
arguments: [name],
|
31
|
+
locale: "en",
|
32
|
+
priority: nil
|
33
|
+
}
|
34
|
+
end
|
35
|
+
|
36
|
+
def rule_name
|
37
|
+
[name, CloudwatchScheduler::Job.queue_name].join("-")
|
38
|
+
end
|
39
|
+
|
40
|
+
def rule_schedule_expression
|
41
|
+
if @every
|
42
|
+
rate_exp
|
43
|
+
else
|
44
|
+
cron_exp
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def rate_exp
|
49
|
+
units = if @every % 1.day == 0
|
50
|
+
"day"
|
51
|
+
elsif @every % 1.hour == 0
|
52
|
+
"hour"
|
53
|
+
elsif @every % 1.minute == 0
|
54
|
+
"minute"
|
55
|
+
else
|
56
|
+
fail "Intervals less than 1 minute are not allowed by Cloudwatch Events."
|
57
|
+
end
|
58
|
+
|
59
|
+
qty = @every.to_i / 1.send(units)
|
60
|
+
|
61
|
+
"rate(#{qty.to_i} #{units.pluralize(qty)})"
|
62
|
+
end
|
63
|
+
|
64
|
+
def cron_exp
|
65
|
+
"cron(#{@cron})"
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
|
2
|
+
|
3
|
+
namespace :cloudwatch_scheduler do
|
4
|
+
|
5
|
+
desc "Create AWS Cloudwatch Event Rules for all defined tasks"
|
6
|
+
task :setup => :environment do
|
7
|
+
Aws.config[:logger] = Logger.new(STDOUT)
|
8
|
+
require Rails.root.join("config/cloudwatch_scheduler")
|
9
|
+
config = CloudwatchScheduler.global
|
10
|
+
CloudwatchScheduler::Provisioner.new(config).provision
|
11
|
+
end
|
12
|
+
|
13
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
|
2
|
+
require "cloudwatch_scheduler/configuration"
|
3
|
+
require "cloudwatch_scheduler/task"
|
4
|
+
require "cloudwatch_scheduler/provisioner"
|
5
|
+
|
6
|
+
require "cloudwatch_scheduler/engine" if defined?(Rails)
|
7
|
+
|
8
|
+
def CloudwatchScheduler(&config)
|
9
|
+
CloudwatchScheduler.global.tap { |c| c.configure(&config) }
|
10
|
+
end
|
11
|
+
|
12
|
+
module CloudwatchScheduler
|
13
|
+
|
14
|
+
def self.global
|
15
|
+
@global ||= CloudwatchScheduler::Configuration.new
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
|
metadata
ADDED
@@ -0,0 +1,151 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: cloudwatch_scheduler
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Paul Sadauskas
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-08-02 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: aws-sdk
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '2.2'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '2.2'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rails
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 4.2.0
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 4.2.0
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: shoryuken
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '2.0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '2.0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: bundler
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '1.12'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '1.12'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rake
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '10.0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '10.0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: rspec
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '3.0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '3.0'
|
97
|
+
description: Use Cloudwatch Events to kick off recurring SQS ActiveJob jobs.
|
98
|
+
email:
|
99
|
+
- psadauskas@gmail.com
|
100
|
+
executables: []
|
101
|
+
extensions: []
|
102
|
+
extra_rdoc_files: []
|
103
|
+
files:
|
104
|
+
- ".gitignore"
|
105
|
+
- ".rspec"
|
106
|
+
- ".rubocop.yml"
|
107
|
+
- ".travis.yml"
|
108
|
+
- Appraisals
|
109
|
+
- Gemfile
|
110
|
+
- Guardfile
|
111
|
+
- README.md
|
112
|
+
- Rakefile
|
113
|
+
- bin/console
|
114
|
+
- bin/setup
|
115
|
+
- cloudwatch_scheduler.gemspec
|
116
|
+
- gemfiles/rails_4.2.gemfile
|
117
|
+
- gemfiles/rails_4.2.gemfile.lock
|
118
|
+
- gemfiles/rails_5.0.gemfile
|
119
|
+
- gemfiles/rails_5.0.gemfile.lock
|
120
|
+
- lib/cloudwatch_scheduler.rb
|
121
|
+
- lib/cloudwatch_scheduler/configuration.rb
|
122
|
+
- lib/cloudwatch_scheduler/engine.rb
|
123
|
+
- lib/cloudwatch_scheduler/job.rb
|
124
|
+
- lib/cloudwatch_scheduler/provisioner.rb
|
125
|
+
- lib/cloudwatch_scheduler/task.rb
|
126
|
+
- lib/cloudwatch_scheduler/tasks/setup.rake
|
127
|
+
- lib/cloudwatch_scheduler/version.rb
|
128
|
+
homepage: https://github.com/paul/cloudwatch_scheduler
|
129
|
+
licenses: []
|
130
|
+
metadata: {}
|
131
|
+
post_install_message:
|
132
|
+
rdoc_options: []
|
133
|
+
require_paths:
|
134
|
+
- lib
|
135
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
136
|
+
requirements:
|
137
|
+
- - ">="
|
138
|
+
- !ruby/object:Gem::Version
|
139
|
+
version: '0'
|
140
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
141
|
+
requirements:
|
142
|
+
- - ">="
|
143
|
+
- !ruby/object:Gem::Version
|
144
|
+
version: '0'
|
145
|
+
requirements: []
|
146
|
+
rubyforge_project:
|
147
|
+
rubygems_version: 2.5.1
|
148
|
+
signing_key:
|
149
|
+
specification_version: 4
|
150
|
+
summary: Use AWS CloudWatch events to trigger recurring jobs.
|
151
|
+
test_files: []
|