Class: RackRequestBlocker

Inherits:
Object
  • Object
show all
Defined in:
lib/rack_request_blocker.rb,
lib/rack_request_blocker/version.rb

Overview

Rack middleware that keeps track of the number of active requests and can block new requests. blog.salsify.com/engineering/tearing-capybara-ajax-tests

Constant Summary collapse

VERSION =
"1.0.0"
@@num_active_requests =
Concurrent::AtomicFixnum.new(0)
@@allowing_requests =
Concurrent::Event.new.tap { |e| e.set }

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(app) ⇒ RackRequestBlocker

Returns a new instance of RackRequestBlocker.



26
27
28
# File 'lib/rack_request_blocker.rb', line 26

def initialize(app)
  @app = app
end

Class Method Details

.allow_requests!Object

Allows the server to accept requests again.



22
23
24
# File 'lib/rack_request_blocker.rb', line 22

def self.allow_requests!
  @@allowing_requests.set
end

.block_requests!Object

Prevents the server from accepting new requests. Any new requests will return an HTTP 503 status.



17
18
19
# File 'lib/rack_request_blocker.rb', line 17

def self.block_requests!
  @@allowing_requests.reset
end

.num_active_requestsObject

Returns the number of requests the server is currently processing.



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

def self.num_active_requests
  @@num_active_requests.value
end

.wait_for_no_active_requests(max_wait_time: 10, for_example: nil, diagnostic_log: true) ⇒ Object



43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# File 'lib/rack_request_blocker.rb', line 43

def self.wait_for_no_active_requests(max_wait_time: 10, for_example: nil, diagnostic_log: true)
  RackRequestBlocker.block_requests!

  unless num_active_requests == 0 || diagnostic_log == false
    msg = "Waiting on #{num_active_requests} active requests"
    msg += " for #{for_example.location}" if for_example
    log msg
  end

  obtained = (num_active_requests == 0) || @@allowing_requests.wait(max_wait_time)
  unless obtained
    raise Timeout::Error, "rack_request_blocker gave up waiting #{max_wait_time}s for pending AJAX requests complete"
  end
ensure
  RackRequestBlocker.allow_requests!
end

Instance Method Details

#call(env) ⇒ Object



30
31
32
33
34
35
36
37
38
39
# File 'lib/rack_request_blocker.rb', line 30

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