msgr 0.0.0 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (85) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +7 -1
  3. data/.travis.yml +5 -3
  4. data/Gemfile +27 -2
  5. data/Guardfile +14 -0
  6. data/README.md +56 -5
  7. data/Rakefile +30 -4
  8. data/lib/msgr/binding.rb +34 -7
  9. data/lib/msgr/client.rb +54 -24
  10. data/lib/msgr/connection.rb +64 -17
  11. data/lib/msgr/consumer.rb +28 -0
  12. data/lib/msgr/dispatcher.rb +12 -5
  13. data/lib/msgr/logging.rb +1 -1
  14. data/lib/msgr/message/acknowledge.rb +30 -0
  15. data/lib/msgr/message.rb +10 -3
  16. data/lib/msgr/pool.rb +31 -31
  17. data/lib/msgr/railtie.rb +51 -0
  18. data/lib/msgr/route.rb +19 -6
  19. data/lib/msgr/routes.rb +34 -2
  20. data/lib/msgr/version.rb +1 -1
  21. data/lib/msgr.rb +15 -7
  22. data/msgr.gemspec +2 -5
  23. data/scripts/simple_test.rb +18 -94
  24. data/spec/fixtures/msgr-routes-test-1.rb +2 -0
  25. data/spec/integration/dummy/README.rdoc +28 -0
  26. data/spec/integration/dummy/Rakefile +6 -0
  27. data/spec/integration/dummy/app/assets/images/.keep +0 -0
  28. data/spec/integration/dummy/app/assets/javascripts/application.js +13 -0
  29. data/spec/integration/dummy/app/assets/stylesheets/application.css +13 -0
  30. data/spec/integration/dummy/app/consumers/application_consumer.rb +3 -0
  31. data/spec/integration/dummy/app/consumers/test_consumer.rb +12 -0
  32. data/spec/integration/dummy/app/controllers/application_controller.rb +5 -0
  33. data/spec/integration/dummy/app/controllers/concerns/.keep +0 -0
  34. data/spec/integration/dummy/app/controllers/test_controller.rb +10 -0
  35. data/spec/integration/dummy/app/helpers/application_helper.rb +2 -0
  36. data/spec/integration/dummy/app/mailers/.keep +0 -0
  37. data/spec/integration/dummy/app/models/.keep +0 -0
  38. data/spec/integration/dummy/app/models/concerns/.keep +0 -0
  39. data/spec/integration/dummy/app/views/layouts/application.html.erb +14 -0
  40. data/spec/integration/dummy/bin/bundle +3 -0
  41. data/spec/integration/dummy/bin/rails +4 -0
  42. data/spec/integration/dummy/bin/rake +4 -0
  43. data/spec/integration/dummy/config/application.rb +24 -0
  44. data/spec/integration/dummy/config/boot.rb +5 -0
  45. data/spec/integration/dummy/config/database.yml +25 -0
  46. data/spec/integration/dummy/config/environment.rb +5 -0
  47. data/spec/integration/dummy/config/environments/development.rb +29 -0
  48. data/spec/integration/dummy/config/environments/production.rb +80 -0
  49. data/spec/integration/dummy/config/environments/test.rb +36 -0
  50. data/spec/integration/dummy/config/initializers/backtrace_silencers.rb +7 -0
  51. data/spec/integration/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  52. data/spec/integration/dummy/config/initializers/inflections.rb +16 -0
  53. data/spec/integration/dummy/config/initializers/mime_types.rb +5 -0
  54. data/spec/integration/dummy/config/initializers/secret_token.rb +12 -0
  55. data/spec/integration/dummy/config/initializers/session_store.rb +3 -0
  56. data/spec/integration/dummy/config/initializers/wrap_parameters.rb +14 -0
  57. data/spec/integration/dummy/config/locales/en.yml +23 -0
  58. data/spec/integration/dummy/config/msgr.rb +3 -0
  59. data/spec/integration/dummy/config/rabbitmq.yml +11 -0
  60. data/spec/integration/dummy/config/routes.rb +58 -0
  61. data/spec/integration/dummy/config.ru +4 -0
  62. data/spec/integration/dummy/db/test.sqlite3 +0 -0
  63. data/spec/integration/dummy/lib/assets/.keep +0 -0
  64. data/spec/integration/dummy/log/.keep +0 -0
  65. data/spec/integration/dummy/public/404.html +58 -0
  66. data/spec/integration/dummy/public/422.html +58 -0
  67. data/spec/integration/dummy/public/500.html +57 -0
  68. data/spec/integration/dummy/public/favicon.ico +0 -0
  69. data/spec/integration/msgr/railtie_spec.rb +12 -0
  70. data/spec/integration/msgr_spec.rb +12 -0
  71. data/spec/integration/spec_helper.rb +48 -0
  72. data/spec/msgr/msgr/client_spec.rb +50 -0
  73. data/spec/msgr/msgr/connection_spec.rb +51 -0
  74. data/spec/msgr/{consumer_spec.rb → msgr/consumer_spec.rb} +0 -0
  75. data/spec/msgr/msgr/pool_spec.rb +68 -0
  76. data/spec/msgr/{route_spec.rb → msgr/route_spec.rb} +0 -0
  77. data/spec/msgr/msgr/routes_spec.rb +113 -0
  78. data/spec/msgr/msgr_spec.rb +36 -0
  79. data/spec/{spec_helper.rb → msgr/spec_helper.rb} +15 -0
  80. data/spec/msgr/support/.keep +0 -0
  81. data/spec/support/setup.rb +27 -0
  82. metadata +126 -59
  83. data/spec/msgr/client_spec.rb +0 -5
  84. data/spec/msgr/routes_spec.rb +0 -59
  85. data/spec/msgr_spec.rb +0 -5
data/lib/msgr/pool.rb CHANGED
@@ -11,10 +11,11 @@ module Msgr
11
11
  @size = (opts[:size] || Celluloid.cores).to_i
12
12
  @running = false
13
13
 
14
+ raise ArgumentError.new 'Pool size must be greater zero.' if @size <= 0
15
+
14
16
  log(:debug) { "Inialize size => #{@size}" }
15
17
 
16
- start if opts[:autostart].nil? || opts[:autostart]
17
- every(30) { log_status } if opts[:nostats].nil? || opts[:nostats]
18
+ every([opts.fetch(:stats_interval, 30).to_i, 1].max) { log_status } if opts[:nostats].nil? || opts[:nostats]
18
19
  end
19
20
 
20
21
  def running?
@@ -37,9 +38,7 @@ module Msgr
37
38
  idle << Worker.new_link(Actor.current, index, @runner_klass, @runner_args)
38
39
  end
39
40
 
40
- log(:debug) { 'Startup done. Invoke worker polling.' }
41
-
42
- idle.each { |worker| async.poll worker }
41
+ log(:debug) { 'Pool ready.' }
43
42
  end
44
43
 
45
44
  def log_status
@@ -63,6 +62,7 @@ module Msgr
63
62
 
64
63
  log(:debug) { 'Graceful shutdown done.' }
65
64
  end
65
+ alias_method :shutdown, :stop
66
66
 
67
67
  # Check if a worker is available.
68
68
  #
@@ -78,9 +78,22 @@ module Msgr
78
78
 
79
79
  # Dispatch given message to a worker.
80
80
  #
81
- def dispatch(message, *args)
82
- messages.push [message, args]
83
- after(0) { signal :dispatch }
81
+ def dispatch(*args)
82
+ log(:debug) { 'Dispatch message to worker.' }
83
+
84
+ fetch_idle_worker.future :dispatch, args
85
+ end
86
+
87
+ # Return an idle worker.
88
+ #
89
+ def fetch_idle_worker
90
+ if (worker = idle.shift)
91
+ busy << worker
92
+ worker
93
+ else
94
+ wait :worker_done
95
+ fetch_idle_worker
96
+ end
84
97
  end
85
98
 
86
99
  # Called by worker to indicated it has finished processing.
@@ -92,7 +105,7 @@ module Msgr
92
105
 
93
106
  if running?
94
107
  idle << worker
95
- poll worker
108
+ after(0) { signal :worker_done }
96
109
  else
97
110
  log(:debug) { "Terminate worker. Still #{busy.size} to go..." }
98
111
 
@@ -104,24 +117,6 @@ module Msgr
104
117
  end
105
118
  end
106
119
 
107
- def poll(worker)
108
- return unless worker.alive?
109
-
110
- if running?
111
- if (message = exclusive { messages.shift })
112
- idle.delete worker
113
- busy << worker
114
-
115
- worker.dispatch message[0], message[1]
116
- else
117
- after(1) { poll worker }
118
- end
119
- else
120
- worker.terminate if worker.alive?
121
- after(0) { signal(:shutdown) } if @busy.empty?
122
- end
123
- end
124
-
125
120
  def to_s
126
121
  "#{self.class.name}[#{@runner_klass}]<#{object_id}>"
127
122
  end
@@ -146,15 +141,20 @@ module Msgr
146
141
  # Dispatch given method and argument to custom runner.
147
142
  # Arguments are used to call `#send` on runner instance.
148
143
  #
149
- def dispatch(method, args)
150
- log(:debug) { "Dispatch to runner: #{runner.class.name}##{method.to_s}" }
144
+ def dispatch(args)
145
+ log(:debug) { "Dispatch to runner: #{runner.class.name}" }
151
146
 
152
147
  # Send method to custom runner.
153
- runner.send method, *args
148
+ runner.send :call, *args
149
+
154
150
  rescue => error
155
151
  log(:error) { "Received error from runner: #{error.message}\n#{error.backtrace.join(" \n")}" }
156
152
  ensure
157
- pool.executed Actor.current
153
+ if pool.alive?
154
+ pool.executed Actor.current
155
+ else
156
+ terminate
157
+ end
158
158
  end
159
159
 
160
160
  def to_s
@@ -0,0 +1,51 @@
1
+ module Msgr
2
+
3
+ class Railtie < ::Rails::Railtie
4
+ config.msgr = ActiveSupport::OrderedOptions.new
5
+ config.autoload_paths << File.expand_path("#{Rails.root}/app/consumers") if File.exist?("#{Rails.root}/app/consumers")
6
+
7
+ initializer 'msgr.logger' do |app|
8
+ app.config.msgr.logger ||= Rails.logger
9
+ end
10
+
11
+ initializer 'msgr.rabbitmq_config' do
12
+ config.msgr.rabbitmq_config ||= Rails.root.join *%w(config rabbitmq.yml)
13
+ end
14
+
15
+ initializer 'msgr.routes_file' do
16
+ config.msgr.routes_file ||= Rails.root.join *%w(config msgr.rb)
17
+ end
18
+
19
+ # Start msgr
20
+ initializer 'msgr.start' do
21
+ config.after_initialize do |app|
22
+ Msgr.logger = app.config.msgr.logger
23
+ Celluloid.logger = app.config.msgr.logger
24
+
25
+ cfile = app.config.msgr.rabbitmq_config.to_s
26
+ config = YAML.load ERB.new(File.read(cfile)).result
27
+
28
+ raise ArgumentError, 'Could not load rabbitmq config.' unless config.is_a? Hash
29
+ raise ArgumentError, 'Could not load rabbitmq environment config ' unless config[Rails.env]
30
+
31
+ client = Msgr::Client.new config[Rails.env]
32
+ client.routes.files << app.config.msgr.routes_file
33
+ client.routes.reload
34
+
35
+ if Rails.env.development?
36
+ reloader = ActiveSupport::FileUpdateChecker.new client.routes.files do
37
+ client.routes.reload
38
+ client.reload
39
+ end
40
+
41
+ ActionDispatch::Reloader.to_prepare do
42
+ reloader.execute_if_updated
43
+ end
44
+ end
45
+
46
+ Msgr.client = client
47
+ client.start
48
+ end
49
+ end
50
+ end
51
+ end
data/lib/msgr/route.rb CHANGED
@@ -1,16 +1,14 @@
1
1
  module Msgr
2
2
 
3
3
  class Route
4
- attr_reader :consumer, :action, :opts, :key
5
- alias_method :routing_key, :key
4
+ attr_reader :consumer, :action, :opts
6
5
 
7
6
  def initialize(key, opts = {})
8
- @key = key.to_s
9
7
  @opts = opts
10
-
11
- raise ArgumentError.new 'Routing key required.' unless @key.present?
12
8
  raise ArgumentError.new 'Missing `to` options.' unless @opts[:to]
13
9
 
10
+ add key
11
+
14
12
  if (match = /\A(?<consumer>\w+)#(?<action>\w+)\z/.match(opts[:to].strip.to_s))
15
13
  @consumer = "#{match[:consumer].camelize}Consumer"
16
14
  @action = match[:action].underscore
@@ -19,8 +17,23 @@ module Msgr
19
17
  end
20
18
  end
21
19
 
20
+ def keys
21
+ @keys ||= []
22
+ end
23
+ alias_method :routing_keys, :keys
24
+
25
+ def add(key)
26
+ raise ArgumentError.new 'Routing key required.' unless key.present?
27
+
28
+ keys << key
29
+ end
30
+
31
+ def accept?(key, opts)
32
+ self.opts == opts
33
+ end
34
+
22
35
  def name
23
- "msgr.consumer-#{key}//#{consumer}##{action}"
36
+ "msgr.consumer.#{consumer}.#{action}"
24
37
  end
25
38
  end
26
39
  end
data/lib/msgr/routes.rb CHANGED
@@ -1,17 +1,49 @@
1
1
  module Msgr
2
2
 
3
3
  class Routes
4
+ attr_reader :routes
4
5
  delegate :each, to: :@routes
5
6
 
6
- def routes
7
- @routes ||= []
7
+ def initialize
8
+ @routes = []
8
9
  end
9
10
 
10
11
  def configure(&block)
11
12
  instance_eval &block
12
13
  end
13
14
 
15
+ def files
16
+ @files ||= []
17
+ end
18
+
19
+ def files=(files)
20
+ @files = Array files
21
+ end
22
+
23
+ def reload
24
+ routes.clear
25
+ files.each do |file|
26
+ if File.exists? file
27
+ load file
28
+ else
29
+ Msgr.logger.warn "Routes file `#{file}` does not exists (anymore)."
30
+ end
31
+ end
32
+ end
33
+
34
+ def load(file)
35
+ raise ArgumentError.new "File `#{file}` does not exists." unless File.exists? file
36
+ instance_eval File.read file
37
+ end
38
+
14
39
  def route(key, opts = {})
40
+ routes.each do |route|
41
+ if route.accept? key, opts
42
+ route.add key
43
+ return
44
+ end
45
+ end
46
+
15
47
  routes << Msgr::Route.new(key, opts)
16
48
  end
17
49
  end
data/lib/msgr/version.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  module Msgr
2
2
  module VERSION
3
3
  MAJOR = 0
4
- MINOR = 0
4
+ MINOR = 1
5
5
  PATCH = 0
6
6
  STAGE = nil
7
7
  STRING = [MAJOR, MINOR, PATCH, STAGE].reject(&:nil?).join('.')
data/lib/msgr.rb CHANGED
@@ -4,11 +4,15 @@ require 'active_support'
4
4
  require 'active_support/core_ext/object/blank'
5
5
  require 'active_support/core_ext/module/delegation'
6
6
  require 'active_support/core_ext/string/inflections'
7
+ require 'active_support/core_ext/hash/reverse_merge'
8
+ require 'active_support/core_ext/hash/keys'
9
+ require 'json'
7
10
 
8
11
  require 'msgr/logging'
9
12
  require 'msgr/binding'
10
13
  require 'msgr/client'
11
14
  require 'msgr/connection'
15
+ require 'msgr/consumer'
12
16
  require 'msgr/dispatcher'
13
17
  require 'msgr/errors'
14
18
  require 'msgr/message'
@@ -16,21 +20,25 @@ require 'msgr/pool'
16
20
  require 'msgr/route'
17
21
  require 'msgr/routes'
18
22
 
23
+ require 'msgr/railtie' if defined? Rails
24
+
19
25
  module Msgr
20
26
 
21
27
  class << self
28
+ attr_accessor :client
29
+ delegate :publish, to: :client
30
+
22
31
  def logger
23
- @logger ||= Logger.new($stdout).tap do |logger|
24
- logger.level = Logger::Severity::INFO
32
+ if @logger.nil?
33
+ @logger = Logger.new $stdout
34
+ @logger.level = Logger::Severity::INFO
25
35
  end
26
- end
27
36
 
28
- def start
29
- # stub
37
+ @logger
30
38
  end
31
39
 
32
- def publish
33
- # stub
40
+ def logger=(logger)
41
+ @logger = logger
34
42
  end
35
43
  end
36
44
  end
data/msgr.gemspec CHANGED
@@ -8,8 +8,8 @@ Gem::Specification.new do |spec|
8
8
  spec.version = Msgr::VERSION
9
9
  spec.authors = ['Jan Graichen']
10
10
  spec.email = ['jg@altimos.de']
11
- spec.description = %q{}
12
- spec.summary = %q{}
11
+ spec.description = %q{Msgr: Rails-like Messaging Framework}
12
+ spec.summary = %q{Msgr: Rails-like Messaging Framework}
13
13
  spec.homepage = 'https://github.com/jgraichen/msgr'
14
14
  spec.license = 'MIT'
15
15
 
@@ -23,7 +23,4 @@ Gem::Specification.new do |spec|
23
23
  spec.add_dependency 'celluloid'
24
24
 
25
25
  spec.add_development_dependency 'bundler', '~> 1.3'
26
- spec.add_development_dependency 'rake'
27
- spec.add_development_dependency 'rspec'
28
- spec.add_development_dependency 'coveralls'
29
26
  end
@@ -1,114 +1,38 @@
1
1
  require 'msgr'
2
2
 
3
- Msgr.logger.level = Logger::Severity::DEBUG
3
+ Msgr.logger.level = Logger::Severity::INFO
4
4
 
5
- @client = Msgr::Client.new uri: 'amqp://msgr:msgr@localhost'
5
+ class TestConsumer < Msgr::Consumer
6
+ def index
7
+ log(:info) { payload }
8
+ end
6
9
 
7
- @client.routes.configure do
8
- route 'abc.#', to: 'test#index'
9
- route 'cde.#', to: 'test#index'
10
- route '#', to: 'test#another_action'
11
- end
12
-
13
- @client.start
10
+ def another_action
11
+ log(:info) { payload }
12
+ end
14
13
 
15
- 10.times do |i|
16
- @client.publish 'abc.XXX', "Message #{i} #{rand}"
14
+ def log_name
15
+ "<TestConsumer##{action}>"
16
+ end
17
17
  end
18
18
 
19
- sleep 5
19
+ @client = Msgr::Client.new user: 'guest', password: 'guest', size: 1
20
20
 
21
21
  @client.routes.configure do
22
22
  route 'abc.#', to: 'test#index'
23
+ route 'cde.#', to: 'test#index'
24
+ route '#', to: 'test#another_action'
23
25
  end
24
26
 
25
- @client.reload
27
+ @client.start
26
28
 
27
- 10.times do |i|
29
+ 100.times do |i|
28
30
  @client.publish 'abc.XXX', "Message #{i} #{rand}"
29
31
  end
30
32
 
31
33
  begin
32
34
  sleep
33
35
  rescue Interrupt
34
- @client.stop
36
+ ensure
37
+ @client.stop timeout: 10
35
38
  end
36
-
37
- #class Dispatcher
38
- # include Msgr::Logging
39
- #
40
- # def call(message)
41
- # log(:info) { message }
42
- # sleep 5 * rand
43
- # log(:info) { 'Done' }
44
- # end
45
- #end
46
- #
47
- #pool = Msgr::Pool.new Dispatcher, size: 10
48
- #pool.start
49
- #
50
- #100.times do |i|
51
- # pool.dispatch(:call, "Message ##{i}")
52
- #end
53
- #
54
- #sleep 5
55
- #
56
- #pool.stop
57
- #pool.terminate
58
- #
59
- #Msgr.logger.info('[ROOT]') { 'Pool terminated.' }
60
-
61
- #require 'celluloid'
62
- #
63
- #class Worker
64
- # include Celluloid
65
- #
66
- # def do_work
67
- # sleep 15
68
- # end
69
- #end
70
- #
71
- #logger = Logger.new $stdout
72
- #
73
- #pool = Worker.pool
74
- #
75
- #logger.info 'Start work'
76
- #
77
- #4.times do |i|
78
- # pool.async.do_work
79
- #end
80
- #
81
- #logger.info 'Wait'
82
- #
83
- #sleep 5
84
- #
85
- #logger.info 'Terminate'
86
- #
87
- #pool.terminate
88
- #
89
- #logger.info 'Done.'
90
-
91
-
92
- #require 'bunny'
93
- #
94
- #bunny = Bunny.new 'amqp://msgr:msgr@localhost'
95
- #bunny.start
96
- #
97
- #channel = bunny.create_channel
98
- #exchange = channel.topic 'msgr.topic'
99
- #queue = channel.queue 'msgr.test.single-queue'
100
- #
101
- #queue.bind(exchange, routing_key: 'a.b.#')
102
- #queue.bind(exchange, routing_key: 'a.c.#')
103
- #queue.subscribe do |delivery_info, metadata, payload|
104
- # puts "#{delivery_info.routing_key} #{payload}"
105
- #end
106
- #
107
- #sleep 1
108
- #
109
- #10.times { |i| exchange.publish "Message ##{i}", routing_key: [ 'a.b.c', 'a.c.d', 'a.b', 'a' ].sample; sleep 0.2 }
110
- #
111
- #sleep 10
112
- #
113
- #channel.close
114
- #bunny.close
@@ -0,0 +1,2 @@
1
+ # Test routes
2
+ route 'abc.#', to: 'test#index'
@@ -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
+ Dummy::Application.load_tasks
File without changes
@@ -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,13 @@
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 top of the
9
+ * compiled file, but it's generally better to create a new file per style scope.
10
+ *
11
+ *= require_self
12
+ *= require_tree .
13
+ */
@@ -0,0 +1,3 @@
1
+ class ApplicationConsumer < Msgr::Consumer
2
+
3
+ end
@@ -0,0 +1,12 @@
1
+ class TestConsumer < ApplicationConsumer
2
+
3
+ def index
4
+ data = { fuubar: 'abc' }
5
+
6
+ publish data, to: 'local.test.another_action'
7
+ end
8
+
9
+ def another_action
10
+ puts "#{payload.inspect}"
11
+ end
12
+ end
@@ -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,10 @@
1
+ class TestController < ApplicationController
2
+
3
+ def index
4
+ @data = { abc: 'abc' }
5
+
6
+ Msgr.publish @data, to: 'local.test.index'
7
+
8
+ render nothing: true
9
+ end
10
+ end
@@ -0,0 +1,2 @@
1
+ module ApplicationHelper
2
+ end
File without changes
File without changes
File without changes
@@ -0,0 +1,14 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>Dummy</title>
5
+ <%= stylesheet_link_tag "application", media: "all", "data-turbolinks-track" => true %>
6
+ <%= javascript_include_tag "application", "data-turbolinks-track" => true %>
7
+ <%= csrf_meta_tags %>
8
+ </head>
9
+ <body>
10
+
11
+ <%= yield %>
12
+
13
+ </body>
14
+ </html>
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env ruby
2
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__)
3
+ load Gem.bin_path('bundler', 'bundle')
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+ APP_PATH = File.expand_path('../../config/application', __FILE__)
3
+ require_relative '../config/boot'
4
+ require 'rails/commands'
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+ require_relative '../config/boot'
3
+ require 'rake'
4
+ Rake.application.run
@@ -0,0 +1,24 @@
1
+ require File.expand_path('../boot', __FILE__)
2
+
3
+ require 'rails/all'
4
+
5
+ Bundler.require(*Rails.groups)
6
+
7
+ module Dummy
8
+ class Application < Rails::Application
9
+ # Settings in config/environments/* take precedence over those specified here.
10
+ # Application configuration should go into files in config/initializers
11
+ # -- all .rb files in that directory are automatically loaded.
12
+
13
+ # Set Time.zone default to the specified zone and make Active Record auto-convert to this zone.
14
+ # Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC.
15
+ # config.time_zone = 'Central Time (US & Canada)'
16
+
17
+ # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded.
18
+ # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s]
19
+ # config.i18n.default_locale = :de
20
+
21
+ config.msgr.logger = Logger.new $stdout
22
+ end
23
+ end
24
+
@@ -0,0 +1,5 @@
1
+ # Set up gems listed in the Gemfile.
2
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../../../Gemfile', __FILE__)
3
+
4
+ require 'bundler/setup' if File.exists?(ENV['BUNDLE_GEMFILE'])
5
+ $LOAD_PATH.unshift File.expand_path('../../../../lib', __FILE__)