Class: Volt::Dispatcher

Inherits:
Object show all
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 Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(volt_app) ⇒ Dispatcher

Returns a new instance of Dispatcher.



16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# File 'lib/volt/tasks/dispatcher.rb', line 16

def initialize(volt_app)
  @volt_app = volt_app

  if Volt.env.test?
    # When testing, we want to run immediately so it blocks and doesn't
    # start the next thread.
    @worker_pool = Concurrent::ImmediateExecutor.new
  else
    @worker_pool = Concurrent::ThreadPoolExecutor.new(
      min_threads: Volt.config.min_worker_threads,
      max_threads: Volt.config.max_worker_threads
    )
  end

  @worker_timeout = Volt.config.worker_timeout || 60
end

Instance Attribute Details

#volt_appObject (readonly)

Returns the value of attribute volt_app.



14
15
16
# File 'lib/volt/tasks/dispatcher.rb', line 14

def volt_app
  @volt_app
end

Class Method Details

.component_last_modified_timeObject



42
43
44
45
46
47
48
# File 'lib/volt/tasks/dispatcher.rb', line 42

def self.component_last_modified_time
  unless @last_modified_time
    component_modified(Time.now.to_i.to_s)
  end

  @last_modified_time
end

.component_modified(time) ⇒ Object

Mark the last time of the component modification for caching in sprockets



34
35
36
# File 'lib/volt/tasks/dispatcher.rb', line 34

def self.component_modified(time)
  @last_modified_time = time
end

Instance Method Details

#close_channel(channel) ⇒ Object



89
90
91
# File 'lib/volt/tasks/dispatcher.rb', line 89

def close_channel(channel)
  QueryTasks.new(@volt_app, channel).close!
end

#component_modified(time) ⇒ Object



38
39
40
# File 'lib/volt/tasks/dispatcher.rb', line 38

def component_modified(time)
  self.class.component_modified(time)
end

#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.



53
54
55
56
57
58
59
60
61
62
63
64
65
66
# File 'lib/volt/tasks/dispatcher.rb', line 53

def dispatch(channel, message)
  # Dispatch the task in the worker pool.  Pas in the meta data
  @worker_pool.post do
    begin
      dispatch_in_thread(channel, message)
    rescue => e
      err = "Worker Thread Exception for #{message}\n"
      err += e.inspect
      err += e.backtrace.join("\n") if e.respond_to?(:backtrace)

      Volt.logger.error(err)
    end
  end
end

#safe_method?(klass, method_name) ⇒ Boolean

Check if it is safe to use this method

Returns:



70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
# File 'lib/volt/tasks/dispatcher.rb', line 70

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