lib/http/2/connection.rb in http-2-0.10.1 vs lib/http/2/connection.rb in http-2-0.10.2

- old
+ new

@@ -31,10 +31,13 @@ DEFAULT_WEIGHT = 16 # Default connection "fast-fail" preamble string as defined by the spec. CONNECTION_PREFACE_MAGIC = "PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n".freeze + # Time to hold recently closed streams until purge (seconds) + RECENTLY_CLOSED_STREAMS_TTL = 15 + # Connection encapsulates all of the connection, stream, flow-control, # error management, and other processing logic required for a well-behaved # HTTP 2.0 endpoint. # # Note that this class should not be used directly. Instead, you want to @@ -681,22 +684,34 @@ @active_stream_count -= 1 # Store a reference to the closed stream, such that we can respond # to any in-flight frames while close is registered on both sides. # References to such streams will be purged whenever another stream - # is closed, with a minimum of 15s RTT time window. - @streams_recently_closed[id] = Time.now - to_delete = @streams_recently_closed.select { |_, v| (Time.now - v) > 15 } - to_delete.each do |stream_id| - @streams.delete stream_id - @streams_recently_closed.delete stream_id - end + # is closed, with a defined RTT time window. + @streams_recently_closed[id] = Time.now.to_i + cleanup_recently_closed end stream.on(:promise, &method(:promise)) if self.is_a? Server stream.on(:frame, &method(:send)) @streams[id] = stream + end + + # Purge recently streams closed within defined RTT time window. + def cleanup_recently_closed + now_ts = Time.now.to_i + to_delete = [] + @streams_recently_closed.each do |stream_id, ts| + # Ruby Hash enumeration is ordered, so once fresh stream is met we can stop searching. + break if now_ts - ts < RECENTLY_CLOSED_STREAMS_TTL + to_delete << stream_id + end + + to_delete.each do |stream_id| + @streams.delete stream_id + @streams_recently_closed.delete stream_id + end end # Emit GOAWAY error indicating to peer that the connection is being # aborted, and once sent, raise a local exception. #