From e14784f63d39660c630fadd754b4ad6cf5836dae Mon Sep 17 00:00:00 2001 From: Samuel Williams Date: Wed, 29 Jul 2026 18:33:52 +1200 Subject: [PATCH] Close HTTP/2 request queue --- lib/async/http/protocol/http2/server.rb | 8 ++---- test/async/http/protocol/http2/server.rb | 31 ++++++++++++++++++++++++ 2 files changed, 33 insertions(+), 6 deletions(-) create mode 100644 test/async/http/protocol/http2/server.rb diff --git a/lib/async/http/protocol/http2/server.rb b/lib/async/http/protocol/http2/server.rb index a00e5ac..82ec908 100644 --- a/lib/async/http/protocol/http2/server.rb +++ b/lib/async/http/protocol/http2/server.rb @@ -41,11 +41,7 @@ def accept_stream(stream_id) # Close the server connection and stop accepting requests. def close(error = nil) - if @requests - # Stop the request loop: - @requests.enqueue(nil) - @requests = nil - end + @requests.close super end @@ -57,7 +53,7 @@ def each(task: Task.current) task.annotate("Reading #{version} requests for #{self.class}.") # It's possible the connection has died before we get here... - @requests&.async do |task, request| + @requests.async do |task, request| task.annotate("Incoming request: #{request.method} #{request.path.inspect}.") response = nil diff --git a/test/async/http/protocol/http2/server.rb b/test/async/http/protocol/http2/server.rb new file mode 100644 index 0000000..dfc6516 --- /dev/null +++ b/test/async/http/protocol/http2/server.rb @@ -0,0 +1,31 @@ +# frozen_string_literal: true + +# Released under the MIT License. +# Copyright, 2026, by Samuel Williams. + +require "async/http/protocol/http2" +require "sus/fixtures/async/scheduler_context" +require "socket" + +describe Async::HTTP::Protocol::HTTP2::Server do + include Sus::Fixtures::Async::SchedulerContext + + let(:sockets) {Socket.pair(Socket::PF_UNIX, Socket::SOCK_STREAM)} + let(:stream) {IO::Stream(sockets.first)} + let(:server) {subject.new(stream)} + + it "closes the request queue" do + request = Object.new + server.requests.enqueue(request) + + server.close + + expect(server.requests).to be(:closed?) + expect(server.requests.dequeue).to be == request + expect(server.requests.dequeue).to be_nil + + expect do + server.requests.enqueue(Object.new) + end.to raise_exception(Async::Queue::ClosedError) + end +end