···20202121let run env =
2222 Switch.run (fun sw ->
2323- (* Create a connection pool *)
2424- let pool = Conpool.create
2323+ (* Create a basic connection pool (no protocol state) *)
2424+ let pool = Conpool.create_basic
2525 ~sw
2626 ~net:(Eio.Stdenv.net env)
2727 ~clock:(Eio.Stdenv.clock env)
···4949 let tls_config = Tls.Config.client ~authenticator:(Ca_certs.authenticator ()) () in
50505151 (* Create pool with TLS *)
5252- let pool = Conpool.create
5252+ let pool = Conpool.create_basic
5353 ~sw
5454 ~net:(Eio.Stdenv.net env)
5555 ~clock:(Eio.Stdenv.clock env)
···7676 ()
7777in
78787979-let pool = Conpool.create ~sw ~net ~clock ~config ()
7979+let pool = Conpool.create_basic ~sw ~net ~clock ~config ()
8080```
81818282Monitor pool statistics:
+22-18
lib/conpool.ml
···248248 let conn_cancel_ref = ref (fun (_ : exn) -> ()) in
249249 let ready_promise, ready_resolver = Eio.Promise.create () in
250250251251- Eio.Fiber.fork ~sw:pool.sw (fun () ->
252252- Eio.Switch.run (fun conn_sw ->
253253- conn_sw_ref := Some conn_sw;
254254- (conn_cancel_ref := fun exn -> Eio.Switch.fail conn_sw exn);
255255- (* Signal that the switch is ready *)
256256- Eio.Promise.resolve ready_resolver ();
257257- (* Block until the switch is cancelled *)
258258- let wait_forever, _never_resolved = Eio.Promise.create () in
259259- Eio.Promise.await wait_forever));
251251+ (* Use fork_daemon so connection fibers don't prevent parent switch from completing.
252252+ When the parent switch completes, all connection daemon fibers are cancelled,
253253+ which triggers cleanup of their inner switches and connection resources. *)
254254+ Eio.Fiber.fork_daemon ~sw:pool.sw (fun () ->
255255+ (try
256256+ Eio.Switch.run (fun conn_sw ->
257257+ conn_sw_ref := Some conn_sw;
258258+ (conn_cancel_ref := fun exn -> Eio.Switch.fail conn_sw exn);
259259+ (* Signal that the switch is ready *)
260260+ Eio.Promise.resolve ready_resolver ();
261261+ (* Block until the switch is cancelled *)
262262+ Eio.Fiber.await_cancel ())
263263+ with
264264+ | Eio.Cancel.Cancelled _ -> ()
265265+ | exn ->
266266+ Log.warn (fun m ->
267267+ m "Connection fiber caught exception: %s" (Printexc.to_string exn)));
268268+ `Stop_daemon);
260269261270 (* Wait for the switch to be created *)
262271 Eio.Promise.await ready_promise;
···584593(** {1 Public API} *)
585594586595let create ~sw ~(net : 'net Eio.Net.t) ~(clock : 'clock Eio.Time.clock) ?tls
587587- ?(config = Config.default) ?protocol () =
588588- let protocol =
589589- match protocol with
590590- | Some p -> p
591591- | None ->
592592- Obj.magic
593593- default_protocol (* Safe: unit is compatible with any 'state *)
594594- in
595595-596596+ ?(config = Config.default) ~protocol () =
596597 Log.info (fun m ->
597598 m "Creating connection pool (max_per_endpoint=%d)"
598599 (Config.max_connections_per_endpoint config));
···623624 Hashtbl.clear pool.endpoints));
624625625626 Pool pool
627627+628628+let create_basic ~sw ~net ~clock ?tls ?config () =
629629+ create ~sw ~net ~clock ?tls ?config ~protocol:default_protocol ()
626630627631let connection ~sw (Pool pool) endpoint =
628632 Log.debug (fun m -> m "Acquiring connection to %a" Endpoint.pp endpoint);
+35-7
lib/conpool.mli
···13131414 For simple exclusive-access protocols (HTTP/1.x, Redis, etc.):
1515 {[
1616- let pool = Conpool.create ~sw ~net ~clock ~tls () in
1616+ let pool = Conpool.create_basic ~sw ~net ~clock ~tls () in
1717 Eio.Switch.run (fun conn_sw ->
1818 let conn = Conpool.connection ~sw:conn_sw pool endpoint in
1919 (* Use conn.flow for I/O *)
···105105106106(** {2 Pool Creation} *)
107107108108+val default_protocol : unit Config.protocol_config
109109+(** Default protocol configuration for simple exclusive-access protocols. Use
110110+ with {!create} for HTTP/1.x, Redis, and similar protocols where each
111111+ connection handles one request at a time with no extra state. *)
112112+108113val create :
109114 sw:Eio.Switch.t ->
110115 net:'net Eio.Net.t ->
111116 clock:'clock Eio.Time.clock ->
112117 ?tls:Tls.Config.client ->
113118 ?config:Config.t ->
114114- ?protocol:'state Config.protocol_config ->
119119+ protocol:'state Config.protocol_config ->
115120 unit ->
116121 'state t
117117-(** Create a connection pool.
122122+(** Create a connection pool with a protocol handler.
118123119124 @param sw Switch for resource management
120125 @param net Network interface for creating connections
121126 @param clock Clock for timeouts
122127 @param tls Optional TLS client configuration
123128 @param config Pool configuration (uses {!Config.default} if not provided)
124124- @param protocol
125125- Protocol handler for state management. If not provided, creates a [unit t]
126126- pool with exclusive access mode (one user per connection).
129129+ @param protocol Protocol handler for state management
127130128131 Examples:
129132130133 Simple pool for HTTP/1.x (exclusive access, no state):
131134 {[
132132- let pool = Conpool.create ~sw ~net ~clock ~tls ()
135135+ let pool =
136136+ Conpool.create ~sw ~net ~clock ~tls ~protocol:Conpool.default_protocol
137137+ ()
133138 ]}
134139135140 HTTP/2 pool (shared access with H2 state):
136141 {[
137142 let pool = Conpool.create ~sw ~net ~clock ~tls ~protocol:h2_handler ()
143143+ ]} *)
144144+145145+val create_basic :
146146+ sw:Eio.Switch.t ->
147147+ net:'net Eio.Net.t ->
148148+ clock:'clock Eio.Time.clock ->
149149+ ?tls:Tls.Config.client ->
150150+ ?config:Config.t ->
151151+ unit ->
152152+ unit t
153153+(** Create a basic connection pool with no protocol state.
154154+155155+ This is a convenience function equivalent to:
156156+ {[
157157+ Conpool.create ~sw ~net ~clock ?tls ?config
158158+ ~protocol:Conpool.default_protocol ()
159159+ ]}
160160+161161+ Use for simple exclusive-access protocols like HTTP/1.x and Redis.
162162+163163+ Example:
164164+ {[
165165+ let pool = Conpool.create_basic ~sw ~net ~clock ~tls ()
138166 ]} *)
139167140168(** {2 Connection Acquisition} *)
+1-1
test/stress_test.ml
···278278 ~connect_retry_count:3 ()
279279 in
280280281281- let pool = Conpool.create ~sw ~net ~clock ~config:pool_config () in
281281+ let pool = Conpool.create_basic ~sw ~net ~clock ~config:pool_config () in
282282283283 (* Record start time *)
284284 let start_time = Eio.Time.now clock in