after_response 0.9.2 → 0.9.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = "after_response"
3
- s.version = "0.9.2"
3
+ s.version = "0.9.3"
4
4
  s.platform = Gem::Platform::RUBY
5
5
  s.summary = "Provides hooks to execute callbacks after the response has been delivered to the client."
6
6
 
@@ -11,7 +11,7 @@ the response to the client application sooner. This would mainly include logging
11
11
  event logging service, sending email and other tasks that do not affect the response body in any way.
12
12
  EOF
13
13
 
14
- s.files = Dir['{lib/*,rails/*}'] +
14
+ s.files = Dir['{lib/**/*,rails/**/*}'] +
15
15
  %w(after_response.gemspec CHANGELOG README)
16
16
  s.require_path = 'lib'
17
17
  s.extra_rdoc_files = ['README', 'CHANGELOG']
@@ -57,6 +57,16 @@ module AfterResponse
57
57
  @after_response_attached
58
58
  end
59
59
 
60
+ # If a container adapter isn't available, this method can be called to enable the buffering of events,
61
+ # and Starboard::EventQueue.flush! must be called manually
62
+ def self.buffer_and_flush_manually!
63
+ @after_response_attached ||= begin
64
+ raise "Callback hook already installed for #{current_container.name}" if current_container
65
+ logger.info{ "[AfterResponse] => Will flush manually" }
66
+ true
67
+ end
68
+ end
69
+
60
70
  def self.logger
61
71
  @logger ||= begin
62
72
  if defined?(Rails)
@@ -0,0 +1,72 @@
1
+ # ACK... Passenger < 3.0 sucks because request loop can't be wrapped to do what we need.
2
+ # https://github.com/FooBarWidget/passenger/blob/release-2.2.14/lib/phusion_passenger/abstract_request_handler.rb
3
+ # We have to overwrite the entire AbstractRequestHandler#main_loop method. Here goes.
4
+
5
+ class PhusionPassenger::AbstractRequestHandler
6
+ # Enter the request handler's main loop.
7
+ def main_loop
8
+ reset_signal_handlers
9
+ begin
10
+ @graceful_termination_pipe = IO.pipe
11
+ @graceful_termination_pipe[0].close_on_exec!
12
+ @graceful_termination_pipe[1].close_on_exec!
13
+
14
+ @main_loop_thread_lock.synchronize do
15
+ @main_loop_generation += 1
16
+ @main_loop_running = true
17
+ @main_loop_thread_cond.broadcast
18
+ end
19
+
20
+ install_useful_signal_handlers
21
+
22
+ while true
23
+ @iterations += 1
24
+ client = accept_connection
25
+ if client.nil?
26
+ break
27
+ end
28
+ begin
29
+ headers, input = parse_request(client)
30
+ if headers
31
+ if headers[REQUEST_METHOD] == PING
32
+ process_ping(headers, input, client)
33
+ else
34
+ process_request(headers, input, client)
35
+ end
36
+ end
37
+ rescue IOError, SocketError, SystemCallError => e
38
+ print_exception("Passenger RequestHandler", e)
39
+ ensure
40
+ # 'input' is the same as 'client' so we don't
41
+ # need to close that.
42
+ # The 'close_write' here prevents forked child
43
+ # processes from unintentionally keeping the
44
+ # connection open.
45
+ client.close_write rescue nil
46
+ client.close rescue nil
47
+ # All this crap to add one line...
48
+ AfterResponse::Callbacks.perform_after_response_callbacks!
49
+ end
50
+ @processed_requests += 1
51
+ end
52
+ rescue EOFError
53
+ # Exit main loop.
54
+ rescue Interrupt
55
+ # Exit main loop.
56
+ rescue SignalException => signal
57
+ if signal.message != HARD_TERMINATION_SIGNAL &&
58
+ signal.message != SOFT_TERMINATION_SIGNAL
59
+ raise
60
+ end
61
+ ensure
62
+ revert_signal_handlers
63
+ @main_loop_thread_lock.synchronize do
64
+ @graceful_termination_pipe[0].close rescue nil
65
+ @graceful_termination_pipe[1].close rescue nil
66
+ @main_loop_generation += 1
67
+ @main_loop_running = false
68
+ @main_loop_thread_cond.broadcast
69
+ end
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,11 @@
1
+ class PhusionPassenger::AbstractRequestHandler
2
+
3
+ protected
4
+ def accept_and_process_next_request_with_after_response(*args)
5
+ returning(accept_and_process_next_request_without_after_response(*args)) do
6
+ AfterResponse::Callbacks.perform_after_response_callbacks!
7
+ end
8
+ end
9
+ alias_method_chain :accept_and_process_next_request, :after_response
10
+
11
+ end
@@ -0,0 +1,33 @@
1
+ module AfterResponse
2
+
3
+ module Adapters
4
+ #
5
+ # Example (in config.ru):
6
+ #
7
+ # require 'after_response/adapters/unicorn'
8
+ #
9
+ # use AfterResponse::Adapters::UnicornMiddleware
10
+ class UnicornMiddleware < Struct.new(:app, :body)
11
+
12
+ def initialize(app)
13
+ super(app)
14
+ end
15
+
16
+ def call(env)
17
+ status, headers, self.body = app.call(env)
18
+ [ status, headers, self ]
19
+ end
20
+
21
+ def each(&block)
22
+ body.each(&block)
23
+ end
24
+
25
+ # In Unicorn, this is called _after_ the socket is closed. (Not true for at least passenger3)
26
+ def close
27
+ body.close if body.respond_to?(:close)
28
+ AfterResponse::Callbacks.perform_after_response_callbacks!
29
+ end
30
+
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,9 @@
1
+ class Unicorn::HttpServer
2
+ alias process_client_without_after_response process_client
3
+ undef_method :process_client
4
+ def process_client(client)
5
+ result = process_client_without_after_response(client)
6
+ AfterResponse::Callbacks.perform_after_response_callbacks!
7
+ result
8
+ end
9
+ end
@@ -0,0 +1,80 @@
1
+ module AfterResponse
2
+
3
+ def self.callbacks
4
+ Callbacks.callbacks
5
+ end
6
+
7
+ def self.transient_callbacks
8
+ Callbacks.transient_callbacks
9
+ end
10
+
11
+ def self.append_after_response(&block)
12
+ Callbacks.append_after_response(&block)
13
+ end
14
+
15
+ def self.append_transient_after_response(&block)
16
+ Callbacks.append_transient_after_response(&block)
17
+ end
18
+
19
+ module Callbacks
20
+
21
+ module Helpers
22
+ def self.included(mod)
23
+ mod.send(:include, TransientHelpers)
24
+ mod.send(:extend, ModuleHelpers)
25
+ end
26
+ end
27
+
28
+ # ApplicationController should include this
29
+ module TransientHelpers
30
+ def after_response(&block)
31
+ AfterResponse.append_transient_after_response(&block)
32
+ end
33
+ end
34
+
35
+ # ApplicationController should extend this
36
+ module ModuleHelpers
37
+ def after_response(&block)
38
+ AfterResponse.append_after_response(&block)
39
+ end
40
+ end
41
+
42
+ def self.append_after_response(&block)
43
+ if AfterResponse.bufferable?
44
+ callbacks << block
45
+ else
46
+ block.call
47
+ end
48
+ end
49
+
50
+ def self.append_transient_after_response(&block)
51
+ if AfterResponse.bufferable?
52
+ transient_callbacks << block
53
+ else
54
+ block.call
55
+ end
56
+ end
57
+
58
+ def self.callbacks
59
+ Thread.current[:__after_response_callbacks__] ||= []
60
+ end
61
+
62
+ def self.transient_callbacks
63
+ Thread.current[:__transient_after_response_callbacks__] ||= []
64
+ end
65
+
66
+ def self.all_callbacks
67
+ transient_callbacks + callbacks
68
+ end
69
+
70
+ def self.perform_after_response_callbacks!
71
+ all_callbacks.each do |b|
72
+ b.call
73
+ end
74
+ ensure
75
+ AfterResponse.transient_callbacks.clear
76
+ end
77
+
78
+ end
79
+
80
+ end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: after_response
3
3
  version: !ruby/object:Gem::Version
4
- hash: 63
5
- prerelease: false
4
+ hash: 61
5
+ prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 9
9
- - 2
10
- version: 0.9.2
9
+ - 3
10
+ version: 0.9.3
11
11
  platform: ruby
12
12
  authors:
13
13
  - Kevin E. Hunt
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2010-12-27 00:00:00 -08:00
18
+ date: 2011-05-02 00:00:00 -07:00
19
19
  default_executable:
20
20
  dependencies: []
21
21
 
@@ -34,6 +34,11 @@ extra_rdoc_files:
34
34
  - README
35
35
  - CHANGELOG
36
36
  files:
37
+ - lib/after_response/adapters/passenger2_2.rb
38
+ - lib/after_response/adapters/passenger3.rb
39
+ - lib/after_response/adapters/unicorn_middleware.rb
40
+ - lib/after_response/adapters/unicorn_monkeypatch.rb
41
+ - lib/after_response/callbacks.rb
37
42
  - lib/after_response.rb
38
43
  - rails/init.rb
39
44
  - after_response.gemspec
@@ -69,7 +74,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
69
74
  requirements: []
70
75
 
71
76
  rubyforge_project:
72
- rubygems_version: 1.3.7
77
+ rubygems_version: 1.5.2
73
78
  signing_key:
74
79
  specification_version: 3
75
80
  summary: Provides hooks to execute callbacks after the response has been delivered to the client.