Class: Praxis::Dispatcher

Inherits:
Object
  • Object
show all
Defined in:
lib/praxis/dispatcher.rb

Class Attribute Summary collapse

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(application: Application.instance) ⇒ Dispatcher

Returns a new instance of Dispatcher.



35
36
37
38
39
# File 'lib/praxis/dispatcher.rb', line 35

def initialize(application: Application.instance)
  @stages = []
  @application = application
  setup_stages!
end

Class Attribute Details

.deferred_callbacksObject (readonly)

Returns the value of attribute deferred_callbacks.



20
21
22
# File 'lib/praxis/dispatcher.rb', line 20

def deferred_callbacks
  @deferred_callbacks
end

Instance Attribute Details

#actionObject (readonly)

Returns the value of attribute action.



11
12
13
# File 'lib/praxis/dispatcher.rb', line 11

def action
  @action
end

#applicationObject (readonly)

Returns the value of attribute application.



13
14
15
# File 'lib/praxis/dispatcher.rb', line 13

def application
  @application
end

#controllerObject (readonly)

Returns the value of attribute controller.



10
11
12
# File 'lib/praxis/dispatcher.rb', line 10

def controller
  @controller
end

#requestObject (readonly)

Returns the value of attribute request.



12
13
14
# File 'lib/praxis/dispatcher.rb', line 12

def request
  @request
end

Class Method Details

.after(*stage_path, **conditions, &block) ⇒ Object



27
28
29
# File 'lib/praxis/dispatcher.rb', line 27

def self.after(*stage_path, **conditions, &block)
  @deferred_callbacks[:after] << [conditions, block]
end

.before(*stage_path, **conditions, &block) ⇒ Object



23
24
25
# File 'lib/praxis/dispatcher.rb', line 23

def self.before(*stage_path, **conditions, &block)
  @deferred_callbacks[:before] << [conditions, block]
end

.current(thread: Thread.current, application: Application.instance) ⇒ Object



31
32
33
# File 'lib/praxis/dispatcher.rb', line 31

def self.current(thread: Thread.current, application: Application.instance)
  thread[:praxis_dispatcher] ||= self.new(application: application)
end

Instance Method Details

#after(*stage_path, &block) ⇒ Object



69
70
71
72
# File 'lib/praxis/dispatcher.rb', line 69

def after(*stage_path, &block)
  stage_name = stage_path.shift
  stages.find { |stage| stage.name == stage_name }.after(*stage_path, &block)
end

#before(*stage_path, &block) ⇒ Object



64
65
66
67
# File 'lib/praxis/dispatcher.rb', line 64

def before(*stage_path, &block)
  stage_name = stage_path.shift
  stages.find { |stage| stage.name == stage_name }.before(*stage_path, &block)
end

#dispatch(controller_class, action, request) ⇒ Object



74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
# File 'lib/praxis/dispatcher.rb', line 74

def dispatch(controller_class, action, request)
  @controller = controller_class.new(request)
  @action = action
  @request = request

  payload = {request: request, response: nil}

  Notifications.instrument 'praxis.request.all'.freeze, payload do
    begin
      # the response stage must be the final stage in the list
      *stages, response_stage = @stages

      stages.each do |stage|
        result = stage.run
        case result
        when Response
          controller.response = result
          break
        end
      end

      response_stage.run

      payload[:response] = controller.response
      controller.response.finish
    rescue => e
      @application.error_handler.handle!(request, e)
    end
  end
ensure
  @controller = nil
  @action = nil
  @request = nil
end

#reset_cache!Object

TODO: fix for multithreaded environments



111
112
113
114
115
116
117
# File 'lib/praxis/dispatcher.rb', line 111

def reset_cache!
  return unless Praxis::Blueprint.caching_enabled?

  Praxis::Blueprint.cache = Hash.new do |hash, key|
    hash[key] = Hash.new
  end
end

#setup_deferred_callbacks!Object



52
53
54
55
56
57
58
59
60
61
62
# File 'lib/praxis/dispatcher.rb', line 52

def setup_deferred_callbacks!
  self.class.deferred_callbacks.each do |stage_name, callbacks|
    callbacks[:before].each do |(*stage_path, block)|
      self.before(stage_name, *stage_path, &block)
    end

    callbacks[:after].each do |(*stage_path, block)|
      self.after(stage_name, *stage_path, &block)
    end
  end
end

#setup_stages!Object



41
42
43
44
45
46
47
48
49
50
# File 'lib/praxis/dispatcher.rb', line 41

def setup_stages!
  @stages << RequestStages::LoadRequest.new(:load_request, self)
  @stages << RequestStages::Validate.new(:validate, self)
  @stages << RequestStages::Action.new(:action, self)
  @stages << RequestStages::Response.new(:response, self)
  @stages.each do |s|
    s.setup!
  end
  setup_deferred_callbacks!
end