Skip to content

Commit 4628f98

Browse files
committed
Merge companion and standard pool into one
1 parent 60b4529 commit 4628f98

File tree

3 files changed

+37
-67
lines changed

3 files changed

+37
-67
lines changed

spec/helpers/networking/connection_pool_spec.cr

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ require "../../load_config"
2121
require "../../../src/invidious/helpers/crystal_class_overrides"
2222
require "../../../src/invidious/connection/*"
2323

24+
TEST_SERVER_URL = URI.parse("http://localhost:12345")
25+
2426
server = HTTP::Server.new do |context|
2527
request = context.request
2628
response = context.response
@@ -44,41 +46,40 @@ Fiber.yield
4446
Spectator.describe Invidious::ConnectionPool do
4547
describe "Pool" do
4648
it "Can make a requests through standard HTTP methods" do
47-
pool = Invidious::ConnectionPool::Pool.new(URI.parse("http://localhost:12345"), max_capacity: 100)
49+
pool = Invidious::ConnectionPool::Pool.new(max_capacity: 100) { next make_client(TEST_SERVER_URL) }
4850

4951
expect(pool.get("/get").body).to eq("get")
5052
expect(pool.post("/post").body).to eq("post")
5153
end
5254

5355
it "Can make streaming requests" do
54-
pool = Invidious::ConnectionPool::Pool.new(URI.parse("http://localhost:12345"), max_capacity: 100)
56+
pool = Invidious::ConnectionPool::Pool.new(max_capacity: 100) { next make_client(TEST_SERVER_URL) }
5557

5658
expect(pool.get("/get") { |r| r.body_io.gets_to_end }).to eq("get")
5759
expect(pool.get("/post") { |r| r.body }).to eq("")
5860
expect(pool.post("/post") { |r| r.body_io.gets_to_end }).to eq("post")
5961
end
6062

6163
it "Allows more than one clients to be checked out (if applicable)" do
62-
pool = Invidious::ConnectionPool::Pool.new(URI.parse("http://localhost:12345"), max_capacity: 100)
64+
pool = Invidious::ConnectionPool::Pool.new(max_capacity: 100) { next make_client(TEST_SERVER_URL) }
6365

64-
pool.checkout do | client |
66+
pool.checkout do |client|
6567
expect(pool.post("/post").body).to eq("post")
6668
end
6769
end
6870

6971
it "Can make multiple requests with the same client" do
70-
pool = Invidious::ConnectionPool::Pool.new(URI.parse("http://localhost:12345"), max_capacity: 100)
72+
pool = Invidious::ConnectionPool::Pool.new(max_capacity: 100) { next make_client(TEST_SERVER_URL) }
7173

72-
pool.checkout do | client |
74+
pool.checkout do |client|
7375
expect(client.get("/get").body).to eq("get")
7476
expect(client.post("/post").body).to eq("post")
7577
expect(client.get("/get").body).to eq("get")
7678
end
77-
7879
end
7980

8081
it "Allows concurrent requests" do
81-
pool = Invidious::ConnectionPool::Pool.new(URI.parse("http://localhost:12345"), max_capacity: 100)
82+
pool = Invidious::ConnectionPool::Pool.new(max_capacity: 100) { next make_client(TEST_SERVER_URL) }
8283
responses = [] of HTTP::Client::Response
8384

8485
WaitGroup.wait do |wg|
@@ -91,7 +92,7 @@ Spectator.describe Invidious::ConnectionPool do
9192
end
9293

9394
it "Raises on checkout timeout" do
94-
pool = Invidious::ConnectionPool::Pool.new(URI.parse("http://localhost:12345"), max_capacity: 2, timeout: 0.01)
95+
pool = Invidious::ConnectionPool::Pool.new(max_capacity: 2, timeout: 0.01) { next make_client(TEST_SERVER_URL) }
9596

9697
# Long running requests
9798
2.times do
@@ -103,8 +104,8 @@ Spectator.describe Invidious::ConnectionPool do
103104
expect { pool.get("/get") }.to raise_error(Invidious::ConnectionPool::Error)
104105
end
105106

106-
it "Raises when an error is encounter" do
107-
pool = Invidious::ConnectionPool::Pool.new(URI.parse("http://localhost:12345"), max_capacity: 100, timeout: 0.01)
107+
it "Raises when an error is encountered" do
108+
pool = Invidious::ConnectionPool::Pool.new(max_capacity: 100) { next make_client(TEST_SERVER_URL) }
108109
expect { pool.get("/get") { raise IO::Error.new } }.to raise_error(Invidious::ConnectionPool::Error)
109110
end
110111
end

src/invidious.cr

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -93,25 +93,32 @@ SOFTWARE = {
9393
}
9494

9595
YT_POOL = Invidious::ConnectionPool::Pool.new(
96-
YT_URL,
9796
max_capacity: CONFIG.pool_size,
9897
idle_capacity: CONFIG.idle_pool_size,
9998
timeout: CONFIG.pool_checkout_timeout
100-
)
99+
) do
100+
next make_client(YT_URL, force_resolve: true)
101+
end
101102

102103
# Image request pool
103104

105+
GGPHT_URL = URI.parse("https://yt3.ggpht.com")
106+
104107
GGPHT_POOL = Invidious::ConnectionPool::Pool.new(
105-
URI.parse("https://yt3.ggpht.com"),
106108
max_capacity: CONFIG.pool_size,
107109
idle_capacity: CONFIG.idle_pool_size,
108110
timeout: CONFIG.pool_checkout_timeout
109-
)
111+
) do
112+
next make_client(GGPHT_URL, force_resolve: true)
113+
end
110114

111-
COMPANION_POOL = Invidious::ConnectionPool::CompanionPool.new(
115+
COMPANION_POOL = Invidious::ConnectionPool::Pool.new(
112116
max_capacity: CONFIG.pool_size,
113117
idle_capacity: CONFIG.idle_pool_size
114-
)
118+
) do
119+
companion = CONFIG.invidious_companion.sample
120+
next make_client(companion.private_url, use_http_proxy: false)
121+
end
115122

116123
# CLI
117124
Kemal.config.extra_options do |parser|

src/invidious/connection/pool.cr

Lines changed: 12 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
module Invidious::ConnectionPool
2-
# The base connection pool that provides the underlying logic that all connection pools are based around
3-
#
4-
# Uses `DB::Pool` for the pooling logic
5-
abstract struct BaseConnectionPool(PoolClient)
2+
# A connection pool to reuse `HTTP::Client` connections
3+
struct Pool
4+
getter pool : DB::Pool(HTTP::Client)
5+
66
# Creates a connection pool with the provided options, and client factory block.
77
def initialize(
88
*,
99
max_capacity : Int32 = 5,
1010
idle_capacity : Int32? = nil,
1111
timeout : Float64 = 5.0,
12-
&client_factory : -> PoolClient
12+
&client_factory : -> HTTP::Client
1313
)
1414
if idle_capacity.nil?
1515
idle_capacity = max_capacity
@@ -22,12 +22,9 @@ module Invidious::ConnectionPool
2222
checkout_timeout: timeout
2323
)
2424

25-
@pool = DB::Pool(PoolClient).new(pool_options, &client_factory)
25+
@pool = DB::Pool(HTTP::Client).new(pool_options, &client_factory)
2626
end
2727

28-
# Returns the underlying `DB::Pool` object
29-
abstract def pool : DB::Pool(PoolClient)
30-
3128
{% for method in %w[get post put patch delete head options] %}
3229
# Streaming API for {{method.id.upcase}} request.
3330
# The response will have its body as an `IO` accessed via `HTTP::Client::Response#body_io`.
@@ -89,45 +86,6 @@ module Invidious::ConnectionPool
8986
end
9087
end
9188

92-
# A basic connection pool where each client within is set to connect to a single resource
93-
struct Pool < BaseConnectionPool(HTTP::Client)
94-
getter pool : DB::Pool(HTTP::Client)
95-
96-
# Creates a pool of clients that connects to the given url, with the provided options.
97-
def initialize(
98-
url : URI,
99-
*,
100-
max_capacity : Int32 = 5,
101-
idle_capacity : Int32? = nil,
102-
timeout : Float64 = 5.0,
103-
)
104-
super(max_capacity: max_capacity, idle_capacity: idle_capacity, timeout: timeout) do
105-
next make_client(url, force_resolve: true)
106-
end
107-
end
108-
end
109-
110-
# A modified connection pool for the interacting with Invidious companion.
111-
#
112-
# The main difference is that clients in this pool are created with different urls
113-
# based on what is randomly selected from the configured list of companions
114-
struct CompanionPool < BaseConnectionPool(HTTP::Client)
115-
getter pool : DB::Pool(HTTP::Client)
116-
117-
# Creates a pool of clients with the provided options.
118-
def initialize(
119-
*,
120-
max_capacity : Int32 = 5,
121-
idle_capacity : Int32? = nil,
122-
timeout : Float64 = 5.0,
123-
)
124-
super(max_capacity: max_capacity, idle_capacity: idle_capacity, timeout: timeout) do
125-
companion = CONFIG.invidious_companion.sample
126-
next make_client(companion.private_url, use_http_proxy: false)
127-
end
128-
end
129-
end
130-
13189
class Error < Exception
13290
end
13391

@@ -147,12 +105,16 @@ module Invidious::ConnectionPool
147105
return pool
148106
else
149107
LOGGER.info("ytimg_pool: Creating a new HTTP pool for \"https://#{subdomain}.ytimg.com\"")
108+
url = URI.parse("https://#{subdomain}.ytimg.com")
109+
150110
pool = ConnectionPool::Pool.new(
151-
URI.parse("https://#{subdomain}.ytimg.com"),
152111
max_capacity: CONFIG.pool_size,
153112
idle_capacity: CONFIG.idle_pool_size,
154113
timeout: CONFIG.pool_checkout_timeout
155-
)
114+
) do
115+
next make_client(url, force_resolve: true)
116+
end
117+
156118
YTIMG_POOLS[subdomain] = pool
157119

158120
return pool

0 commit comments

Comments
 (0)