diff --git a/CHANGELOG.md b/CHANGELOG.md index e72235c..5e04276 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,11 @@ +## 1.1.0 + +Several changes which improved performance for the common cases. A few highlights: + +* Opting into ruby 3.4 features when possible (such as `String#append_as_bytes` instead of `String#<<`) +* reducing string and array allocations on several places (connection management, frame generation, hpack header compression, etc) +* "streams recently closed" not having to regenerate the list when not necessary + ## 1.0.2 ### Improvements diff --git a/lib/http/2/version.rb b/lib/http/2/version.rb index be64531..82fa53c 100644 --- a/lib/http/2/version.rb +++ b/lib/http/2/version.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true module HTTP2 - VERSION = "1.0.2" + VERSION = "1.1.0" end diff --git a/sig/2.rbs b/sig/2.rbs index 593eda1..7887f62 100644 --- a/sig/2.rbs +++ b/sig/2.rbs @@ -41,44 +41,44 @@ module HTTP2 # # FRAMES type frame_control_flags = Array[:end_headers | :end_stream] + type common_frame = { stream: Integer } + # # HEADERS - # type headers_frame = { - # type: :headers, flags: frame_control_flags, stream: Integer, payload: Enumerable[header_pair], - # ?method: Symbol, ?trailer: Array[String], ?content_length: Integer, ?padding: Integer - # } + type headers_frame = common_frame & { + type: :headers, flags: frame_control_flags, payload: Enumerable[header_pair] | String, + ?method: Symbol, ?trailer: Array[String], ?content_length: Integer, ?padding: Integer + } # # DATA - type data_frame = { type: :data, flags: frame_control_flags, stream: Integer, length: Integer, payload: String, padding: Integer } - | { type: :data, flags: frame_control_flags, stream: Integer, length: Integer, payload: String } - | { type: :data, flags: frame_control_flags, payload: String } + type data_frame = { type: :data, flags: frame_control_flags, ?length: Integer, payload: String, ?padding: Integer } # # PUSH_PROMISE - # type push_promise_frame = { type: :push_promise, promise_stream: Integer, flags: frame_control_flags, stream: Integer, ?method: Symbol, ?trailer: Array[String], ?content_length: Integer, payload: Enumerable[header_pair], ?padding: Integer } + type push_promise_frame = { type: :push_promise, promise_stream: Integer, flags: frame_control_flags, ?method: Symbol, ?trailer: Array[String], ?content_length: Integer, payload: Enumerable[header_pair], ?padding: Integer } # # SETTINGS - # type settings_frame = { type: :settings, stream: 0, payload: Array[[Symbol | Integer, Integer]] } + type settings_frame = { type: :settings, payload: Array[[Symbol | Integer, Integer]] } # # WINDOW_UPDATE - # type window_update_frame = { type: :window_update, stream: Integer, increment: Integer } + type window_update_frame = { type: :window_update, increment: Integer } # # PRIORITY - type priority_frame = { type: :priority, stream: Integer, dependency: Integer, exclusive: bool, weight: Integer } + type priority_frame = { dependency: Integer, exclusive: bool, weight: Integer } # # ALTSVC - # type altsvc_frame = { type: :altsvc, stream: 0, max_age: Integer, port: Integer, proto: "String", host: String } + type altsvc_frame = { type: :altsvc, max_age: Integer, port: Integer, proto: "String", host: String } # # ORIGIN - # type origin_frame = { type: :origin, stream: 0, origin: Array[String] } + type origin_frame = { type: :origin, origin: Array[String] } # # PING - # type ping_frame = { type: :ping, payload: String, length: Integer } + type ping_frame = { type: :ping, payload: String, length: Integer } # # GOAWAY - # type goaway_frame = { type: :goaway, stream: 0, last_stream: Integer, error: Symbol? } + type goaway_frame = { type: :goaway, last_stream: Integer, error: Symbol? } - # type frame = headers_frame | data_frame | push_promise_frame | + # type frame = common_frame & (headers_frame | data_frame | push_promise_frame | # settings_frame | window_update_frame | priority_frame | altsvc_frame | - # origin_frame | ping_frame | goaway_frame + # origin_frame | ping_frame | goaway_frame) type frame_key = :type | :flags | :stream | :padding | :ignore | # headers diff --git a/sig/flow_buffer.rbs b/sig/flow_buffer.rbs index 38254e5..1b82e16 100644 --- a/sig/flow_buffer.rbs +++ b/sig/flow_buffer.rbs @@ -10,14 +10,14 @@ module HTTP2 private - def update_local_window: (frame) -> void + def update_local_window: (data_frame frame) -> void def calculate_window_update: (Integer) -> void - def send_data: (?frame? frame, ?bool encode) -> void + def send_data: (?data_frame? frame, ?bool encode) -> void - def send_frame: (frame frame, bool encode) -> void + def send_frame: (data_frame frame, bool encode) -> void - def process_window_update: (frame: frame, ?encode: bool) -> void + def process_window_update: (frame: window_update_frame, ?encode: bool) -> void end end \ No newline at end of file diff --git a/sig/frame_buffer.rbs b/sig/frame_buffer.rbs index 49c50b1..8dbaaed 100644 --- a/sig/frame_buffer.rbs +++ b/sig/frame_buffer.rbs @@ -4,7 +4,7 @@ module HTTP2 @buffer: Array[data_frame] - def <<: (data_frame) -> void + def <<: (data_frame frame) -> void def empty?: () -> bool diff --git a/sig/header/encoding_context.rbs b/sig/header/encoding_context.rbs index 60fc8c6..e20fe6d 100644 --- a/sig/header/encoding_context.rbs +++ b/sig/header/encoding_context.rbs @@ -38,6 +38,8 @@ module HTTP2 def table_size=: (Integer) -> void + def listen_on_table: { () -> void } -> void + private def initialize: (?connection_opts options) -> void diff --git a/sig/stream.rbs b/sig/stream.rbs index a4f2f87..3f1864c 100644 --- a/sig/stream.rbs +++ b/sig/stream.rbs @@ -29,15 +29,15 @@ module HTTP2 def closed?: () -> bool - def receive: (frame) -> void + def receive: (frame frame) -> void alias << receive - def verify_trailers: (frame) -> void + def verify_trailers: (headers_frame frame) -> void def calculate_content_length: (Integer?) -> void - def send: (frame) -> void + def send: (frame frame) -> void def headers: (Enumerable[header_pair] headers, ?end_headers: bool, ?end_stream: bool) -> void @@ -80,7 +80,7 @@ module HTTP2 def complete_transition: (frame) -> void - def process_priority: ({weight: Integer, dependency: Integer, exclusive: bool}) -> void + def process_priority: (priority_frame frame) -> void def end_stream?: (frame frame) -> boolish