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
# 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
    # 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
  end
rescue => e
  @application.error_handler.handle!(request, e)
ensure
  @controller = nil
  @action = nil
  @request = nil
end

#reset_cache!Object



108
109
110
111
112
113
114
# File 'lib/praxis/dispatcher.rb', line 108

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