Class: Waterpig::RequestWaitMiddleware

Inherits:
Object
  • Object
show all
Defined in:
lib/waterpig/request-wait-middleware.rb

Overview

This Rack middleware is designed to resolve common timing problems with end-to-end tests. Without it, specs will often finish and :after hooks will get executed while a request is still “in flight”. The result can be, for example, specs failing because the database has been wiped before a request truly finishes.

This middleware counts requests and allows other processes (e.g. testing processes) to block via RequestWaitMiddle.wait_for_idle() so that they do not proceed until all requests have completed.

Constant Summary collapse

BLOCKED =
[503, {}, ["Test is over - server no longer available"]].freeze
@@idle_mutex =
Mutex.new
@@waiting_requests =
{}
@@block_requests =
false

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(app) ⇒ RequestWaitMiddleware

Returns a new instance of RequestWaitMiddleware.



37
38
39
# File 'lib/waterpig/request-wait-middleware.rb', line 37

def initialize(app)
  @app = app
end

Class Method Details

.wait_for_idleObject

This is the only method one would normally call: wrap calls that e.g. drop the test database in wait_for_idle{ <code> } in order to be sure that outstanding requests are complete



23
24
25
26
27
28
29
30
31
# File 'lib/waterpig/request-wait-middleware.rb', line 23

def self.wait_for_idle
  @@block_requests = true

  @@idle_mutex.synchronize do
    yield
  end

  @@block_requests = false
end

Instance Method Details

#block_requestObject



54
55
56
# File 'lib/waterpig/request-wait-middleware.rb', line 54

def block_request
  BLOCKED
end

#block_requests?Boolean

Returns:

  • (Boolean)


33
34
35
# File 'lib/waterpig/request-wait-middleware.rb', line 33

def block_requests?
  @@block_requests
end

#call(env) ⇒ Object



41
42
43
44
45
46
47
48
49
50
# File 'lib/waterpig/request-wait-middleware.rb', line 41

def call(env)
  increment_active_requests(env)
  if block_requests?
    block_request
  else
    @app.call(env)
  end
ensure
  decrement_active_requests(env)
end

#decrement_active_requests(env) ⇒ Object



63
64
65
66
67
68
# File 'lib/waterpig/request-wait-middleware.rb', line 63

def decrement_active_requests(env)
  @@waiting_requests.delete(env.object_id)
  if @@waiting_requests.empty?
    @@idle_mutex.unlock
  end
end

#increment_active_requests(env) ⇒ Object



58
59
60
61
# File 'lib/waterpig/request-wait-middleware.rb', line 58

def increment_active_requests(env)
  @@idle_mutex.lock unless @@idle_mutex.owned?
  @@waiting_requests[env.object_id] = true
end