totoro 1.0.5 → 1.0.6

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 (105) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +6 -0
  3. data/lib/generators/totoro/templates/totoro.yml +3 -2
  4. data/lib/totoro/config.rb +8 -0
  5. data/lib/totoro/services/broadcast_service.rb +5 -1
  6. data/lib/totoro/services/enqueue_service.rb +6 -2
  7. data/lib/totoro/version.rb +1 -1
  8. data/pkg/totoro-1.0.5.gem +0 -0
  9. data/pkg/totoro-1.0.5/CODE_OF_CONDUCT.md +74 -0
  10. data/pkg/totoro-1.0.5/Dockerfile +14 -0
  11. data/pkg/totoro-1.0.5/Gemfile +8 -0
  12. data/pkg/totoro-1.0.5/Gemfile.lock +68 -0
  13. data/pkg/totoro-1.0.5/LICENSE.txt +21 -0
  14. data/pkg/totoro-1.0.5/README.md +169 -0
  15. data/pkg/totoro-1.0.5/Rakefile +8 -0
  16. data/pkg/totoro-1.0.5/bin/console +15 -0
  17. data/pkg/totoro-1.0.5/bin/setup +8 -0
  18. data/pkg/totoro-1.0.5/bin/totoro +16 -0
  19. data/pkg/totoro-1.0.5/docker-compose.yml +43 -0
  20. data/pkg/totoro-1.0.5/lib/generators/totoro/config_generator.rb +12 -0
  21. data/pkg/totoro-1.0.5/lib/generators/totoro/init_generator.rb +14 -0
  22. data/pkg/totoro-1.0.5/lib/generators/totoro/templates/create_totoro_failed_messages.rb +12 -0
  23. data/pkg/totoro-1.0.5/lib/generators/totoro/templates/initializer.rb +1 -0
  24. data/pkg/totoro-1.0.5/lib/generators/totoro/templates/totoro.yml +33 -0
  25. data/pkg/totoro-1.0.5/lib/generators/totoro/templates/update_totoro_failed_messages.rb +6 -0
  26. data/pkg/totoro-1.0.5/lib/generators/totoro/templates/worker.rb.erb +10 -0
  27. data/pkg/totoro-1.0.5/lib/generators/totoro/update_generator.rb +12 -0
  28. data/pkg/totoro-1.0.5/lib/generators/totoro/worker_generator.rb +17 -0
  29. data/pkg/totoro-1.0.5/lib/totoro.rb +21 -0
  30. data/pkg/totoro-1.0.5/lib/totoro/base_queue.rb +44 -0
  31. data/pkg/totoro-1.0.5/lib/totoro/base_worker.rb +61 -0
  32. data/pkg/totoro-1.0.5/lib/totoro/config.rb +44 -0
  33. data/pkg/totoro-1.0.5/lib/totoro/errors/connection_break_error.rb +6 -0
  34. data/pkg/totoro-1.0.5/lib/totoro/errors/need_queue_name_error.rb +5 -0
  35. data/pkg/totoro-1.0.5/lib/totoro/initializer.rb +39 -0
  36. data/pkg/totoro-1.0.5/lib/totoro/message_resender.rb +17 -0
  37. data/pkg/totoro-1.0.5/lib/totoro/models/totoro_failed_message.rb +8 -0
  38. data/pkg/totoro-1.0.5/lib/totoro/railtie.rb +15 -0
  39. data/pkg/totoro-1.0.5/lib/totoro/services/broadcast_service.rb +33 -0
  40. data/pkg/totoro-1.0.5/lib/totoro/services/enqueue_service.rb +38 -0
  41. data/pkg/totoro-1.0.5/lib/totoro/services/resend_service.rb +19 -0
  42. data/pkg/totoro-1.0.5/lib/totoro/services/subscribe_service.rb +34 -0
  43. data/pkg/totoro-1.0.5/lib/totoro/tasks/resend_message.rake +8 -0
  44. data/pkg/totoro-1.0.5/lib/totoro/utils.rb +22 -0
  45. data/pkg/totoro-1.0.5/lib/totoro/version.rb +5 -0
  46. data/pkg/totoro-1.0.5/pkg/totoro-1.0.4.gem +0 -0
  47. data/pkg/totoro-1.0.5/spec/spec_helper.rb +14 -0
  48. data/pkg/totoro-1.0.5/spec/totoro_spec.rb +9 -0
  49. data/pkg/totoro-1.0.5/test/rabbitmq_commands.txt +6 -0
  50. data/pkg/totoro-1.0.5/test/totoro_test/Gemfile +43 -0
  51. data/pkg/totoro-1.0.5/test/totoro_test/Gemfile.lock +157 -0
  52. data/pkg/totoro-1.0.5/test/totoro_test/README.md +24 -0
  53. data/pkg/totoro-1.0.5/test/totoro_test/Rakefile +6 -0
  54. data/pkg/totoro-1.0.5/test/totoro_test/app/channels/application_cable/channel.rb +4 -0
  55. data/pkg/totoro-1.0.5/test/totoro_test/app/channels/application_cable/connection.rb +4 -0
  56. data/pkg/totoro-1.0.5/test/totoro_test/app/controllers/application_controller.rb +2 -0
  57. data/pkg/totoro-1.0.5/test/totoro_test/app/jobs/application_job.rb +2 -0
  58. data/pkg/totoro-1.0.5/test/totoro_test/app/mailers/application_mailer.rb +4 -0
  59. data/pkg/totoro-1.0.5/test/totoro_test/app/models/application_record.rb +3 -0
  60. data/pkg/totoro-1.0.5/test/totoro_test/app/models/worker/example_queue.rb +10 -0
  61. data/pkg/totoro-1.0.5/test/totoro_test/app/models/worker/exchange_queue.rb +10 -0
  62. data/pkg/totoro-1.0.5/test/totoro_test/app/models/worker/shu_queue.rb +10 -0
  63. data/pkg/totoro-1.0.5/test/totoro_test/app/services/bench_mark.txt +7 -0
  64. data/pkg/totoro-1.0.5/test/totoro_test/app/services/load_test.rb +19 -0
  65. data/pkg/totoro-1.0.5/test/totoro_test/app/views/layouts/mailer.html.erb +13 -0
  66. data/pkg/totoro-1.0.5/test/totoro_test/app/views/layouts/mailer.text.erb +1 -0
  67. data/pkg/totoro-1.0.5/test/totoro_test/bin/bundle +3 -0
  68. data/pkg/totoro-1.0.5/test/totoro_test/bin/delayed_job +5 -0
  69. data/pkg/totoro-1.0.5/test/totoro_test/bin/rails +9 -0
  70. data/pkg/totoro-1.0.5/test/totoro_test/bin/rake +9 -0
  71. data/pkg/totoro-1.0.5/test/totoro_test/bin/setup +34 -0
  72. data/pkg/totoro-1.0.5/test/totoro_test/bin/spring +17 -0
  73. data/pkg/totoro-1.0.5/test/totoro_test/bin/update +29 -0
  74. data/pkg/totoro-1.0.5/test/totoro_test/config.ru +5 -0
  75. data/pkg/totoro-1.0.5/test/totoro_test/config/application.rb +34 -0
  76. data/pkg/totoro-1.0.5/test/totoro_test/config/boot.rb +3 -0
  77. data/pkg/totoro-1.0.5/test/totoro_test/config/cable.yml +10 -0
  78. data/pkg/totoro-1.0.5/test/totoro_test/config/database.yml +55 -0
  79. data/pkg/totoro-1.0.5/test/totoro_test/config/environment.rb +5 -0
  80. data/pkg/totoro-1.0.5/test/totoro_test/config/environments/development.rb +47 -0
  81. data/pkg/totoro-1.0.5/test/totoro_test/config/environments/production.rb +82 -0
  82. data/pkg/totoro-1.0.5/test/totoro_test/config/environments/test.rb +41 -0
  83. data/pkg/totoro-1.0.5/test/totoro_test/config/initializers/application_controller_renderer.rb +8 -0
  84. data/pkg/totoro-1.0.5/test/totoro_test/config/initializers/backtrace_silencers.rb +7 -0
  85. data/pkg/totoro-1.0.5/test/totoro_test/config/initializers/cors.rb +16 -0
  86. data/pkg/totoro-1.0.5/test/totoro_test/config/initializers/filter_parameter_logging.rb +4 -0
  87. data/pkg/totoro-1.0.5/test/totoro_test/config/initializers/inflections.rb +16 -0
  88. data/pkg/totoro-1.0.5/test/totoro_test/config/initializers/mime_types.rb +4 -0
  89. data/pkg/totoro-1.0.5/test/totoro_test/config/initializers/totoro.rb +1 -0
  90. data/pkg/totoro-1.0.5/test/totoro_test/config/initializers/wrap_parameters.rb +14 -0
  91. data/pkg/totoro-1.0.5/test/totoro_test/config/locales/en.yml +33 -0
  92. data/pkg/totoro-1.0.5/test/totoro_test/config/puma.rb +56 -0
  93. data/pkg/totoro-1.0.5/test/totoro_test/config/routes.rb +3 -0
  94. data/pkg/totoro-1.0.5/test/totoro_test/config/secrets.yml +32 -0
  95. data/pkg/totoro-1.0.5/test/totoro_test/config/spring.rb +6 -0
  96. data/pkg/totoro-1.0.5/test/totoro_test/config/totoro.yml +42 -0
  97. data/pkg/totoro-1.0.5/test/totoro_test/db/migrate/20181019041208_create_delayed_jobs.rb +22 -0
  98. data/pkg/totoro-1.0.5/test/totoro_test/db/migrate/20181019070846_create_totoro_failed_messages.rb +11 -0
  99. data/pkg/totoro-1.0.5/test/totoro_test/db/migrate/20181228033422_update_totoro_failed_messages.rb +5 -0
  100. data/pkg/totoro-1.0.5/test/totoro_test/db/schema.rb +42 -0
  101. data/pkg/totoro-1.0.5/test/totoro_test/db/seeds.rb +7 -0
  102. data/pkg/totoro-1.0.5/test/totoro_test/public/robots.txt +1 -0
  103. data/pkg/totoro-1.0.5/test/totoro_test/test/test_helper.rb +10 -0
  104. data/pkg/totoro-1.0.5/totoro.gemspec +29 -0
  105. metadata +99 -2
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bundler/gem_tasks'
4
+ require 'rspec/core/rake_task'
5
+
6
+ RSpec::Core::RakeTask.new(:spec)
7
+
8
+ task default: :spec
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require 'bundler/setup'
5
+ require 'totoro'
6
+
7
+ # You can add fixtures and/or initialization code here to make experimenting
8
+ # with your gem easier. You can also use a different console, if you like.
9
+
10
+ # (If you use this, don't forget to add pry to your Gemfile!)
11
+ # require "pry"
12
+ # Pry.start
13
+
14
+ require 'irb'
15
+ IRB.start(__FILE__)
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require 'totoro'
5
+ # You might want to change this
6
+ ENV['RAILS_ENV'] ||= 'development'
7
+
8
+ root = Dir.pwd
9
+ root = File.dirname(root) until File.exist?(File.join(root, 'config'))
10
+ Dir.chdir(root)
11
+
12
+ require File.join(root, 'config', 'environment')
13
+
14
+ worker_class = ARGV[0]
15
+
16
+ ::Worker.const_get(worker_class.to_s.camelize).new.execute
@@ -0,0 +1,43 @@
1
+ version: '2.0'
2
+ services:
3
+ rabbitmq:
4
+ image: rabbitmq:3-management-alpine
5
+ environment:
6
+ RABBITMQ_DEFAULT_USER: app
7
+ RABBITMQ_DEFAULT_PASS: app
8
+ ports:
9
+ - '5672:5672'
10
+ - '15672:15672'
11
+
12
+ db:
13
+ image: postgres:9.6.6
14
+ restart: always
15
+ ports:
16
+ - '5432:5432'
17
+ volumes:
18
+ - 'postgres:/var/lib/postgresql/data'
19
+ environment:
20
+ POSTGRES_USER: root
21
+ POSTGRES_PASSWORD: root
22
+
23
+ totoro:
24
+ build: .
25
+ ports:
26
+ - '3000:3000'
27
+ volumes:
28
+ - ./test/totoro_test:/app
29
+ - .:/totoro
30
+ command: totoro example_queue
31
+ environment:
32
+ POSTGRES_HOST: db
33
+ POSTGRES_USER: root
34
+ POSTGRES_PASSWORD: root
35
+ RABBITMQ_HOST: rabbitmq
36
+ RABBITMQ_USERNAME: app
37
+ RABBITMQ_PASSWORD: app
38
+ depends_on:
39
+ - db
40
+ - rabbitmq
41
+
42
+ volumes:
43
+ postgres:
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Totoro
4
+ class ConfigGenerator < Rails::Generators::Base
5
+ source_root File.expand_path('templates', __dir__)
6
+ desc 'Generate totoro config file'
7
+
8
+ def copy_config_file
9
+ template 'totoro.yml', File.join('config', 'totoro.yml')
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Totoro
4
+ class InitGenerator < Rails::Generators::Base
5
+ source_root File.expand_path('templates', __dir__)
6
+ desc 'Generate totoro config file'
7
+
8
+ def copy_config_file
9
+ template 'create_totoro_failed_messages.rb', File.join('db/migrate', "#{Time.now.strftime('%Y%m%d%H%M%S')}_create_totoro_failed_messages.rb")
10
+ template 'totoro.yml', File.join('config', 'totoro.yml')
11
+ template 'initializer.rb', File.join('config/initializers', 'totoro.rb')
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,12 @@
1
+ class CreateTotoroFailedMessages < ActiveRecord::Migration[5.1]
2
+ def change
3
+ enable_extension "plpgsql"
4
+ create_table :totoro_failed_messages do |t|
5
+ t.string :class_name
6
+ t.string :queue_id
7
+ t.jsonb :payload
8
+ t.string :group
9
+ t.timestamps
10
+ end
11
+ end
12
+ end
@@ -0,0 +1 @@
1
+ Totoro::Initializer.new.execute
@@ -0,0 +1,33 @@
1
+ default: &default
2
+ connect:
3
+ host: rabbitmq
4
+ port: 5672
5
+ user: app
6
+ pass: app
7
+ queue:
8
+ example_queue:
9
+ name: real.queue.name
10
+ durable: true
11
+ clean_start: false
12
+ manual_ack: true
13
+ force_ack: true
14
+
15
+ custom:
16
+ connect:
17
+ host: rabbitmq
18
+ port: 5672
19
+ user: app
20
+ pass: app
21
+ queue:
22
+ custom_queue:
23
+ name: custom.queue.name
24
+ durable: true
25
+
26
+ development:
27
+ <<: *default
28
+
29
+ test:
30
+ <<: *default
31
+
32
+ production:
33
+ <<: *default
@@ -0,0 +1,6 @@
1
+ class UpdateTotoroFailedMessages < ActiveRecord::Migration[5.1]
2
+ def change
3
+ add_column :totoro_failed_messages, :group, :string
4
+ Totoro::TotoroFailedMessage.all.update(group: 'enqueue')
5
+ end
6
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Worker
4
+ class <%= name.camelcase %> < Totoro::BaseWorker
5
+ setup queue_name: '<%= queue || name.underscore %>'<% if prefix.present? %> ,prefix: :<%= prefix %><% end %>
6
+ def process(payload, metadata, delivery_info)
7
+ # worker process
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Totoro
4
+ class UpdateGenerator < Rails::Generators::Base
5
+ source_root File.expand_path('templates', __dir__)
6
+ desc 'Update totoro to 1.0.0'
7
+
8
+ def copy_config_file
9
+ template 'update_totoro_failed_messages.rb', File.join('db/migrate', "#{Time.now.strftime('%Y%m%d%H%M%S')}_update_totoro_failed_messages.rb")
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Totoro
4
+ class WorkerGenerator < Rails::Generators::Base
5
+ desc 'Generate totoro worker file'
6
+
7
+ source_root File.expand_path('templates', __dir__)
8
+ argument :name, type: :string
9
+ argument :queue, type: :string, required: false
10
+ argument :prefix, type: :string, required: false
11
+
12
+ def copy_config_file
13
+ template 'worker.rb.erb',
14
+ File.join('app/models/worker', "#{name.underscore}.rb")
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'totoro/version'
4
+ require 'totoro/config'
5
+ require 'totoro/base_queue'
6
+ require 'totoro/base_worker'
7
+ require 'totoro/utils'
8
+ require 'totoro/services/enqueue_service'
9
+ require 'totoro/services/broadcast_service'
10
+ require 'totoro/services/subscribe_service'
11
+ require 'totoro/services/resend_service'
12
+ require 'totoro/errors/connection_break_error'
13
+ require 'totoro/errors/need_queue_name_error'
14
+ require 'totoro/initializer'
15
+ require 'totoro/message_resender'
16
+ require 'totoro/models/totoro_failed_message'
17
+ require 'totoro/railtie' if defined?(Rails)
18
+
19
+ module Totoro
20
+ # Your code goes here...
21
+ end
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bunny'
4
+
5
+ module Totoro
6
+ class BaseQueue
7
+ class <<self
8
+ def config
9
+ @config ||= Totoro::Config.new
10
+ end
11
+
12
+ def connection
13
+ @connection ||= Bunny.new(config.connect.merge(threaded: false))
14
+ end
15
+
16
+ def broadcast(id, payload)
17
+ Totoro::BroadcastService.new(connection, config).broadcast(id, payload)
18
+ rescue Totoro::ConnectionBreakError => error
19
+ handle_failed_msg(id, payload, error, :broadcast)
20
+ end
21
+
22
+ def enqueue(id, payload)
23
+ Totoro::EnqueueService.new(connection, config).enqueue(id, payload)
24
+ rescue Totoro::ConnectionBreakError => error
25
+ handle_failed_msg(id, payload, error, :enqueue)
26
+ end
27
+
28
+ private
29
+
30
+ def handle_failed_msg(id, payload, error, group)
31
+ Rails.logger.error error.message
32
+ Rails.logger.info 'Add failed message to resend list'
33
+ STDOUT.flush
34
+ @connection = nil
35
+ Totoro::TotoroFailedMessage.create(
36
+ class_name: to_s,
37
+ queue_id: id,
38
+ group: group,
39
+ payload: payload
40
+ )
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,61 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Totoro
4
+ class BaseWorker
5
+ def self.setup(attrs)
6
+ prefix = attrs[:prefix]
7
+ queue_name = attrs[:queue_name]
8
+ define_method('setup') do
9
+ raise(Totoro::NeedQueueNameError) if queue_name.nil?
10
+
11
+ @prefix = prefix
12
+ @queue_name = queue_name
13
+ end
14
+ end
15
+
16
+ def initialize
17
+ setup
18
+ end
19
+
20
+ def execute
21
+ Rails.logger.info 'Listening to the Rabbitmq'
22
+ STDOUT.flush
23
+ subscribe_service.subscribe(@queue_name) do |delivery_info, metadata, payload|
24
+ Rails.logger.debug "#{@queue_name} received message"
25
+ STDOUT.flush
26
+ payload_hash = JSON.parse(payload).with_indifferent_access
27
+ process(payload_hash, metadata, delivery_info)
28
+ end
29
+
30
+ handle_usr1_n_usr2
31
+
32
+ subscribe_service.channel.work_pool.join
33
+ rescue SignalException
34
+ puts 'Terminating process ..'
35
+ subscribe_service.channel.work_pool.shutdown(true)
36
+ puts 'Stopped.'
37
+ end
38
+
39
+ def process; end
40
+
41
+ private
42
+
43
+ def handle_usr1_n_usr2
44
+ %w[USR1 USR2].each do |signal|
45
+ Signal.trap(signal) do
46
+ puts "#{signal} received."
47
+ handler = "on_#{signal.downcase}"
48
+ send handler if respond_to?(handler)
49
+ end
50
+ end
51
+ end
52
+
53
+ def config
54
+ @config ||= Totoro::Config.new(@prefix)
55
+ end
56
+
57
+ def subscribe_service
58
+ @subscribe_service ||= Totoro::SubscribeService.new(config)
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Totoro
4
+ class Config
5
+ def initialize(prefix = nil)
6
+ @data = Rails.application.config_for(:totoro).with_indifferent_access
7
+ @data = @data[prefix] if prefix.present?
8
+ end
9
+
10
+ def reset_data
11
+ @data = nil
12
+ end
13
+
14
+ def connect
15
+ @data[:connect]
16
+ end
17
+
18
+ def exchange(id)
19
+ @data[:exchange][id][:name]
20
+ end
21
+
22
+ def exchange_name_for_queue(queue_id)
23
+ @data[:queue][queue_id][:exchange]
24
+ end
25
+
26
+ def clean_start?(id)
27
+ !!@data[:queue][id][:clean_start]
28
+ end
29
+
30
+ def manual_ack?(id)
31
+ !!@data[:queue][id][:manual_ack]
32
+ end
33
+
34
+ def force_ack?(id)
35
+ manual_ack?(id) && !!@data[:queue][id][:force_ack]
36
+ end
37
+
38
+ def queue(id)
39
+ name = @data[:queue][id][:name]
40
+ settings = { durable: @data[:queue][id][:durable] }
41
+ [name, settings]
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Totoro
4
+ class ConnectionBreakError < StandardError
5
+ end
6
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Totoro
4
+ class NeedQueueNameError < RuntimeError; end
5
+ end
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Totoro
4
+ class Initializer
5
+ DEFAULT_CONFIG = %i[default connect queue].freeze
6
+ def execute
7
+ config = Rails.application.config_for(:totoro).with_indifferent_access
8
+ # set default queue class
9
+ Totoro.const_set('Queue', default_queue_class(config))
10
+ # set custom queue class
11
+ (config.symbolize_keys.keys - DEFAULT_CONFIG).each do |prefix|
12
+ prefix_module(prefix, queue_class(prefix))
13
+ end
14
+ end
15
+
16
+ private
17
+
18
+ def default_queue_class(config)
19
+ if config.key?(:default)
20
+ queue_class(:default)
21
+ else
22
+ Class.new(Totoro::BaseQueue)
23
+ end
24
+ end
25
+
26
+ def queue_class(prefix)
27
+ custom_queue_class = Class.new(Totoro::BaseQueue)
28
+ custom_queue_class.define_singleton_method('config') do
29
+ @config ||= Totoro::Config.new(prefix)
30
+ end
31
+ custom_queue_class
32
+ end
33
+
34
+ def prefix_module(prefix, custom_queue_class)
35
+ prefix_module = Totoro.const_set(prefix.to_s.camelize, Module.new)
36
+ prefix_module.const_set('Queue', custom_queue_class)
37
+ end
38
+ end
39
+ end