@@ -10,7 +10,7 @@ module Adapters
1010 class Http
1111 include Flipper ::Adapter
1212
13- attr_reader :client , :last_get_all_response
13+ attr_reader :client
1414
1515 def initialize ( options = { } )
1616 @client = Client . new ( url : options . fetch ( :url ) ,
@@ -24,6 +24,8 @@ def initialize(options = {})
2424 debug_output : options [ :debug_output ] )
2525 @last_get_all_etag = nil
2626 @last_get_all_result = nil
27+ @last_get_all_response = nil
28+ @get_all_mutex = Mutex . new
2729 end
2830
2931 def get ( feature )
@@ -58,31 +60,30 @@ def get_multi(features)
5860 end
5961
6062 def get_all ( cache_bust : false )
63+ options = { }
6164 path = "/features?exclude_gate_names=true"
6265 path += "&_cb=#{ Time . now . to_i } " if cache_bust
66+ etag = @get_all_mutex . synchronize { @last_get_all_etag }
6367
64- # Pass If-None-Match header if we have an ETag
65- options = { }
66- if @last_get_all_etag
67- options [ :headers ] = { if_none_match : @last_get_all_etag }
68+ if etag
69+ options [ :headers ] = { if_none_match : etag }
6870 end
6971
7072 response = @client . get ( path , options )
71-
72- @last_get_all_response = response
73+ @get_all_mutex . synchronize { @last_get_all_response = response }
7374
7475 if response . is_a? ( Net ::HTTPNotModified )
75- if @last_get_all_result
76- return @last_get_all_result
76+ cached_result = @get_all_mutex . synchronize { @last_get_all_result }
77+
78+ if cached_result
79+ return cached_result
7780 else
7881 raise Error , response
7982 end
8083 end
8184
8285 raise Error , response unless response . is_a? ( Net ::HTTPOK )
8386
84- @last_get_all_etag = response [ 'etag' ] if response [ 'etag' ]
85-
8687 parsed_response = response . body . empty? ? { } : Typecast . from_json ( response . body )
8788 parsed_features = parsed_response [ 'features' ] || [ ]
8889 gates_by_key = parsed_features . each_with_object ( { } ) do |parsed_feature , hash |
@@ -96,11 +97,18 @@ def get_all(cache_bust: false)
9697 result [ feature . key ] = result_for_feature ( feature , gates_by_key [ feature . key ] )
9798 end
9899
99- # Cache the result for 304 responses
100- @last_get_all_result = result
100+ @get_all_mutex . synchronize do
101+ @last_get_all_etag = response [ 'etag' ] if response [ 'etag' ]
102+ @last_get_all_result = result
103+ end
104+
101105 result
102106 end
103107
108+ def last_get_all_response
109+ @get_all_mutex . synchronize { @last_get_all_response }
110+ end
111+
104112 def features
105113 response = @client . get ( '/features?exclude_gate_names=true' )
106114 raise Error , response unless response . is_a? ( Net ::HTTPOK )
0 commit comments