deify 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +3 -0
- data/LICENSE +20 -0
- data/README.md +65 -0
- data/Rakefile +15 -0
- data/deify.gemspec +20 -0
- data/lib/deify.rb +5 -0
- data/lib/deify/engine.rb +13 -0
- data/lib/generators/install_generator.rb +15 -0
- data/lib/generators/templates/redis.yml +16 -0
- data/lib/generators/templates/resque.god +55 -0
- data/lib/generators/templates/resque.rb +18 -0
- metadata +90 -0
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2012 Monica McArthur
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,65 @@
|
|
1
|
+
Surety
|
2
|
+
============
|
3
|
+
|
4
|
+
A lightweight guaranteed-delivery messaging system.
|
5
|
+
|
6
|
+
|
7
|
+
Dependency Notes
|
8
|
+
================
|
9
|
+
|
10
|
+
* Surety uses ActiveRecord to persist the message requests in order to provide transactional, guaranteed-delivery requests. Requires ActiveRecord 3.0.0 or higher.
|
11
|
+
* Surety uses Resque to underpin the message processing/retry loop. Requires Resque 1.19.0 or higher.
|
12
|
+
|
13
|
+
|
14
|
+
Usage / Examples
|
15
|
+
================
|
16
|
+
|
17
|
+
A simple class that can send a message for guaranteed delivery:
|
18
|
+
|
19
|
+
class TestGenerator
|
20
|
+
include Surety::Generator
|
21
|
+
|
22
|
+
def some_method
|
23
|
+
self.send_message(message_content)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
|
28
|
+
On the server side, to start up the loop to process messages:
|
29
|
+
|
30
|
+
Surety::Processor.request_next
|
31
|
+
|
32
|
+
|
33
|
+
Configuration
|
34
|
+
=============
|
35
|
+
|
36
|
+
Both the prefix for the ActiveRecord database connection name (as specified in database.yml) and the class to which Surety delegates messages for processing after pulling them off the queue are configurable.
|
37
|
+
|
38
|
+
Also configurable are three parameters related to failure retries:
|
39
|
+
* retry interval: base amount of time to wait before a retry, in minutes. Defaults to 10.
|
40
|
+
* backoff factor: factor to divide the failure count by before calculating an exponential backoff. The backoff factor is (2^floor(failure count/backoff interval)). Defaults to 2.
|
41
|
+
* max backoff: maximum number of powers of 2 to backoff. Defaults to 7 (which gives a backoff factor of 128; together with the default retry interval of 10, this produces a default max backoff amount of 1280 minutes ~ 1 day).
|
42
|
+
|
43
|
+
Example configuration (from a sample config/initializers/surety.rb file)
|
44
|
+
|
45
|
+
Surety::Configuration.database_prefix = 'surety_'
|
46
|
+
Surety::Configuration.message_processing_delegate = MessageDistributor
|
47
|
+
Surety::Configuration.retry_interval = 20
|
48
|
+
Surety::Configuration.backoff_factor = 4
|
49
|
+
Surety::Configuration.max_backoff = 5
|
50
|
+
|
51
|
+
|
52
|
+
Install
|
53
|
+
=======
|
54
|
+
|
55
|
+
### As a gem
|
56
|
+
|
57
|
+
$ gem install surety
|
58
|
+
|
59
|
+
|
60
|
+
Acknowledgements
|
61
|
+
================
|
62
|
+
|
63
|
+
Copyright (c) 2012 Monica McArthur, released under the MIT license.
|
64
|
+
|
65
|
+
Thanks to Ryan and Steve for arguing that this gem was necessary... it is.
|
data/Rakefile
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'rake'
|
2
|
+
require 'rake/testtask'
|
3
|
+
require 'bundler'
|
4
|
+
Bundler::GemHelper.install_tasks
|
5
|
+
|
6
|
+
desc 'Default: run unit tests.'
|
7
|
+
task :default => :test
|
8
|
+
|
9
|
+
desc 'Test the surety gem.'
|
10
|
+
Rake::TestTask.new(:test) do |t|
|
11
|
+
t.libs << 'lib'
|
12
|
+
t.libs << 'test'
|
13
|
+
t.pattern = 'test/**/*_test.rb'
|
14
|
+
t.verbose = true
|
15
|
+
end
|
data/deify.gemspec
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Gem::Specification.new do |s|
|
2
|
+
s.name = 'deify'
|
3
|
+
s.version = '0.0.1'
|
4
|
+
s.date = Time.now.strftime('%Y-%m-%d')
|
5
|
+
s.summary = 'Sets up god/resque/redis configuration for any app using resque-based gems at Revolution Prep.'
|
6
|
+
s.homepage = ''
|
7
|
+
s.email = 'monica@revolutionprep.com'
|
8
|
+
s.authors = ['Monica McArthur']
|
9
|
+
|
10
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
11
|
+
s.files = `git ls-files`.split("\n")
|
12
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
13
|
+
s.require_paths = ['lib']
|
14
|
+
|
15
|
+
s.add_dependency('rails', '>= 3.0.0')
|
16
|
+
|
17
|
+
s.description = <<-DESC
|
18
|
+
Sets up god/resque/redis configuration for any app using resque-based gems at Revolution Prep.
|
19
|
+
DESC
|
20
|
+
end
|
data/lib/deify.rb
ADDED
data/lib/deify/engine.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'rails/generators'
|
2
|
+
|
3
|
+
module Deify
|
4
|
+
class InstallGenerator < Rails::Generators::Base
|
5
|
+
|
6
|
+
source_root File.join(File.dirname(__FILE__), 'templates')
|
7
|
+
|
8
|
+
def manifest
|
9
|
+
copy_file "resque.god", "config/god/resque.god"
|
10
|
+
copy_file "redis.yml", "config/redis.yml"
|
11
|
+
copy_file "resque.rb", "config/initializers/resque.rb"
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
app_name = 'your_app_name' # This should match the app name in deploy.rb
|
2
|
+
rails_env = ENV['RAILS_ENV'] || "production"
|
3
|
+
rails_root = ENV['RAILS_ROOT'] || "/var/www/#{app_name}"
|
4
|
+
rake_cmd = rails_env != 'development' ? '/opt/ruby_ent/bin/rake' : '/usr/bin/rake'
|
5
|
+
num_workers = rails_env == 'production' ? 10 : 2
|
6
|
+
|
7
|
+
num_workers.times do |num|
|
8
|
+
God.watch do |w|
|
9
|
+
w.name = "#{app_name}-resque-#{num}"
|
10
|
+
w.group = "#{app_name}-resque"
|
11
|
+
w.interval = 30.seconds
|
12
|
+
w.env = {"QUEUE"=>"*", "RAILS_ENV"=>rails_env}
|
13
|
+
w.start = "#{rake_cmd} -f #{rails_root}/Rakefile environment resque:work"
|
14
|
+
w.stop_signal = 'QUIT'
|
15
|
+
w.stop_timeout = 60.seconds
|
16
|
+
w.log = "#{rails_root}/log/god.log"
|
17
|
+
|
18
|
+
# restart if memory gets too high
|
19
|
+
w.transition(:up, :restart) do |on|
|
20
|
+
on.condition(:memory_usage) do |c|
|
21
|
+
c.above = 350.megabytes
|
22
|
+
c.times = 2
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
# determine the state on startup
|
27
|
+
w.transition(:init, { true => :up, false => :start }) do |on|
|
28
|
+
on.condition(:process_running) do |c|
|
29
|
+
c.running = true
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
# determine when process has finished starting
|
34
|
+
w.transition([:start, :restart], :up) do |on|
|
35
|
+
on.condition(:process_running) do |c|
|
36
|
+
c.running = true
|
37
|
+
c.interval = 5.seconds
|
38
|
+
end
|
39
|
+
|
40
|
+
# failsafe
|
41
|
+
on.condition(:tries) do |c|
|
42
|
+
c.times = 5
|
43
|
+
c.transition = :start
|
44
|
+
c.interval = 5.seconds
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
# start if process is not running
|
49
|
+
w.transition(:up, :start) do |on|
|
50
|
+
on.condition(:process_running) do |c|
|
51
|
+
c.running = false
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# Put this file in config/initializers to control how resque and resque-pubsub are run
|
2
|
+
|
3
|
+
rails_root = ENV['RAILS_ROOT'] || File.dirname(__FILE__) + '/../..'
|
4
|
+
rails_env = ENV['RAILS_ENV'] || 'development'
|
5
|
+
|
6
|
+
require 'resque'
|
7
|
+
require 'resque/failure/base'
|
8
|
+
require 'resque/failure/redis'
|
9
|
+
require 'resque/failure/airbrake'
|
10
|
+
require 'resque/failure/multiple'
|
11
|
+
Resque::Failure::Multiple.classes = [Resque::Failure::Redis, Resque::Failure::Airbrake]
|
12
|
+
Resque::Failure.backend = Resque::Failure::Multiple
|
13
|
+
|
14
|
+
REDIS_CONFIG = YAML.load_file(rails_root + '/config/redis.yml')[rails_env]
|
15
|
+
Resque.redis = REDIS_CONFIG["host"] + ':' + REDIS_CONFIG["port"].to_s
|
16
|
+
|
17
|
+
# Replace 'your_app_name' below with the actual name of the application, or some other namespace if you desire
|
18
|
+
Resque.redis.namespace = rails_env=='test' ? 'resque:test_your_app_name' : 'resque:your_app_name'
|
metadata
ADDED
@@ -0,0 +1,90 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: deify
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 29
|
5
|
+
prerelease:
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 0
|
9
|
+
- 1
|
10
|
+
version: 0.0.1
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Monica McArthur
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2012-02-06 00:00:00 Z
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
name: rails
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
none: false
|
25
|
+
requirements:
|
26
|
+
- - ">="
|
27
|
+
- !ruby/object:Gem::Version
|
28
|
+
hash: 7
|
29
|
+
segments:
|
30
|
+
- 3
|
31
|
+
- 0
|
32
|
+
- 0
|
33
|
+
version: 3.0.0
|
34
|
+
type: :runtime
|
35
|
+
version_requirements: *id001
|
36
|
+
description: " Sets up god/resque/redis configuration for any app using resque-based gems at Revolution Prep.\n"
|
37
|
+
email: monica@revolutionprep.com
|
38
|
+
executables: []
|
39
|
+
|
40
|
+
extensions: []
|
41
|
+
|
42
|
+
extra_rdoc_files: []
|
43
|
+
|
44
|
+
files:
|
45
|
+
- Gemfile
|
46
|
+
- LICENSE
|
47
|
+
- README.md
|
48
|
+
- Rakefile
|
49
|
+
- deify.gemspec
|
50
|
+
- lib/deify.rb
|
51
|
+
- lib/deify/engine.rb
|
52
|
+
- lib/generators/install_generator.rb
|
53
|
+
- lib/generators/templates/redis.yml
|
54
|
+
- lib/generators/templates/resque.god
|
55
|
+
- lib/generators/templates/resque.rb
|
56
|
+
homepage: ""
|
57
|
+
licenses: []
|
58
|
+
|
59
|
+
post_install_message:
|
60
|
+
rdoc_options: []
|
61
|
+
|
62
|
+
require_paths:
|
63
|
+
- lib
|
64
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ">="
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
hash: 3
|
70
|
+
segments:
|
71
|
+
- 0
|
72
|
+
version: "0"
|
73
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
74
|
+
none: false
|
75
|
+
requirements:
|
76
|
+
- - ">="
|
77
|
+
- !ruby/object:Gem::Version
|
78
|
+
hash: 3
|
79
|
+
segments:
|
80
|
+
- 0
|
81
|
+
version: "0"
|
82
|
+
requirements: []
|
83
|
+
|
84
|
+
rubyforge_project:
|
85
|
+
rubygems_version: 1.8.10
|
86
|
+
signing_key:
|
87
|
+
specification_version: 3
|
88
|
+
summary: Sets up god/resque/redis configuration for any app using resque-based gems at Revolution Prep.
|
89
|
+
test_files: []
|
90
|
+
|