Class: Volt::Dispatcher
- Includes:
- DRb::DRbUndumped
- Defined in:
- lib/volt/tasks/dispatcher.rb
Overview
The task dispatcher is responsible for taking incoming messages from the socket channel and dispatching them to the proper handler.
Instance Method Summary collapse
-
#dispatch(channel, message) ⇒ Object
Dispatch takes an incoming Task from the client and runs it on the server, returning the result to the client.
-
#safe_method?(klass, method_name) ⇒ Boolean
Check if it is safe to use this method.
Instance Method Details
#dispatch(channel, message) ⇒ Object
Dispatch takes an incoming Task from the client and runs it on the server, returning the result to the client. Tasks returning a promise will wait to return.
15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 |
# File 'lib/volt/tasks/dispatcher.rb', line 15 def dispatch(channel, ) callback_id, class_name, method_name, , *args = method_name = method_name.to_sym # Get the class klass = Object.send(:const_get, class_name) promise = Promise.new start_time = Time.now.to_f # Check that we are calling on a Task class and a method provide at # Task or above in the ancestor chain. (so no :send or anything) if safe_method?(klass, method_name) promise.resolve(nil) # Init and send the method promise = promise.then do Thread.current['meta'] = # # Profile the code # RubyProf.start result = klass.new(channel, self).send(method_name, *args) # res = RubyProf.stop # # # Print a flat profile to text # printer = RubyProf::FlatPrinter.new(res) # printer.print(STDOUT) Thread.current['meta'] = nil result end else # Unsafe method promise.reject(RuntimeError.new("unsafe method: #{method_name}")) end # Called after task runs or fails finish = proc do |error| run_time = ((Time.now.to_f - start_time) * 1000).round(3) Volt.logger.log_dispatch(class_name, method_name, run_time, args, error) end # Run the promise and pass the return value/error back to the client promise.then do |result| channel.('response', callback_id, result, nil) finish.call end.fail do |error| finish.call(error) channel.('response', callback_id, nil, error) end end |
#safe_method?(klass, method_name) ⇒ Boolean
Check if it is safe to use this method
74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 |
# File 'lib/volt/tasks/dispatcher.rb', line 74 def safe_method?(klass, method_name) # Make sure the class being called is a Task. return false unless klass.ancestors.include?(Task) # Make sure the method is defined on the klass we're using and not up the hiearchy. # ^ This check prevents methods like #send, #eval, #instance_eval, #class_eval, etc... klass.ancestors.each do |ancestor_klass| if ancestor_klass.instance_methods(false).include?(method_name) return true elsif ancestor_klass == Task # We made it to Task and didn't find the method, that means it # was defined above Task, so we reject the call. return false end end false end |