wamp-worker 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 (129) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +13 -0
  3. data/.rspec +2 -0
  4. data/.ruby-version +1 -0
  5. data/.travis.yml +5 -0
  6. data/Gemfile +4 -0
  7. data/LICENSE.txt +21 -0
  8. data/README.md +204 -0
  9. data/Rakefile +6 -0
  10. data/bin/console +14 -0
  11. data/bin/setup +8 -0
  12. data/bin/wamp-worker +46 -0
  13. data/lib/wamp/worker.rb +132 -0
  14. data/lib/wamp/worker/config.rb +184 -0
  15. data/lib/wamp/worker/handler.rb +196 -0
  16. data/lib/wamp/worker/proxy/backgrounder.rb +38 -0
  17. data/lib/wamp/worker/proxy/base.rb +101 -0
  18. data/lib/wamp/worker/proxy/dispatcher.rb +115 -0
  19. data/lib/wamp/worker/proxy/requestor.rb +91 -0
  20. data/lib/wamp/worker/queue.rb +135 -0
  21. data/lib/wamp/worker/rails.rb +28 -0
  22. data/lib/wamp/worker/runner.rb +240 -0
  23. data/lib/wamp/worker/ticker.rb +30 -0
  24. data/lib/wamp/worker/version.rb +5 -0
  25. data/spec/spec_helper.rb +29 -0
  26. data/spec/support/client_stub.rb +47 -0
  27. data/spec/support/handler_stub.rb +105 -0
  28. data/spec/support/redis_stub.rb +89 -0
  29. data/spec/support/session_stub.rb +101 -0
  30. data/spec/wamp/worker/config_spec.rb +90 -0
  31. data/spec/wamp/worker/handler_spec.rb +162 -0
  32. data/spec/wamp/worker/proxy_spec.rb +153 -0
  33. data/spec/wamp/worker/queue_spec.rb +49 -0
  34. data/spec/wamp/worker/runner_spec.rb +108 -0
  35. data/spec/wamp/worker_spec.rb +8 -0
  36. data/test/app_test.rb +124 -0
  37. data/test/hello.py +50 -0
  38. data/test/sidekiq.yml +5 -0
  39. data/test/wamp_test/.generators +8 -0
  40. data/test/wamp_test/.ruby-version +1 -0
  41. data/test/wamp_test/Gemfile +65 -0
  42. data/test/wamp_test/Gemfile.lock +246 -0
  43. data/test/wamp_test/README.md +24 -0
  44. data/test/wamp_test/Rakefile +6 -0
  45. data/test/wamp_test/app/assets/config/manifest.js +3 -0
  46. data/test/wamp_test/app/assets/images/.keep +0 -0
  47. data/test/wamp_test/app/assets/javascripts/application.js +16 -0
  48. data/test/wamp_test/app/assets/javascripts/cable.js +13 -0
  49. data/test/wamp_test/app/assets/javascripts/channels/.keep +0 -0
  50. data/test/wamp_test/app/assets/stylesheets/application.css +15 -0
  51. data/test/wamp_test/app/channels/application_cable/channel.rb +4 -0
  52. data/test/wamp_test/app/channels/application_cable/connection.rb +4 -0
  53. data/test/wamp_test/app/controllers/add_controller.rb +11 -0
  54. data/test/wamp_test/app/controllers/application_controller.rb +3 -0
  55. data/test/wamp_test/app/controllers/concerns/.keep +0 -0
  56. data/test/wamp_test/app/controllers/ping_controller.rb +7 -0
  57. data/test/wamp_test/app/handlers/add_handler.rb +9 -0
  58. data/test/wamp_test/app/handlers/back_add_handler.rb +26 -0
  59. data/test/wamp_test/app/handlers/back_ping_handler.rb +10 -0
  60. data/test/wamp_test/app/handlers/ping_handler.rb +10 -0
  61. data/test/wamp_test/app/helpers/application_helper.rb +2 -0
  62. data/test/wamp_test/app/jobs/application_job.rb +2 -0
  63. data/test/wamp_test/app/mailers/application_mailer.rb +4 -0
  64. data/test/wamp_test/app/models/application_record.rb +3 -0
  65. data/test/wamp_test/app/models/concerns/.keep +0 -0
  66. data/test/wamp_test/app/views/layouts/application.html.erb +15 -0
  67. data/test/wamp_test/app/views/layouts/mailer.html.erb +13 -0
  68. data/test/wamp_test/app/views/layouts/mailer.text.erb +1 -0
  69. data/test/wamp_test/bin/bundle +3 -0
  70. data/test/wamp_test/bin/rails +9 -0
  71. data/test/wamp_test/bin/rake +9 -0
  72. data/test/wamp_test/bin/setup +36 -0
  73. data/test/wamp_test/bin/spring +17 -0
  74. data/test/wamp_test/bin/update +31 -0
  75. data/test/wamp_test/bin/yarn +11 -0
  76. data/test/wamp_test/config.ru +5 -0
  77. data/test/wamp_test/config/application.rb +19 -0
  78. data/test/wamp_test/config/boot.rb +4 -0
  79. data/test/wamp_test/config/cable.yml +10 -0
  80. data/test/wamp_test/config/credentials.yml.enc +1 -0
  81. data/test/wamp_test/config/database.yml +25 -0
  82. data/test/wamp_test/config/environment.rb +5 -0
  83. data/test/wamp_test/config/environments/development.rb +61 -0
  84. data/test/wamp_test/config/environments/production.rb +94 -0
  85. data/test/wamp_test/config/environments/test.rb +46 -0
  86. data/test/wamp_test/config/initializers/application_controller_renderer.rb +8 -0
  87. data/test/wamp_test/config/initializers/assets.rb +14 -0
  88. data/test/wamp_test/config/initializers/backtrace_silencers.rb +7 -0
  89. data/test/wamp_test/config/initializers/content_security_policy.rb +25 -0
  90. data/test/wamp_test/config/initializers/cookies_serializer.rb +5 -0
  91. data/test/wamp_test/config/initializers/filter_parameter_logging.rb +4 -0
  92. data/test/wamp_test/config/initializers/inflections.rb +16 -0
  93. data/test/wamp_test/config/initializers/mime_types.rb +4 -0
  94. data/test/wamp_test/config/initializers/wamp-worker.rb +8 -0
  95. data/test/wamp_test/config/initializers/wrap_parameters.rb +14 -0
  96. data/test/wamp_test/config/locales/en.yml +33 -0
  97. data/test/wamp_test/config/master.key +1 -0
  98. data/test/wamp_test/config/puma.rb +34 -0
  99. data/test/wamp_test/config/routes.rb +4 -0
  100. data/test/wamp_test/config/sidekiq.yml +6 -0
  101. data/test/wamp_test/config/spring.rb +6 -0
  102. data/test/wamp_test/config/storage.yml +34 -0
  103. data/test/wamp_test/db/development.sqlite3 +0 -0
  104. data/test/wamp_test/db/seeds.rb +7 -0
  105. data/test/wamp_test/lib/assets/.keep +0 -0
  106. data/test/wamp_test/lib/tasks/.keep +0 -0
  107. data/test/wamp_test/package.json +5 -0
  108. data/test/wamp_test/public/404.html +67 -0
  109. data/test/wamp_test/public/422.html +67 -0
  110. data/test/wamp_test/public/500.html +66 -0
  111. data/test/wamp_test/public/apple-touch-icon-precomposed.png +0 -0
  112. data/test/wamp_test/public/apple-touch-icon.png +0 -0
  113. data/test/wamp_test/public/favicon.ico +0 -0
  114. data/test/wamp_test/public/robots.txt +1 -0
  115. data/test/wamp_test/storage/.keep +0 -0
  116. data/test/wamp_test/test/application_system_test_case.rb +5 -0
  117. data/test/wamp_test/test/controllers/.keep +0 -0
  118. data/test/wamp_test/test/fixtures/.keep +0 -0
  119. data/test/wamp_test/test/fixtures/files/.keep +0 -0
  120. data/test/wamp_test/test/helpers/.keep +0 -0
  121. data/test/wamp_test/test/integration/.keep +0 -0
  122. data/test/wamp_test/test/mailers/.keep +0 -0
  123. data/test/wamp_test/test/models/.keep +0 -0
  124. data/test/wamp_test/test/system/.keep +0 -0
  125. data/test/wamp_test/test/test_helper.rb +10 -0
  126. data/test/wamp_test/vendor/.keep +0 -0
  127. data/test/web/index.html +101 -0
  128. data/wamp-worker.gemspec +32 -0
  129. metadata +395 -0
@@ -0,0 +1,115 @@
1
+ require_relative "base"
2
+
3
+ module Wamp
4
+ module Worker
5
+ module Proxy
6
+
7
+ class Dispatcher < Base
8
+ attr_accessor :session
9
+
10
+ # We want to timeout every few seconds so higher level code can
11
+ # look for a shutdown
12
+ TIMEOUT = 2
13
+
14
+ # Constructor
15
+ #
16
+ def initialize(name, session=nil, uuid: nil)
17
+ super name, uuid: uuid
18
+ self.session = session
19
+ end
20
+
21
+ # Increments the ticker
22
+ #
23
+ def increment_ticker
24
+ self.ticker.increment
25
+ end
26
+
27
+ # Check the queues
28
+ #
29
+ def check_queues
30
+ check_queue [self.command_req_queue, self.background_res_queue]
31
+ end
32
+
33
+ # Executes the request
34
+ #
35
+ # @param request [Descriptor] - The request
36
+ def process(descriptor)
37
+ return unless descriptor != nil
38
+
39
+ raise(RuntimeError, "must have a session to process a descriptor") unless self.session != nil
40
+
41
+ # Create the callback
42
+ callback = -> result, error, details {
43
+ # Need to remove the session from the details response
44
+ details&.delete(:session)
45
+
46
+ # Create the params
47
+ params = { result: result, error: error, details: details }
48
+
49
+ # Push the response back
50
+ self.queue.push descriptor.handle, descriptor.command, params
51
+ }
52
+
53
+ # Call the session
54
+ if descriptor.command == :call
55
+
56
+ # invoke the call method
57
+ procedure = descriptor.params[:procedure]
58
+ args = descriptor.params[:args]
59
+ kwargs = descriptor.params[:kwargs]
60
+ options = descriptor.params[:options]
61
+
62
+ self.session.call(procedure, args, kwargs, options, &callback)
63
+
64
+ elsif descriptor.command == :publish
65
+
66
+ # invoke the publish method
67
+ topic = descriptor.params[:topic]
68
+ args = descriptor.params[:args]
69
+ kwargs = descriptor.params[:kwargs]
70
+ options = descriptor.params[:options]
71
+
72
+ self.session.publish(topic, args, kwargs, options, &callback)
73
+
74
+ elsif descriptor.command == :yield
75
+
76
+ # invoke the yield method
77
+ request = descriptor.params[:request]
78
+ options = descriptor.params[:options]
79
+ check_defer = descriptor.params[:check_defer]
80
+ result_hash = descriptor.params[:result] || {}
81
+
82
+ # Get the response from the descriptor params
83
+ result = Wamp::Client::Response.from_hash(result_hash)
84
+
85
+ self.session.yield(request, result, options, check_defer)
86
+
87
+ else
88
+
89
+ # Return error if the command is not supported
90
+ error = Wamp::Client::Response::CallError.new(
91
+ Wamp::Client::Response::DEFAULT_ERROR,
92
+ ["unsupported proxy command '#{descriptor.command}'"])
93
+ callback.call(nil, error.to_hash, {})
94
+
95
+ end
96
+
97
+ end
98
+
99
+ private
100
+
101
+ # This methods blocks waiting for a value to appear in the queue
102
+ #
103
+ # @param queue_name [String] - the name of the queue
104
+ def check_queue(queue_name)
105
+
106
+ # Wait for a value to appear in the queue. We have a timeout so
107
+ # the thread can check if the worker has been killed
108
+ self.queue.pop(queue_name, wait: true, timeout: TIMEOUT)
109
+ end
110
+
111
+ end
112
+ end
113
+ end
114
+ end
115
+
@@ -0,0 +1,91 @@
1
+ require_relative "base"
2
+
3
+ module Wamp
4
+ module Worker
5
+ module Proxy
6
+
7
+ class Requestor < Base
8
+
9
+ # Performs the session "call" method
10
+ #
11
+ # @param procedure [String] - The procedure to call
12
+ # @param args [Array] - Array of arguments
13
+ # @param kwargs [Hash] - Hash of key/word arguments
14
+ # @param options [Hash] - Options for the call
15
+ def call(procedure, args=nil, kwargs=nil, options={}, &callback)
16
+
17
+ # Create the params
18
+ params = { procedure: procedure, args: args, kwargs: kwargs, options: options }
19
+
20
+ # Execute the command
21
+ request_response :call, params, true, &callback
22
+ end
23
+
24
+ # Performs the session "publish" method
25
+ #
26
+ # @param topic [String] - The topic to publish
27
+ # @param args [Array] - Array of arguments
28
+ # @param kwargs [Hash] - Hash of key/word arguments
29
+ # @param options [Hash] - Options for the subscribe
30
+ def publish(topic, args=nil, kwargs=nil, options={}, &callback)
31
+
32
+ # Create the params
33
+ params = { topic: topic , args: args, kwargs: kwargs, options: options }
34
+
35
+ # Execute the command
36
+ request_response :publish, params, options[:acknowledge], &callback
37
+ end
38
+
39
+ private
40
+
41
+ # Method to push the request and wait for the response
42
+ #
43
+ # @param command [Symbol] - The command
44
+ # @param params [Hash] - The parameters
45
+ # @param wait [Bool] - if true, will wait for the response
46
+ def request_response(command, params, wait=true)
47
+
48
+ # Create a response handle
49
+ handle = self.unique_command_resp_queue
50
+
51
+ # Push the request
52
+ self.queue.push self.command_req_queue, command, params, handle
53
+
54
+ # If wait, check the queue and respond
55
+ if wait
56
+
57
+ # Store the start ticker
58
+ start_tick = self.ticker.get
59
+
60
+ # Wait for the response
61
+ descriptor = self.queue.pop(handle, wait: true, delete: true)
62
+
63
+ # check for nil descriptor
64
+ if descriptor == nil
65
+
66
+ # If the ticker never incremented, throw a "worker not responding" error
67
+ current_tick = self.ticker.get
68
+ if start_tick == current_tick
69
+ raise(RuntimeError, "worker '#{self.name}' is not responding")
70
+ else
71
+ raise(RuntimeError, "request to #{handle} timed out")
72
+ end
73
+
74
+ else
75
+
76
+ # If a block was given, respond
77
+ if block_given?
78
+ response = [descriptor.params[:result], descriptor.params[:error], descriptor.params[:details]]
79
+ yield(*response)
80
+ end
81
+
82
+ end
83
+
84
+ end
85
+ end
86
+
87
+
88
+ end
89
+ end
90
+ end
91
+ end
@@ -0,0 +1,135 @@
1
+ require "json"
2
+
3
+ module Wamp
4
+ module Worker
5
+
6
+ class Queue
7
+ attr_reader :redis, :default_timeout
8
+
9
+ # This class represents the payload that will be stored in Redis
10
+ class Descriptor
11
+ attr_reader :command, :handle, :params
12
+
13
+ # Constructor
14
+ #
15
+ # @param command [Symbol] - The command for the descriptor
16
+ # @param handle [String] - The handle representing the descriptor
17
+ # @param params [Hash] - The params for the command
18
+ def initialize(command, handle, params)
19
+ @command = command.to_sym
20
+ @handle = handle
21
+ @params = params || {}
22
+ end
23
+
24
+ # Create a Descriptor object from the json payload
25
+ #
26
+ # @param json_string [String] - The string from the Redis store
27
+ # @return [Descriptor] - The instantiated descriptor
28
+ def self.from_json(json_string)
29
+ return unless json_string
30
+ parsed = JSON.parse(json_string, :symbolize_names => true)
31
+ self.new(parsed[:command], parsed[:handle], parsed[:params])
32
+ end
33
+
34
+ # Creates the json payload from the object
35
+ #
36
+ # @return [String] - The string that will go into the Redis store
37
+ def to_json
38
+ { command: self.command, handle: self.handle, params: self.params }.to_json
39
+ end
40
+ end
41
+
42
+ # Constructor
43
+ #
44
+ def initialize(name)
45
+ @redis = Wamp::Worker.config.redis(name)
46
+ @default_timeout = Wamp::Worker.config.timeout(name)
47
+ end
48
+
49
+ # Pushes a command onto the queue
50
+ #
51
+ # @param queue_name [String] - The name of the queue
52
+ # @param command [Symbol] - The command
53
+ # @param params [Hash] - The params for the request
54
+ # @param handle [String] - The response handle
55
+ def push(queue_name, command, params, handle=nil)
56
+
57
+ # Create the descriptor
58
+ descriptor = Descriptor.new(command, handle, params)
59
+
60
+ # Log the info
61
+ log(:push, queue_name, descriptor)
62
+
63
+ # Queue the command
64
+ self.redis.lpush(queue_name, descriptor.to_json)
65
+ end
66
+
67
+ # Pops a command off of the queue
68
+ #
69
+ # @param queue_name [String, Array] - The name of the queue (or multiple queues if brpop)
70
+ # @param wait [Bool] - True if we want to block waiting for the response
71
+ # @param delete [Bool] - True if we want the queue deleted (only applicable if wait)
72
+ # @param timeout [Int] - Number of seconds to wait before timing out
73
+ def pop(queue_name, wait: false, delete: false, timeout: nil)
74
+
75
+ # Retrieve the response from the queue
76
+ if wait
77
+ # Use the default timeout if non is specified
78
+ timeout ||= self.default_timeout
79
+
80
+ # Make the pop call
81
+ response = self.redis.brpop(queue_name, timeout: timeout)
82
+
83
+ # Returns [queue, value]
84
+ if response != nil
85
+ queue_name = response[0]
86
+ response = response[1]
87
+ end
88
+ else
89
+ # Else just call the method
90
+ response = self.redis.rpop(queue_name)
91
+ end
92
+
93
+ # If delete was set, delete the queue
94
+ if delete
95
+ self.redis.del(queue_name)
96
+ end
97
+
98
+ # Parse the response
99
+ descriptor = response != nil ? Descriptor.from_json(response) : nil
100
+
101
+ # Log the info
102
+ log(:pop, queue_name, descriptor)
103
+
104
+ # Return the queue_name and the descriptor
105
+ descriptor
106
+ end
107
+
108
+ private
109
+
110
+ # Returns the logger
111
+ #
112
+ def logger
113
+ Wamp::Worker.logger
114
+ end
115
+
116
+ # Logs the info
117
+ #
118
+ def log(type, queue_name, descriptor)
119
+ return unless logger.level == Logger::DEBUG
120
+
121
+ if descriptor
122
+ logger.debug("#{self.class.name} #{type.upcase} : #{queue_name}")
123
+ logger.debug(" command: #{descriptor.command}")
124
+ logger.debug(" params: #{descriptor.params}")
125
+ logger.debug(" handle: #{descriptor.handle}")
126
+ else
127
+ logger.debug("#{self.class.name} #{type.upcase} : #{queue_name} : EMPTY")
128
+ end
129
+ end
130
+
131
+
132
+ end
133
+ end
134
+ end
135
+
@@ -0,0 +1,28 @@
1
+ module Wamp
2
+ module Worker
3
+ module Rails
4
+
5
+ # This method will load Rails
6
+ #
7
+ # @param environment [String] - The Rails environment
8
+ # @param require [String] - The path to the Rails working directory or a file with requires
9
+ def self.load_app(environment, require)
10
+ ENV['RACK_ENV'] = ENV['RAILS_ENV'] = environment
11
+
12
+ raise ArgumentError, "'#{require}' does not exist" unless File.exist?(require)
13
+
14
+ if File.directory?(require)
15
+ require 'rails'
16
+ if ::Rails::VERSION::MAJOR < 5
17
+ raise "only Rails version 5 and higher supported"
18
+ else
19
+ require File.expand_path("#{require}/config/environment.rb")
20
+ end
21
+ else
22
+ require(require) || raise(ArgumentError, "no require file found at '#{require}'")
23
+ end
24
+ end
25
+
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,240 @@
1
+ require "thread"
2
+ require "wamp/client/connection"
3
+
4
+ module Wamp
5
+ module Worker
6
+ module Runner
7
+
8
+ # This is a base class for all of the runners
9
+ class Base
10
+ attr_reader :name, :dispatcher
11
+
12
+ # Constructor
13
+ #
14
+ # @param name [Symbol] - the name of the worker
15
+ def initialize(name, uuid: nil)
16
+ # Initialize the dispatcher
17
+ @name = name || :default
18
+ @dispatcher = Proxy::Dispatcher.new(self.name, uuid: uuid)
19
+ @active = false
20
+ end
21
+
22
+ # Returns the logger
23
+ #
24
+ def logger
25
+ Wamp::Worker.logger
26
+ end
27
+
28
+ # Returns if the runner is active
29
+ #
30
+ def active?
31
+ @active
32
+ end
33
+
34
+ # Starts the runner
35
+ #
36
+ def start
37
+ return if self.active?
38
+ @active = true
39
+ self._start
40
+ end
41
+
42
+ # Stops the runner
43
+ #
44
+ def stop
45
+ return unless self.active?
46
+ self._stop
47
+ @active = false
48
+ end
49
+
50
+ #region Override Methods
51
+ def _start
52
+ end
53
+
54
+ def _stop
55
+ end
56
+ #endregion
57
+
58
+ end
59
+
60
+ # This class monitors the queue and returns the descriptor
61
+ class Background < Base
62
+ attr_reader :callback, :thread
63
+
64
+ # Constructor
65
+ #
66
+ # @param name [Symbol] - the name of the worker
67
+ def initialize(name, uuid: nil, &callback)
68
+ super name, uuid: uuid
69
+
70
+ @callback = callback
71
+
72
+ # Log the event
73
+ logger.debug("#{self.class.name} '#{self.name}' created")
74
+ end
75
+
76
+ # Starts the background runner
77
+ #
78
+ def _start
79
+ # Start the background thread
80
+ Thread.new do
81
+
82
+ # The background thread will infinitely call the callback while the
83
+ # runner is active
84
+ while self.active?
85
+ begin
86
+ self.callback.call(self)
87
+ rescue => e
88
+ logger.error("#{self.class.name} #{e.class.name} - #{e.message}")
89
+ end
90
+ end
91
+
92
+ end
93
+ end
94
+ end
95
+
96
+ # This class is the main runner
97
+ class Main < Base
98
+ attr_reader :challenge, :client, :descriptor_queue, :queue_monitor
99
+
100
+ # Constructor
101
+ #
102
+ def initialize(name=nil, **options)
103
+ super name
104
+
105
+ # Combine the options
106
+ options = Wamp::Worker.config.connection(self.name).merge options
107
+
108
+ # Setup different options
109
+ @challenge = options[:challenge]
110
+ @client = options[:client] || Wamp::Client::Connection.new(options)
111
+ @active = false
112
+
113
+ # Log the event
114
+ logger.info("#{self.class.name} '#{self.name}' created with options")
115
+ logger.info(" uri: #{options[:uri]}")
116
+ logger.info(" realm: #{options[:realm]}")
117
+
118
+ # Create a queue for passing messages to the main runner
119
+ @descriptor_queue = ::Queue.new
120
+
121
+ # Note: since the queue monitor is attached to the same worker,
122
+ # we need to lock the UUIDs together. This will make sure they
123
+ # delegate background tasks correctly
124
+ uuid = self.dispatcher.uuid
125
+
126
+ # Create a command queue monitor
127
+ @queue_monitor = Background.new(self.name, uuid: uuid) do |runner|
128
+ descriptor = runner.dispatcher.check_queues
129
+ self.descriptor_queue.push(descriptor) if descriptor
130
+ end
131
+
132
+ # Add the tick loop handler
133
+ self.client.transport_class.add_tick_loop { self.tick_handler }
134
+
135
+ # Initialize the last tick
136
+ @last_tick = Time.now.to_i
137
+
138
+ # Catch SIGINT
139
+ Signal.trap('INT') { self.stop }
140
+ Signal.trap('TERM') { self.stop }
141
+ end
142
+
143
+ # Starts the run loop
144
+ #
145
+ def _start
146
+
147
+ # On join, we need to subscribe and register the different handlers
148
+ self.client.on :join do |session, details|
149
+ self.join_handler session, details
150
+ end
151
+
152
+ # On leave, we will print a message
153
+ self.client.on :leave do |reason, details|
154
+ self.leave_handler(reason, details)
155
+ end
156
+
157
+ # On challenge, we will run the users challenge code
158
+ self.client.on :challenge do |authmethod, details|
159
+ self.challenge_handler(authmethod, details)
160
+ end
161
+
162
+ # Start the monitors
163
+ self.queue_monitor.start
164
+
165
+ # Log info
166
+ logger.info("#{self.class.name} '#{self.name}' started")
167
+
168
+ # Start the connection
169
+ self.client.open
170
+ end
171
+
172
+ # Stops the run loop
173
+ #
174
+ def _stop
175
+
176
+ # Stop the other threads
177
+ self.queue_monitor.stop
178
+
179
+ # Stop the event machine
180
+ self.client.close
181
+ end
182
+
183
+ def join_handler(session, details)
184
+ logger.info("#{self.class.name} runner '#{self.name}' joined session with realm '#{details[:realm]}'")
185
+
186
+ # Set the session
187
+ self.dispatcher.session = session
188
+
189
+ # Register for the procedures
190
+ Wamp::Worker.register_procedures(self.name, self.dispatcher, session)
191
+
192
+ # Subscribe to the topics
193
+ Wamp::Worker.subscribe_topics(self.name, self.dispatcher, session)
194
+ end
195
+
196
+ def leave_handler(reason, details)
197
+ logger.info("#{self.class.name} runner '#{self.name}' left session: #{reason}")
198
+
199
+ # Clear the session
200
+ self.dispatcher.session = nil
201
+ end
202
+
203
+ def challenge_handler(authmethod, extra)
204
+ logger.info("#{self.class.name} runner '#{self.name}' challenge")
205
+
206
+ if self.challenge
207
+ self.challenge.call(authmethod, extra)
208
+ else
209
+ self.stop
210
+ raise(ArgumentError, "client asked for '#{authmethod}' challenge, but no ':challenge' option was provided")
211
+ end
212
+ end
213
+
214
+ # This method periodically checks if any work has come in from the queues
215
+ #
216
+ def tick_handler
217
+
218
+ # This code will implement the ticker every second. This tells the
219
+ # requestors that the worker is alive
220
+ current_time = Time.now.to_i
221
+ if current_time > @last_tick
222
+ self.dispatcher.increment_ticker
223
+ @last_tick = current_time
224
+ end
225
+
226
+ # Loop until the queue is empty
227
+ until self.descriptor_queue.empty? do
228
+
229
+ # Pop the value and process it
230
+ descriptor = self.descriptor_queue.pop
231
+ self.dispatcher.process(descriptor)
232
+
233
+ end
234
+ end
235
+
236
+ end
237
+
238
+ end
239
+ end
240
+ end