@@ -472,6 +472,60 @@ fn handle_connection[
472472 break
473473
474474
475+ struct SyncExecutor[T: HTTPService](Movable):
476+ """ Single-threaded executor: handles each connection to completion before accepting the next.
477+
478+ This is the default executor used by `Server.serve`. It processes connections
479+ sequentially — receive, parse, dispatch to handler, respond — then loops back
480+ to accept the next connection.
481+
482+ Parameters:
483+ T: The HTTP service type that handles incoming requests.
484+ """
485+
486+ var provision_pool : ProvisionPool
487+ var config : ServerConfig
488+ var server_address : String
489+ var tcp_keep_alive : Bool
490+
491+ fn __init__ (out self , config : ServerConfig, server_address : String, tcp_keep_alive : Bool):
492+ self .provision_pool = ProvisionPool(config.max_connections, config)
493+ self .config = config.copy()
494+ self .server_address = server_address
495+ self .tcp_keep_alive = tcp_keep_alive
496+
497+ fn execute (mut self , var conn : TCPConnection[NetworkType.tcp4], mut handler : Self.T):
498+ var index : Int
499+ try :
500+ index = self .provision_pool.borrow()
501+ except :
502+ try :
503+ conn^ .teardown()
504+ except :
505+ pass
506+ return
507+
508+ try :
509+ handle_connection(
510+ conn,
511+ self .provision_pool.provisions[index],
512+ handler,
513+ self .config,
514+ self .server_address,
515+ self .tcp_keep_alive,
516+ )
517+ except :
518+ pass
519+ finally :
520+ try :
521+ conn^ .teardown()
522+ except :
523+ pass
524+ self .provision_pool.provisions[index].prepare_for_new_request()
525+ self .provision_pool.provisions[index].keepalive_count = 0
526+ self .provision_pool.release(index)
527+
528+
475529struct Server (Movable ):
476530 """ HTTP/1.1 Server implementation."""
477531
@@ -543,7 +597,7 @@ struct Server(Movable):
543597 raise server_err^
544598
545599 fn serve [T : HTTPService](self , ln : NoTLSListener[NetworkType.tcp4], mut handler : T) raises ServerError :
546- """ Serve HTTP requests from an existing listener.
600+ """ Serve HTTP requests from an existing listener using the default single-threaded executor .
547601
548602 Parameters:
549603 T: The type of HTTPService that handles incoming requests.
@@ -555,46 +609,34 @@ struct Server(Movable):
555609 Raises:
556610 ServerError: If accept fails or critical connection handling errors occur.
557611 """
558- var provision_pool = ProvisionPool(self .config.max_connections, self .config)
612+ var executor = SyncExecutor[T](self .config, self ._address, self .tcp_keep_alive)
613+ self .serve_with_executor(ln, handler, executor)
614+
615+ fn serve_with_executor [
616+ T : HTTPService,
617+ ](self , ln : NoTLSListener[NetworkType.tcp4], mut handler : T, mut executor : SyncExecutor[T]) raises ServerError :
618+ """ Serve HTTP requests using a custom executor for connection dispatch.
559619
620+ Use this method to provide a custom execution model such as a thread pool
621+ or async runtime for handling connections concurrently.
622+
623+ Parameters:
624+ T: The type of HTTPService that handles incoming requests.
625+ Args:
626+ ln: TCP server that listens for incoming connections.
627+ handler: An object that handles incoming HTTP requests.
628+ executor: The executor that dispatches each accepted connection.
629+
630+ Raises:
631+ ServerError: If accept fails or critical connection handling errors occur.
632+ """
560633 while True :
561634 var conn : TCPConnection[NetworkType.tcp4]
562635 try :
563636 conn = ln.accept()
564637 except listener_err:
565638 raise listener_err^
566-
567- var index : Int
568- try :
569- index = provision_pool.borrow()
570- except provision_err:
571- # Pool exhausted - close the connection and continue
572- try :
573- conn^ .teardown()
574- except :
575- pass
576- continue
577-
578- try :
579- handle_connection(
580- conn,
581- provision_pool.provisions[index],
582- handler,
583- self .config,
584- self .address(),
585- self .tcp_keep_alive,
586- )
587- except socket_err:
588- # Connection handling failed - just close the connection
589- pass
590- finally :
591- try :
592- conn^ .teardown()
593- except :
594- pass
595- provision_pool.provisions[index].prepare_for_new_request()
596- provision_pool.provisions[index].keepalive_count = 0
597- provision_pool.release(index)
639+ executor.execute(conn^ , handler)
598640
599641
600642fn _send_error_response (mut conn : TCPConnection[NetworkType.tcp4], var response : HTTPResponse):
0 commit comments