tread_mill 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +28 -0
  3. data/README.md +152 -0
  4. data/Rakefile +28 -0
  5. data/lib/tasks/tread_mill_tasks.rake +8 -0
  6. data/lib/tread_mill.rb +68 -0
  7. data/lib/tread_mill/fork_callbacks.rb +20 -0
  8. data/lib/tread_mill/queue_listener.rb +23 -0
  9. data/lib/tread_mill/railtie.rb +19 -0
  10. data/lib/tread_mill/version.rb +3 -0
  11. data/test/dummy/README.rdoc +28 -0
  12. data/test/dummy/Rakefile +6 -0
  13. data/test/dummy/app/assets/javascripts/application.js +13 -0
  14. data/test/dummy/app/assets/stylesheets/application.css +15 -0
  15. data/test/dummy/app/controllers/application_controller.rb +5 -0
  16. data/test/dummy/app/helpers/application_helper.rb +2 -0
  17. data/test/dummy/app/views/layouts/application.html.erb +14 -0
  18. data/test/dummy/bin/bundle +3 -0
  19. data/test/dummy/bin/rails +4 -0
  20. data/test/dummy/bin/rake +4 -0
  21. data/test/dummy/config.ru +4 -0
  22. data/test/dummy/config/application.rb +24 -0
  23. data/test/dummy/config/boot.rb +5 -0
  24. data/test/dummy/config/database.yml +25 -0
  25. data/test/dummy/config/environment.rb +5 -0
  26. data/test/dummy/config/environments/development.rb +37 -0
  27. data/test/dummy/config/environments/production.rb +82 -0
  28. data/test/dummy/config/environments/test.rb +39 -0
  29. data/test/dummy/config/initializers/assets.rb +8 -0
  30. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  31. data/test/dummy/config/initializers/cookies_serializer.rb +3 -0
  32. data/test/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  33. data/test/dummy/config/initializers/inflections.rb +16 -0
  34. data/test/dummy/config/initializers/mime_types.rb +4 -0
  35. data/test/dummy/config/initializers/session_store.rb +3 -0
  36. data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
  37. data/test/dummy/config/locales/en.yml +23 -0
  38. data/test/dummy/config/routes.rb +2 -0
  39. data/test/dummy/config/secrets.yml +22 -0
  40. data/test/dummy/db/test.sqlite3 +0 -0
  41. data/test/dummy/log/test.log +10 -0
  42. data/test/dummy/public/404.html +67 -0
  43. data/test/dummy/public/422.html +67 -0
  44. data/test/dummy/public/500.html +66 -0
  45. data/test/dummy/public/favicon.ico +0 -0
  46. data/test/integration/navigation_test.rb +10 -0
  47. data/test/queue_listener_test.rb +7 -0
  48. data/test/test_helper.rb +15 -0
  49. data/test/tread_mill_test.rb +7 -0
  50. metadata +173 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: f5cc9f12b5f080934e1e27c98fdd6c8bd1d49a7a
4
+ data.tar.gz: 860247bf4d4a9fc23508e41b5b2798c3c7ded808
5
+ SHA512:
6
+ metadata.gz: c3777805116b0a99afe44bf77be919099c3c7a075001e1be7e43ffb08557163b619c4c6ed80671abe575e0de80f38fe145cd3ef123cd10dbc56ef45c573d0e26
7
+ data.tar.gz: 63d5bb6e9f193a1003eab217155fc2ad7caa8f3415181da9a98f1718b79f6c30acdd8e249679408338a11bc17e9d25081756cae692e986ce3ea723ddb56a82e1
data/LICENSE ADDED
@@ -0,0 +1,28 @@
1
+ Copyright (c) 2014, Protobit
2
+ All rights reserved.
3
+
4
+ Redistribution and use in source and binary forms, with or without
5
+ modification, are permitted provided that the following conditions are met:
6
+
7
+ * Redistributions of source code must retain the above copyright notice, this
8
+ list of conditions and the following disclaimer.
9
+
10
+ * Redistributions in binary form must reproduce the above copyright notice,
11
+ this list of conditions and the following disclaimer in the documentation
12
+ and/or other materials provided with the distribution.
13
+
14
+ * Neither the name of the {organization} nor the names of its
15
+ contributors may be used to endorse or promote products derived from
16
+ this software without specific prior written permission.
17
+
18
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
22
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
+
@@ -0,0 +1,152 @@
1
+ # TreadMill
2
+
3
+ TreadMill Rails plugin for background workers. This gem is designed to integrate into an existing Rails application and provide immediate RabbitMQ integration using the Sneakers worker gem and Rails 4.2.0.beta1 ActiveJob.
4
+
5
+ ## Notes
6
+
7
+ Tags:
8
+
9
+ * [0.0.1](/Protobit/tread_mill/wiki/0.0.1) tag for Rails 4.1
10
+ * [0.0.2](/Protobit/tread_mill/wiki/0.0.1) tag for Rails 4.2.0.beta1
11
+ * HEAD or 0.0.3 tag for Rails 4.2 stable
12
+
13
+ ## Installation
14
+
15
+ Add this line to your applications's Gemfile:
16
+
17
+ ```
18
+ gem 'tread_mill'
19
+ ```
20
+
21
+ And then execute:
22
+
23
+ ```
24
+ bundle install
25
+ ```
26
+
27
+ ## Usage
28
+
29
+ ### Options
30
+
31
+ ```RUBY
32
+ module MyApp
33
+ class Application < Rails::Application
34
+ # Queues you wish to listen on.
35
+ config.active_job.queue_name_delimiter = '.'
36
+ config.active_job.queue_adapter = :sneakers
37
+ config.active_job.queue_base_name = 'amqp.myapplication'
38
+
39
+ # configure queues: amqp.myapplication.my_queue and amqp.myapplication.my_second_queue
40
+ config.tread_mill.queues = %w(my_queue my_second_queue)
41
+
42
+ # Configure 'ActionMailer#deliver_later': amqp.myapplication.mailers
43
+ config.tread_mill.queues << 'mailers'
44
+
45
+ # Optional: Probably best set in your sneakers configuration.
46
+ # config.tread_mill.workers = # of workers
47
+
48
+ end
49
+ end
50
+ ```
51
+
52
+ ### Running your ActiveJob based workers.
53
+
54
+ ```
55
+ rake tread_mill:run
56
+ ```
57
+
58
+ **That's it.**
59
+
60
+ ### Example Upstart:
61
+
62
+ As suggested by jondot, the Sneakers maintainer, daemons used to run jobs with
63
+ Sneakers, and thusly TreadMill, should be done so using Upstart (or whatever
64
+ flavor other of daemon management subsystems your chosen OS uses). Sneakers
65
+ no longer supports the ability to daemonize.
66
+
67
+ The following a sample upstart config file to get you started:
68
+
69
+ ```
70
+ description 'Application Tread Mill Server'
71
+
72
+ env ENVIRONMENT_VAR='VALUE'
73
+
74
+ setuid deploy
75
+ setgid www-data
76
+
77
+ chdir /srv/www/application/current
78
+
79
+ start on [2345]
80
+ stop on [!2345]
81
+
82
+ exec /usr/local/bin/ruby /usr/local/bin/bundle exec rake tread_mill:run
83
+ ```
84
+
85
+ This file will go in `/etc/init` on Ubuntu systems. Should be named with the
86
+ service name followed by `.conf`: `application-treadmill.conf`.
87
+
88
+ Now to start/stop your service:
89
+
90
+ ```BASH
91
+ root@nix:/root# start application-treadmill
92
+ application-treadmill start/running, process 27996
93
+ ...
94
+ root@nix:/root# stop application-treadmill
95
+ application-treadmill stop/waiting
96
+ ```
97
+
98
+ More information on Upstart can be found [here](http://upstart.ubuntu.com/cookbook/#console).
99
+
100
+ **NOTE: Upstart `restart` is not the command you are looking for *waves 2
101
+ fingers from left to right in front of you*. You must stop/start between
102
+ configuration changes for the changes to take effect.**
103
+
104
+ ### Example workers:
105
+
106
+ Assuming you are using the ActiveJob::Base worker class:
107
+
108
+ ```Ruby
109
+ # app/workers/my_worker.rb
110
+
111
+ # Assuming: config.active_job.queue_name_delimiter = '.'
112
+
113
+ class Workers::MyWorker < ActiveJob::Base
114
+ queue_as :my_queue # queue used will be 'amqp.myapplication.my_queue'
115
+
116
+ def perform(user)
117
+ user.do_work
118
+ end
119
+
120
+ class << self
121
+ def work_for(user)
122
+ self.enqueue(user)
123
+ end
124
+ end
125
+ end
126
+ ```
127
+
128
+ Then you are set to use your workers wherever you want:
129
+
130
+ ```Ruby
131
+ # app/models/user.rb
132
+
133
+ class User
134
+ def work_later
135
+ Workers::MyWorker.work_for(self)
136
+ end
137
+ end
138
+ ```
139
+
140
+ ### Support Versions
141
+
142
+ #### Rails 4.2.0
143
+
144
+ Should be working now. If you see any issues, feel free to submit a Pull Request.
145
+
146
+ #### Rails 4.2.0.beta1
147
+
148
+ TreadMill should work out of the box with a valid Sneakers configuration. For ActionMailer::DeliverLater integration, all you need to do is include a `:mailer` queue, which should be prefixed by your selected `queue_name_prefix` (`config.tread_mill.queues = %(amqp.myapplication.mailers)`).
149
+
150
+ #### Rails <=4.1
151
+
152
+ Due to a pretty large set of API changes between ActiveJob's github repository pre-merge and now, it doesn't make sense to support pre-4.2 ActiveJob, especially considering the Rails team has flatly rejected supporting pre-4.2. As a result, this gem as of version `0.0.2`, only supports `>= 4.2.0.beta1`.
@@ -0,0 +1,28 @@
1
+ begin
2
+ require 'bundler/setup'
3
+ rescue LoadError
4
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
5
+ end
6
+
7
+ require 'rdoc/task'
8
+
9
+ RDoc::Task.new(:rdoc) do |rdoc|
10
+ rdoc.rdoc_dir = 'rdoc'
11
+ rdoc.title = 'TreadMill'
12
+ rdoc.options << '--line-numbers'
13
+ rdoc.rdoc_files.include('README.md')
14
+ rdoc.rdoc_files.include('lib/**/*.rb')
15
+ end
16
+
17
+ Bundler::GemHelper.install_tasks
18
+
19
+ require 'rake/testtask'
20
+
21
+ Rake::TestTask.new(:test) do |t|
22
+ t.libs << 'lib'
23
+ t.libs << 'test'
24
+ t.pattern = 'test/**/*_test.rb'
25
+ t.verbose = false
26
+ end
27
+
28
+ task default: :test
@@ -0,0 +1,8 @@
1
+ require 'tread_mill'
2
+
3
+ namespace :tread_mill do
4
+ desc 'Run ActiveJob workers against environment specified queues.'
5
+ task run: :environment do
6
+ TreadMill.run_queues(ENV['QUEUE'] || ENV['QUEUES'])
7
+ end
8
+ end
@@ -0,0 +1,68 @@
1
+ # encoding: utf-8
2
+
3
+ # Load sneakers...
4
+ require 'sneakers'
5
+ require 'sneakers/runner'
6
+
7
+ require 'tread_mill/fork_callbacks'
8
+ require 'tread_mill/queue_listener'
9
+
10
+ module TreadMill
11
+ include ActiveSupport::Configurable
12
+
13
+ config_accessor :queues, :workers
14
+
15
+ # Check to see if we're properly configured to send messages.
16
+ # Unfortunately, sneakers/bunny doesn't have a real method check because
17
+ # the connections are setup at request time. This is really just a best
18
+ # guess.
19
+ def self.configured?
20
+ Sneakers.configured? &&
21
+ !Sneakers::Config[:amqp]
22
+ .match(/^amqps?:\/\/([^:]+(:[^@]+)?@)?[^:]+(:[0-9]+)?\/?$/).nil?
23
+ end
24
+
25
+ # Process input queues to ensure QueueListener#for_queues gets the proper
26
+ # input.
27
+ def self.process_queues(queues)
28
+ case queues
29
+ when Array
30
+ queues.flatten
31
+ when String
32
+ queues.split(',')
33
+ else
34
+ fail ArgumentError, 'TreadMill#run_queues must be passed an Array of '\
35
+ 'queues or comma separated list of queues.'
36
+ end
37
+ end
38
+
39
+ mattr_accessor :runner
40
+
41
+ # Setup QueueListeners for each queue and run them in a Sneakers::Runner.
42
+ # Take the passed in queues first if provided, then use any application
43
+ # configured queues.
44
+ def self.run_queues(ques = nil, options = {})
45
+ ques = self.process_queues(ques) if ques
46
+ queue_listeners = QueueListener.for_queues(ques || queues)
47
+
48
+ sneakers_config = {
49
+ before_fork: ForkCallbacks.method(:before_fork),
50
+ after_fork: ForkCallbacks.method(:after_fork)
51
+ }
52
+
53
+ # Let these primarily reside in the sneakers config unless explicitly set.
54
+ sneakers_config[:workers] = workers if workers
55
+
56
+ Sneakers.configure(sneakers_config.merge(options))
57
+
58
+ self.runner = Sneakers::Runner.new(queue_listeners)
59
+ self.runner.run
60
+ end
61
+
62
+ # If a runner is running, stop it.
63
+ def self.stop_queues
64
+ self.runner.stop unless self.runner.nil?
65
+ end
66
+ end
67
+
68
+ require 'tread_mill/railtie' if defined?(Rails)
@@ -0,0 +1,20 @@
1
+ # encoding: utf-8
2
+
3
+ module TreadMill
4
+ # Encapsulate before and after fork collbacks.
5
+
6
+ module ForkCallbacks
7
+ def self.before_fork
8
+ # as there's no need for the master process to hold a connection
9
+ if defined?(ActiveRecord::Base)
10
+ ActiveRecord::Base.connection.disconnect!
11
+ end
12
+ end
13
+
14
+ def self.after_fork
15
+ if defined?(ActiveRecord::Base)
16
+ ActiveRecord::Base.establish_connection
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,23 @@
1
+ # encoding: utf-8
2
+
3
+ require 'active_job/queue_adapters/sneakers_adapter'
4
+
5
+ module TreadMill
6
+ # We want to subclass the JobWrapper to ensure the messages are deserialized
7
+ # properly.
8
+ class QueueListener < ActiveJob::QueueAdapters::SneakersAdapter::JobWrapper
9
+ include ActiveSupport::Rescuable
10
+
11
+ # Generate a worker for each queue specified.
12
+ def self.for_queues(*queues)
13
+ queues.flatten.map do |queue|
14
+ # Sneakers::Runner wants a worker class, not an instance.
15
+ # So, here we are creating anonymous classes and setting the queue
16
+ # accordingly.
17
+ Class.new(QueueListener) do
18
+ from_queue queue
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,19 @@
1
+ # encoding: utf-8
2
+
3
+ module TreadMill
4
+ class Railtie < Rails::Railtie
5
+ railtie_name :tread_mill
6
+
7
+ config.tread_mill = ActiveSupport::OrderedOptions.new
8
+
9
+ rake_tasks do
10
+ load "tasks/tread_mill_tasks.rake"
11
+ end
12
+
13
+ initializer "tread_mill.set_configs" do |app|
14
+ options = app.config.tread_mill
15
+ options.queues ||= []
16
+ options.each { |k,v| TreadMill.send("#{k}=", v.flatten) }
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,3 @@
1
+ module TreadMill
2
+ VERSION = '0.0.3'
3
+ end
@@ -0,0 +1,28 @@
1
+ == README
2
+
3
+ This README would normally document whatever steps are necessary to get the
4
+ application up and running.
5
+
6
+ Things you may want to cover:
7
+
8
+ * Ruby version
9
+
10
+ * System dependencies
11
+
12
+ * Configuration
13
+
14
+ * Database creation
15
+
16
+ * Database initialization
17
+
18
+ * How to run the test suite
19
+
20
+ * Services (job queues, cache servers, search engines, etc.)
21
+
22
+ * Deployment instructions
23
+
24
+ * ...
25
+
26
+
27
+ Please feel free to use a different markup language if you do not plan to run
28
+ <tt>rake doc:app</tt>.
@@ -0,0 +1,6 @@
1
+ # Add your own tasks in files placed in lib/tasks ending in .rake,
2
+ # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
3
+
4
+ require File.expand_path('../config/application', __FILE__)
5
+
6
+ Rails.application.load_tasks
@@ -0,0 +1,13 @@
1
+ // This is a manifest file that'll be compiled into application.js, which will include all the files
2
+ // listed below.
3
+ //
4
+ // Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
5
+ // or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path.
6
+ //
7
+ // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
8
+ // compiled file.
9
+ //
10
+ // Read Sprockets README (https://github.com/sstephenson/sprockets#sprockets-directives) for details
11
+ // about supported directives.
12
+ //
13
+ //= require_tree .
@@ -0,0 +1,15 @@
1
+ /*
2
+ * This is a manifest file that'll be compiled into application.css, which will include all the files
3
+ * listed below.
4
+ *
5
+ * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
6
+ * or vendor/assets/stylesheets of plugins, if any, can be referenced here using a relative path.
7
+ *
8
+ * You're free to add application-wide styles to this file and they'll appear at the bottom of the
9
+ * compiled file so the styles you add here take precedence over styles defined in any styles
10
+ * defined in the other CSS/SCSS files in this directory. It is generally better to create a new
11
+ * file per style scope.
12
+ *
13
+ *= require_tree .
14
+ *= require_self
15
+ */
@@ -0,0 +1,5 @@
1
+ class ApplicationController < ActionController::Base
2
+ # Prevent CSRF attacks by raising an exception.
3
+ # For APIs, you may want to use :null_session instead.
4
+ protect_from_forgery with: :exception
5
+ end
@@ -0,0 +1,2 @@
1
+ module ApplicationHelper
2
+ end