roundhouse-x 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (168) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +12 -0
  3. data/.travis.yml +16 -0
  4. data/3.0-Upgrade.md +70 -0
  5. data/Changes.md +1127 -0
  6. data/Gemfile +27 -0
  7. data/LICENSE +7 -0
  8. data/README.md +52 -0
  9. data/Rakefile +9 -0
  10. data/bin/roundhouse +19 -0
  11. data/bin/roundhousectl +93 -0
  12. data/lib/generators/roundhouse/templates/worker.rb.erb +9 -0
  13. data/lib/generators/roundhouse/templates/worker_spec.rb.erb +6 -0
  14. data/lib/generators/roundhouse/templates/worker_test.rb.erb +8 -0
  15. data/lib/generators/roundhouse/worker_generator.rb +49 -0
  16. data/lib/roundhouse/actor.rb +39 -0
  17. data/lib/roundhouse/api.rb +859 -0
  18. data/lib/roundhouse/cli.rb +396 -0
  19. data/lib/roundhouse/client.rb +210 -0
  20. data/lib/roundhouse/core_ext.rb +105 -0
  21. data/lib/roundhouse/exception_handler.rb +30 -0
  22. data/lib/roundhouse/fetch.rb +154 -0
  23. data/lib/roundhouse/launcher.rb +98 -0
  24. data/lib/roundhouse/logging.rb +104 -0
  25. data/lib/roundhouse/manager.rb +236 -0
  26. data/lib/roundhouse/middleware/chain.rb +149 -0
  27. data/lib/roundhouse/middleware/i18n.rb +41 -0
  28. data/lib/roundhouse/middleware/server/active_record.rb +13 -0
  29. data/lib/roundhouse/middleware/server/logging.rb +40 -0
  30. data/lib/roundhouse/middleware/server/retry_jobs.rb +206 -0
  31. data/lib/roundhouse/monitor.rb +124 -0
  32. data/lib/roundhouse/paginator.rb +42 -0
  33. data/lib/roundhouse/processor.rb +159 -0
  34. data/lib/roundhouse/rails.rb +24 -0
  35. data/lib/roundhouse/redis_connection.rb +77 -0
  36. data/lib/roundhouse/scheduled.rb +115 -0
  37. data/lib/roundhouse/testing/inline.rb +28 -0
  38. data/lib/roundhouse/testing.rb +193 -0
  39. data/lib/roundhouse/util.rb +68 -0
  40. data/lib/roundhouse/version.rb +3 -0
  41. data/lib/roundhouse/web.rb +264 -0
  42. data/lib/roundhouse/web_helpers.rb +249 -0
  43. data/lib/roundhouse/worker.rb +90 -0
  44. data/lib/roundhouse.rb +177 -0
  45. data/roundhouse.gemspec +27 -0
  46. data/test/config.yml +9 -0
  47. data/test/env_based_config.yml +11 -0
  48. data/test/fake_env.rb +0 -0
  49. data/test/fixtures/en.yml +2 -0
  50. data/test/helper.rb +49 -0
  51. data/test/test_api.rb +521 -0
  52. data/test/test_cli.rb +389 -0
  53. data/test/test_client.rb +294 -0
  54. data/test/test_exception_handler.rb +55 -0
  55. data/test/test_fetch.rb +206 -0
  56. data/test/test_logging.rb +34 -0
  57. data/test/test_manager.rb +169 -0
  58. data/test/test_middleware.rb +160 -0
  59. data/test/test_monitor.rb +258 -0
  60. data/test/test_processor.rb +176 -0
  61. data/test/test_rails.rb +23 -0
  62. data/test/test_redis_connection.rb +127 -0
  63. data/test/test_retry.rb +390 -0
  64. data/test/test_roundhouse.rb +87 -0
  65. data/test/test_scheduled.rb +120 -0
  66. data/test/test_scheduling.rb +75 -0
  67. data/test/test_testing.rb +78 -0
  68. data/test/test_testing_fake.rb +240 -0
  69. data/test/test_testing_inline.rb +65 -0
  70. data/test/test_util.rb +18 -0
  71. data/test/test_web.rb +605 -0
  72. data/test/test_web_helpers.rb +52 -0
  73. data/web/assets/images/bootstrap/glyphicons-halflings-white.png +0 -0
  74. data/web/assets/images/bootstrap/glyphicons-halflings.png +0 -0
  75. data/web/assets/images/logo.png +0 -0
  76. data/web/assets/images/status/active.png +0 -0
  77. data/web/assets/images/status/idle.png +0 -0
  78. data/web/assets/images/status-sd8051fd480.png +0 -0
  79. data/web/assets/javascripts/application.js +83 -0
  80. data/web/assets/javascripts/dashboard.js +300 -0
  81. data/web/assets/javascripts/locales/README.md +27 -0
  82. data/web/assets/javascripts/locales/jquery.timeago.ar.js +96 -0
  83. data/web/assets/javascripts/locales/jquery.timeago.bg.js +18 -0
  84. data/web/assets/javascripts/locales/jquery.timeago.bs.js +49 -0
  85. data/web/assets/javascripts/locales/jquery.timeago.ca.js +18 -0
  86. data/web/assets/javascripts/locales/jquery.timeago.cs.js +18 -0
  87. data/web/assets/javascripts/locales/jquery.timeago.cy.js +20 -0
  88. data/web/assets/javascripts/locales/jquery.timeago.da.js +18 -0
  89. data/web/assets/javascripts/locales/jquery.timeago.de.js +18 -0
  90. data/web/assets/javascripts/locales/jquery.timeago.el.js +18 -0
  91. data/web/assets/javascripts/locales/jquery.timeago.en-short.js +20 -0
  92. data/web/assets/javascripts/locales/jquery.timeago.en.js +20 -0
  93. data/web/assets/javascripts/locales/jquery.timeago.es.js +18 -0
  94. data/web/assets/javascripts/locales/jquery.timeago.et.js +18 -0
  95. data/web/assets/javascripts/locales/jquery.timeago.fa.js +22 -0
  96. data/web/assets/javascripts/locales/jquery.timeago.fi.js +28 -0
  97. data/web/assets/javascripts/locales/jquery.timeago.fr-short.js +16 -0
  98. data/web/assets/javascripts/locales/jquery.timeago.fr.js +17 -0
  99. data/web/assets/javascripts/locales/jquery.timeago.he.js +18 -0
  100. data/web/assets/javascripts/locales/jquery.timeago.hr.js +49 -0
  101. data/web/assets/javascripts/locales/jquery.timeago.hu.js +18 -0
  102. data/web/assets/javascripts/locales/jquery.timeago.hy.js +18 -0
  103. data/web/assets/javascripts/locales/jquery.timeago.id.js +18 -0
  104. data/web/assets/javascripts/locales/jquery.timeago.it.js +16 -0
  105. data/web/assets/javascripts/locales/jquery.timeago.ja.js +19 -0
  106. data/web/assets/javascripts/locales/jquery.timeago.ko.js +17 -0
  107. data/web/assets/javascripts/locales/jquery.timeago.lt.js +20 -0
  108. data/web/assets/javascripts/locales/jquery.timeago.mk.js +20 -0
  109. data/web/assets/javascripts/locales/jquery.timeago.nl.js +20 -0
  110. data/web/assets/javascripts/locales/jquery.timeago.no.js +18 -0
  111. data/web/assets/javascripts/locales/jquery.timeago.pl.js +31 -0
  112. data/web/assets/javascripts/locales/jquery.timeago.pt-br.js +16 -0
  113. data/web/assets/javascripts/locales/jquery.timeago.pt.js +16 -0
  114. data/web/assets/javascripts/locales/jquery.timeago.ro.js +18 -0
  115. data/web/assets/javascripts/locales/jquery.timeago.rs.js +49 -0
  116. data/web/assets/javascripts/locales/jquery.timeago.ru.js +34 -0
  117. data/web/assets/javascripts/locales/jquery.timeago.sk.js +18 -0
  118. data/web/assets/javascripts/locales/jquery.timeago.sl.js +44 -0
  119. data/web/assets/javascripts/locales/jquery.timeago.sv.js +18 -0
  120. data/web/assets/javascripts/locales/jquery.timeago.th.js +20 -0
  121. data/web/assets/javascripts/locales/jquery.timeago.tr.js +16 -0
  122. data/web/assets/javascripts/locales/jquery.timeago.uk.js +34 -0
  123. data/web/assets/javascripts/locales/jquery.timeago.uz.js +19 -0
  124. data/web/assets/javascripts/locales/jquery.timeago.zh-cn.js +20 -0
  125. data/web/assets/javascripts/locales/jquery.timeago.zh-tw.js +20 -0
  126. data/web/assets/stylesheets/application.css +746 -0
  127. data/web/assets/stylesheets/bootstrap.css +9 -0
  128. data/web/locales/cs.yml +68 -0
  129. data/web/locales/da.yml +68 -0
  130. data/web/locales/de.yml +69 -0
  131. data/web/locales/el.yml +68 -0
  132. data/web/locales/en.yml +77 -0
  133. data/web/locales/es.yml +69 -0
  134. data/web/locales/fr.yml +69 -0
  135. data/web/locales/hi.yml +75 -0
  136. data/web/locales/it.yml +69 -0
  137. data/web/locales/ja.yml +69 -0
  138. data/web/locales/ko.yml +68 -0
  139. data/web/locales/nl.yml +68 -0
  140. data/web/locales/no.yml +69 -0
  141. data/web/locales/pl.yml +59 -0
  142. data/web/locales/pt-br.yml +68 -0
  143. data/web/locales/pt.yml +67 -0
  144. data/web/locales/ru.yml +75 -0
  145. data/web/locales/sv.yml +68 -0
  146. data/web/locales/ta.yml +75 -0
  147. data/web/locales/zh-cn.yml +68 -0
  148. data/web/locales/zh-tw.yml +68 -0
  149. data/web/views/_footer.erb +22 -0
  150. data/web/views/_job_info.erb +84 -0
  151. data/web/views/_nav.erb +66 -0
  152. data/web/views/_paging.erb +23 -0
  153. data/web/views/_poll_js.erb +5 -0
  154. data/web/views/_poll_link.erb +7 -0
  155. data/web/views/_status.erb +4 -0
  156. data/web/views/_summary.erb +40 -0
  157. data/web/views/busy.erb +90 -0
  158. data/web/views/dashboard.erb +75 -0
  159. data/web/views/dead.erb +34 -0
  160. data/web/views/layout.erb +31 -0
  161. data/web/views/morgue.erb +71 -0
  162. data/web/views/queue.erb +45 -0
  163. data/web/views/queues.erb +27 -0
  164. data/web/views/retries.erb +74 -0
  165. data/web/views/retry.erb +34 -0
  166. data/web/views/scheduled.erb +54 -0
  167. data/web/views/scheduled_job_info.erb +8 -0
  168. metadata +404 -0
data/lib/roundhouse.rb ADDED
@@ -0,0 +1,177 @@
1
+ # encoding: utf-8
2
+ require 'roundhouse/version'
3
+ fail "Roundhouse #{Roundhouse::VERSION} does not support Ruby 1.9." if RUBY_PLATFORM != 'java' && RUBY_VERSION < '2.0.0'
4
+
5
+ require 'roundhouse/logging'
6
+ require 'roundhouse/client'
7
+ require 'roundhouse/worker'
8
+ require 'roundhouse/redis_connection'
9
+
10
+ require 'json'
11
+
12
+ module Roundhouse
13
+ NAME = 'Roundhouse'
14
+ LICENSE = 'See LICENSE and the LGPL-3.0 for licensing details.'
15
+
16
+ DEFAULTS = {
17
+ queues: [],
18
+ labels: [],
19
+ concurrency: 25,
20
+ require: '.',
21
+ environment: nil,
22
+ timeout: 8,
23
+ poll_interval_average: nil,
24
+ average_scheduled_poll_interval: 15,
25
+ error_handlers: [],
26
+ lifecycle_events: {
27
+ startup: [],
28
+ quiet: [],
29
+ shutdown: [],
30
+ },
31
+ dead_max_jobs: 10_000,
32
+ dead_timeout_in_seconds: 180 * 24 * 60 * 60 # 6 months
33
+ }
34
+
35
+ DEFAULT_WORKER_OPTIONS = {
36
+ 'retry' => true,
37
+ 'queue' => 'default'
38
+ }
39
+
40
+ def self.❨╯°□°❩╯︵┻━┻
41
+ puts "Calm down, yo."
42
+ end
43
+
44
+ def self.options
45
+ @options ||= DEFAULTS.dup
46
+ end
47
+
48
+ def self.options=(opts)
49
+ @options = opts
50
+ end
51
+
52
+ ##
53
+ # Configuration for Roundhouse server, use like:
54
+ #
55
+ # Roundhouse.configure_server do |config|
56
+ # config.redis = { :namespace => 'myapp', :size => 25, :url => 'redis://myhost:8877/0' }
57
+ # config.server_middleware do |chain|
58
+ # chain.add MyServerHook
59
+ # end
60
+ # end
61
+ def self.configure_server
62
+ yield self if server?
63
+ end
64
+
65
+ ##
66
+ # Configuration for Roundhouse client, use like:
67
+ #
68
+ # Roundhouse.configure_client do |config|
69
+ # config.redis = { :namespace => 'myapp', :size => 1, :url => 'redis://myhost:8877/0' }
70
+ # end
71
+ def self.configure_client
72
+ yield self unless server?
73
+ end
74
+
75
+ def self.server?
76
+ defined?(Roundhouse::CLI)
77
+ end
78
+
79
+ def self.redis(&block)
80
+ raise ArgumentError, "requires a block" unless block
81
+ redis_pool.with(&block)
82
+ end
83
+
84
+ def self.redis_pool
85
+ @redis ||= Roundhouse::RedisConnection.create
86
+ end
87
+
88
+ def self.redis=(hash)
89
+ @redis = if hash.is_a?(ConnectionPool)
90
+ hash
91
+ else
92
+ Roundhouse::RedisConnection.create(hash)
93
+ end
94
+ end
95
+
96
+ def self.client_middleware
97
+ @client_chain ||= Middleware::Chain.new
98
+ yield @client_chain if block_given?
99
+ @client_chain
100
+ end
101
+
102
+ def self.server_middleware
103
+ @server_chain ||= Processor.default_middleware
104
+ yield @server_chain if block_given?
105
+ @server_chain
106
+ end
107
+
108
+ def self.default_worker_options=(hash)
109
+ @default_worker_options = default_worker_options.merge(hash.stringify_keys)
110
+ end
111
+
112
+ def self.default_worker_options
113
+ defined?(@default_worker_options) ? @default_worker_options : DEFAULT_WORKER_OPTIONS
114
+ end
115
+
116
+ def self.load_json(string)
117
+ JSON.parse(string)
118
+ end
119
+
120
+ def self.dump_json(object)
121
+ JSON.generate(object)
122
+ end
123
+
124
+ def self.logger
125
+ Roundhouse::Logging.logger
126
+ end
127
+
128
+ def self.logger=(log)
129
+ Roundhouse::Logging.logger = log
130
+ end
131
+
132
+ # When set, overrides Roundhouse.options[:average_scheduled_poll_interval] and sets
133
+ # the average interval that this process will delay before checking for
134
+ # scheduled jobs or job retries that are ready to run.
135
+ #
136
+ # See roundhouse/scheduled.rb for an in-depth explanation of this value
137
+ def self.poll_interval=(interval)
138
+ $stderr.puts "DEPRECATION: `config.poll_interval = #{interval}` will be removed in Roundhouse 4. Please update to `config.average_scheduled_poll_interval = #{interval}`."
139
+ self.options[:poll_interval_average] = interval
140
+ end
141
+
142
+ # How frequently Redis should be checked by a random Roundhouse process for
143
+ # scheduled and retriable jobs. Each individual process will take turns by
144
+ # waiting some multiple of this value.
145
+ #
146
+ # See roundhouse/scheduled.rb for an in-depth explanation of this value
147
+ def self.average_scheduled_poll_interval=(interval)
148
+ self.options[:average_scheduled_poll_interval] = interval
149
+ end
150
+
151
+ # Register a proc to handle any error which occurs within the Roundhouse process.
152
+ #
153
+ # Roundhouse.configure_server do |config|
154
+ # config.error_handlers << proc {|ex,ctx_hash| MyErrorService.notify(ex, ctx_hash) }
155
+ # end
156
+ #
157
+ # The default error handler logs errors to Roundhouse.logger.
158
+ def self.error_handlers
159
+ self.options[:error_handlers]
160
+ end
161
+
162
+ # Register a block to run at a point in the Roundhouse lifecycle.
163
+ # :startup, :quiet or :shutdown are valid events.
164
+ #
165
+ # Roundhouse.configure_server do |config|
166
+ # config.on(:shutdown) do
167
+ # puts "Goodbye cruel world!"
168
+ # end
169
+ # end
170
+ def self.on(event, &block)
171
+ raise ArgumentError, "Symbols only please: #{event}" unless event.is_a?(Symbol)
172
+ raise ArgumentError, "Invalid event name: #{event}" unless options[:lifecycle_events].key?(event)
173
+ options[:lifecycle_events][event] << block
174
+ end
175
+ end
176
+
177
+ require 'roundhouse/rails' if defined?(::Rails::Engine)
@@ -0,0 +1,27 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/roundhouse/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.authors = ["Ho-Sheng Hsiao", "Mike Perham"]
6
+ gem.email = ["hosh@shopapps.co", "mperham@gmail.com"]
7
+ gem.summary = "Round-robin load-balanced background processing for Ruby"
8
+ gem.description = "Round-robin load-balanced background processing for Ruby."
9
+ gem.homepage = "http://roundhouse.shopapps.io"
10
+ gem.license = "LGPL-3.0"
11
+
12
+ gem.executables = ['roundhouse', 'roundhousectl']
13
+ gem.files = `git ls-files | grep -Ev '^(myapp|examples)'`.split("\n")
14
+ gem.test_files = `git ls-files -- test/*`.split("\n")
15
+ gem.name = "roundhouse-x"
16
+ gem.require_paths = ["lib"]
17
+ gem.version = Roundhouse::VERSION
18
+ gem.add_dependency 'redis', '~> 3.2', '>= 3.2.1'
19
+ gem.add_dependency 'redis-namespace', '~> 1.5', '>= 1.5.2'
20
+ gem.add_dependency 'connection_pool', '~> 2.2', '>= 2.2.0'
21
+ gem.add_dependency 'celluloid', '~> 0.17.0'
22
+ gem.add_dependency 'json', '~> 1.0'
23
+ gem.add_development_dependency 'sinatra', '~> 1.4', '>= 1.4.6'
24
+ gem.add_development_dependency 'minitest', '~> 5.7', '>= 5.7.0'
25
+ gem.add_development_dependency 'rake', '~> 10.0'
26
+ gem.add_development_dependency 'rails', '~> 4', '>= 3.2.0'
27
+ end
data/test/config.yml ADDED
@@ -0,0 +1,9 @@
1
+ ---
2
+ :verbose: false
3
+ :require: ./test/fake_env.rb
4
+ :pidfile: /tmp/roundhouse-config-test.pid
5
+ :logfile: /tmp/roundhouse.log
6
+ :concurrency: 50
7
+ :queues:
8
+ - [<%="very_"%>often, 2]
9
+ - [seldom, 1]
@@ -0,0 +1,11 @@
1
+ ---
2
+ :pidfile: /tmp/roundhouse-config-test.pid
3
+ :concurrency: 50
4
+ staging:
5
+ :verbose: false
6
+ :require: ./test/fake_env.rb
7
+ :logfile: /tmp/roundhouse.log
8
+ :concurrency: 5
9
+ :queues:
10
+ - [<%="very_"%>often, 2]
11
+ - [seldom, 1]
data/test/fake_env.rb ADDED
File without changes
@@ -0,0 +1,2 @@
1
+ en:
2
+ translated_text: 'Changed text from add locals'
data/test/helper.rb ADDED
@@ -0,0 +1,49 @@
1
+ $CELLULOID_DEBUG = false
2
+ $TESTING = true
3
+ if ENV["COVERAGE"]
4
+ require 'simplecov'
5
+ SimpleCov.start do
6
+ add_filter "/test/"
7
+ add_filter "/myapp/"
8
+ end
9
+ end
10
+ ENV['RACK_ENV'] = ENV['RAILS_ENV'] = 'test'
11
+
12
+ begin
13
+ require 'pry-byebug'
14
+ rescue LoadError
15
+ end
16
+
17
+ require 'minitest/autorun'
18
+ require 'minitest/pride'
19
+
20
+ require 'celluloid/current'
21
+ require 'celluloid/test'
22
+ Celluloid.boot
23
+ require 'roundhouse'
24
+ require 'roundhouse/util'
25
+ Roundhouse.logger.level = Logger::ERROR
26
+
27
+ Roundhouse::Test = Minitest::Test
28
+
29
+ require 'roundhouse/redis_connection'
30
+ REDIS_URL = ENV['REDIS_URL'] || 'redis://localhost/15'
31
+ REDIS = Roundhouse::RedisConnection.create(:url => REDIS_URL, :namespace => 'testy')
32
+
33
+ Roundhouse.configure_client do |config|
34
+ config.redis = { :url => REDIS_URL, :namespace => 'testy' }
35
+ end
36
+
37
+ def capture_logging(lvl=Logger::INFO)
38
+ old = Roundhouse.logger
39
+ begin
40
+ out = StringIO.new
41
+ logger = Logger.new(out)
42
+ logger.level = lvl
43
+ Roundhouse.logger = logger
44
+ yield
45
+ out.string
46
+ ensure
47
+ Roundhouse.logger = old
48
+ end
49
+ end