Class: ElastomerClient::Middleware::OpaqueId
- Inherits:
-
Faraday::Middleware
- Object
- Faraday::Middleware
- ElastomerClient::Middleware::OpaqueId
- Defined in:
- lib/elastomer_client/middleware/opaque_id.rb
Overview
This Faraday middleware implements the “X-Opaque-Id” request / response headers for Elasticsearch. The X-Opaque-Id header, when provided on the request header, will be returned as a header in the response. This is useful in environments which reuse connections to ensure that cross-talk does not occur between two requests.
The SecureRandom lib is used to generate a UUID string for each request. This value is used as the content for the “X-Opaque-Id” header. If the value is different between the request and the response, then an ‘ElastomerClient::Client::OpaqueIdError` is raised. In this case no response will be returned.
See [Elasticsearch “X-Opaque-Id” header](github.com/elasticsearch/elasticsearch/issues/1202) for more details.
Constant Summary collapse
- X_OPAQUE_ID =
"X-Opaque-Id".freeze
- COUNTER_MAX =
2**32 - 1
Instance Method Summary collapse
-
#call(env) ⇒ Object
Faraday middleware implementation.
-
#generate_uuid ⇒ Object
Generate a UUID using the built-in SecureRandom class.
Instance Method Details
#call(env) ⇒ Object
Faraday middleware implementation.
env - Faraday environment Hash
Returns the environment Hash
32 33 34 35 36 37 38 39 40 41 42 43 44 |
# File 'lib/elastomer_client/middleware/opaque_id.rb', line 32 def call(env) uuid = generate_uuid.freeze env[:request_headers][X_OPAQUE_ID] = uuid @app.call(env).on_complete do |renv| response_uuid = renv[:response_headers][X_OPAQUE_ID] # Don't raise OpaqueIdError if the response is a 5xx if !response_uuid.nil? && uuid != response_uuid && renv.status < 500 raise ::ElastomerClient::Client::OpaqueIdError, "Conflicting 'X-Opaque-Id' headers: request #{uuid.inspect}, response #{response_uuid.inspect}" end end end |
#generate_uuid ⇒ Object
Generate a UUID using the built-in SecureRandom class. This can be a little slow at times, so we will reuse the same UUID and append an incrementing counter.
Returns the UUID string.
51 52 53 54 55 56 57 58 59 60 61 62 |
# File 'lib/elastomer_client/middleware/opaque_id.rb', line 51 def generate_uuid t = Thread.current unless t.key? :opaque_id_base t[:opaque_id_base] = (SecureRandom.urlsafe_base64(12) + "%08x").freeze t[:opaque_id_counter] = -1 end t[:opaque_id_counter] += 1 t[:opaque_id_counter] = 0 if t[:opaque_id_counter] > COUNTER_MAX t[:opaque_id_base] % t[:opaque_id_counter] end |