msgr 0.0.0 → 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 (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__)