TCP/TLS connection pooling for Eio
1(*---------------------------------------------------------------------------
2 Copyright (c) 2025 Anil Madhavapeddy <anil@recoil.org>. All rights reserved.
3 SPDX-License-Identifier: ISC
4 ---------------------------------------------------------------------------*)
5
6(** Configuration for connection pools *)
7
8(** {1 Logging} *)
9
10val src : Logs.Src.t
11(** Logs source for configuration operations. Configure logging with:
12 {[
13 Logs.Src.set_level Conpool.Config.src (Some Logs.Debug)
14 ]} *)
15
16(** {1 Type} *)
17
18type t
19(** Pool configuration *)
20
21(** {1 Construction} *)
22
23val make :
24 ?max_connections_per_endpoint:int ->
25 ?max_idle_time:float ->
26 ?max_connection_lifetime:float ->
27 ?max_connection_uses:int ->
28 ?health_check:([Eio.Resource.close_ty | Eio.Flow.two_way_ty] Eio.Resource.t -> bool) ->
29 ?connect_timeout:float ->
30 ?connect_retry_count:int ->
31 ?connect_retry_delay:float ->
32 ?on_connection_created:(Endpoint.t -> unit) ->
33 ?on_connection_closed:(Endpoint.t -> unit) ->
34 ?on_connection_reused:(Endpoint.t -> unit) ->
35 unit ->
36 t
37(** Create pool configuration with optional parameters.
38
39 @param max_connections_per_endpoint
40 Maximum concurrent connections per endpoint (default: 10)
41 @param max_idle_time
42 Maximum time a connection can sit idle in seconds (default: 60.0)
43 @param max_connection_lifetime
44 Maximum connection age in seconds (default: 300.0)
45 @param max_connection_uses
46 Maximum times a connection can be reused (default: unlimited)
47 @param health_check Custom health check function (default: none)
48 @param connect_timeout Connection timeout in seconds (default: 10.0)
49 @param connect_retry_count Number of connection retry attempts (default: 3)
50 @param connect_retry_delay
51 Initial retry delay in seconds, with exponential backoff (default: 0.1)
52 @param on_connection_created Hook called when a connection is created
53 @param on_connection_closed Hook called when a connection is closed
54 @param on_connection_reused Hook called when a connection is reused *)
55
56val default : t
57(** Sensible defaults for most use cases:
58 - max_connections_per_endpoint: 10
59 - max_idle_time: 60.0s
60 - max_connection_lifetime: 300.0s
61 - max_connection_uses: unlimited
62 - health_check: none
63 - connect_timeout: 10.0s
64 - connect_retry_count: 3
65 - connect_retry_delay: 0.1s
66 - hooks: none *)
67
68(** {1 Accessors} *)
69
70val max_connections_per_endpoint : t -> int
71(** Get maximum connections per endpoint. *)
72
73val max_idle_time : t -> float
74(** Get maximum idle time in seconds. *)
75
76val max_connection_lifetime : t -> float
77(** Get maximum connection lifetime in seconds. *)
78
79val max_connection_uses : t -> int option
80(** Get maximum connection uses, if any. *)
81
82val health_check :
83 t -> ([Eio.Resource.close_ty | Eio.Flow.two_way_ty] Eio.Resource.t -> bool) option
84(** Get custom health check function, if any. *)
85
86val connect_timeout : t -> float option
87(** Get connection timeout in seconds, if any. *)
88
89val connect_retry_count : t -> int
90(** Get number of connection retry attempts. *)
91
92val connect_retry_delay : t -> float
93(** Get initial retry delay in seconds. *)
94
95val on_connection_created : t -> (Endpoint.t -> unit) option
96(** Get connection created hook, if any. *)
97
98val on_connection_closed : t -> (Endpoint.t -> unit) option
99(** Get connection closed hook, if any. *)
100
101val on_connection_reused : t -> (Endpoint.t -> unit) option
102(** Get connection reused hook, if any. *)
103
104(** {1 Pretty-printing} *)
105
106val pp : t Fmt.t
107(** Pretty-printer for configuration. *)
108
109(** {1 Protocol Handler Configuration}
110
111 Protocol handlers define protocol-specific behavior for typed connection pools.
112 This enables different pooling strategies for different protocols
113 (e.g., exclusive for HTTP/1.x, shared for HTTP/2). *)
114
115(** Access mode for connections.
116 - [Exclusive] - Each connection is used by one request at a time (HTTP/1.x)
117 - [Shared n] - Up to n concurrent requests can share a connection (HTTP/2) *)
118type access_mode =
119 | Exclusive
120 (** Exclusive access - one request per connection at a time *)
121 | Shared of int
122 (** Shared access - up to n concurrent requests per connection *)
123
124(** Connection flow type for protocol handlers. *)
125type connection_flow = [Eio.Resource.close_ty | Eio.Flow.two_way_ty] Eio.Resource.t
126
127(** Protocol configuration for typed connection pools.
128 @param 'state The protocol-specific state type (e.g., H2_client.t for HTTP/2) *)
129type 'state protocol_config = {
130 init_state :
131 sw:Eio.Switch.t ->
132 flow:connection_flow ->
133 tls_epoch:Tls.Core.epoch_data option ->
134 'state;
135 (** Initialize protocol state when a new connection is created.
136 The [sw] parameter is a connection-lifetime switch that can be used
137 to spawn long-running fibers (e.g., HTTP/2 frame reader).
138 For HTTP/2, this performs the handshake and returns the H2_client.t. *)
139
140 on_acquire : 'state -> unit;
141 (** Called when a connection is acquired from the pool.
142 For HTTP/2, this can start the background reader fiber if not already running. *)
143
144 on_release : 'state -> unit;
145 (** Called when a connection is released back to the pool.
146 For HTTP/2, this is typically a no-op since the reader keeps running. *)
147
148 is_healthy : 'state -> bool;
149 (** Protocol-specific health check. Return false if connection should be closed.
150 For HTTP/2, checks if GOAWAY has been received. *)
151
152 on_close : 'state -> unit;
153 (** Cleanup callback when connection is destroyed.
154 For HTTP/2, can send GOAWAY frame. *)
155
156 access_mode : 'state -> access_mode;
157 (** Get the access mode for this connection.
158 For HTTP/2, returns [Shared n] with max_concurrent from peer settings. *)
159}