HttpDispatcher
Pennington.Infrastructure
Default IInProcessHttpDispatcher. Inspects the registered IServer and returns an in-memory client when it's a TestServer, or a socket-bound client pointing at Kestrel's listening address otherwise.
The handler chain is built once and shared by every client this dispatcher hands out — clients are cheap wrappers created with disposeHandler: false, so a caller's using releases the wrapper without tearing down the connection pool. This matters on the Kestrel path: SiteProjection issues one fetch per page, and a per-fetch handler cannot pool, so every fetch opened a fresh loopback socket that then sat in TIME_WAIT. A corpus larger than the ~16k Windows ephemeral port range exhausted it partway through and the remaining fetches failed with SocketError.AddressAlreadyInUse — silently dropping those pages from the search index and llms.txt, since RenderOneAsync treats a failed fetch as a per-page error.
Constructors
HttpDispatcher
#public HttpDispatcher(IServer server, BuildHtmlCache cache)
Initializes the dispatcher with the host's registered IServer and the shared render cache.
Parameters
serverIServercacheBuildHtmlCache
Methods
Pennington.Infrastructure.HttpDispatcher
namespace Pennington.Infrastructure;
/// Default IInProcessHttpDispatcher. Inspects the registered IServer and returns an in-memory client when it's a TestServer, or a socket-bound client pointing at Kestrel's listening address otherwise. The handler chain is built once and shared by every client this dispatcher hands out — clients are cheap wrappers created with disposeHandler: false, so a caller's using releases the wrapper without tearing down the connection pool. This matters on the Kestrel path: SiteProjection issues one fetch per page, and a per-fetch handler cannot pool, so every fetch opened a fresh loopback socket that then sat in TIME_WAIT. A corpus larger than the ~16k Windows ephemeral port range exhausted it partway through and the remaining fetches failed with SocketError.AddressAlreadyInUse — silently dropping those pages from the search index and llms.txt, since RenderOneAsync treats a failed fetch as a per-page error.
public class HttpDispatcher
{
/// Returns an HttpClient whose requests flow through the running app's pipeline.
public HttpClient CreateClient()
;
/// Disposes the shared handler chain and its pooled connections.
public void Dispose()
;
/// Initializes the dispatcher with the host's registered IServer and the shared render cache.
public HttpDispatcher(IServer server, BuildHtmlCache cache)
;
}