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



66
67
68
69
# File 'lib/praxis/dispatcher.rb', line 66

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



61
62
63
64
# File 'lib/praxis/dispatcher.rb', line 61

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



71
72
73
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
# File 'lib/praxis/dispatcher.rb', line 71

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



105
106
107
108
109
110
111
# File 'lib/praxis/dispatcher.rb', line 105

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



49
50
51
52
53
54
55
56
57
58
59
# File 'lib/praxis/dispatcher.rb', line 49

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
# 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)
  setup_deferred_callbacks!
end