roundhouse-x 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.
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