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.



33
34
35
36
37
# File 'lib/praxis/dispatcher.rb', line 33

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

Class Attribute Details

.deferred_callbacksObject (readonly)

Returns the value of attribute deferred_callbacks.



18
19
20
# File 'lib/praxis/dispatcher.rb', line 18

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.



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

def application
  @application
end

#controllerObject (readonly)

Returns the value of attribute controller.



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

def controller
  @controller
end

#requestObject (readonly)

Returns the value of attribute request.



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

def request
  @request
end

Class Method Details

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



25
26
27
# File 'lib/praxis/dispatcher.rb', line 25

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

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



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

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

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



29
30
31
# File 'lib/praxis/dispatcher.rb', line 29

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

Instance Method Details

#after(*stage_path, &block) ⇒ Object



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

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



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

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



70
71
72
73
74
75
76
77
78
79
80
81
82
83
# File 'lib/praxis/dispatcher.rb', line 70

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

  payload = { request: request, response: nil, controller: @controller }

  instrumented_dispatch(payload)
ensure
  @controller = nil
  @action = nil
  @request = nil
end

#instrumented_dispatch(payload) ⇒ Object



85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
# File 'lib/praxis/dispatcher.rb', line 85

def instrumented_dispatch(payload)
  Notifications.instrument 'praxis.request.all', 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
  rescue StandardError => e
    @application.error_handler.handle!(request, e)
  end
end

#reset_cache!Object

TODO: fix for multithreaded environments



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

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

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

#setup_deferred_callbacks!Object



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

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

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

#setup_stages!Object



39
40
41
42
43
44
45
46
# File 'lib/praxis/dispatcher.rb', line 39

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(&:setup!)
  setup_deferred_callbacks!
end