From 137f49d1d1ac0f67425ade2f30c364de3759e6de Mon Sep 17 00:00:00 2001 From: Eric Coissac Date: Mon, 13 Apr 2026 16:27:01 +0200 Subject: [PATCH] :wrench: refactor(http): use thread-safe lazy-initialized HTTP client with connection pooling - Replace global _httpClient variable by a sync.Once-based lazy initialization - Add getHTTPClient() function to safely initialize client with connection pooling settings (MaxIdleConnsPerHost, Max Con ns/Conn per host) - Set connection pool size based on obidefault.ParallelWorkers() This ensures safe concurrent access and better resource management in multi-threaded Lua environments. --- pkg/obilua/luahttp.go | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/pkg/obilua/luahttp.go b/pkg/obilua/luahttp.go index 07d80e6..6120ae3 100644 --- a/pkg/obilua/luahttp.go +++ b/pkg/obilua/luahttp.go @@ -4,15 +4,33 @@ import ( "io" "net/http" "strings" + "sync" "time" + "git.metabarcoding.org/obitools/obitools4/obitools4/pkg/obidefault" lua "github.com/yuin/gopher-lua" ) const httpClientTimeout = 30 * time.Second -var _httpClient = &http.Client{ - Timeout: httpClientTimeout, +var ( + _httpClient *http.Client + _httpClientOnce sync.Once +) + +func getHTTPClient() *http.Client { + _httpClientOnce.Do(func() { + conns := 2 * obidefault.ParallelWorkers() + _httpClient = &http.Client{ + Transport: &http.Transport{ + MaxIdleConnsPerHost: conns, + MaxConnsPerHost: conns, + IdleConnTimeout: 90 * time.Second, + }, + Timeout: httpClientTimeout, + } + }) + return _httpClient } // RegisterHTTP registers the http module in the Lua state as a global, @@ -46,7 +64,7 @@ func luaHTTPPost(L *lua.LState) int { } req.Header.Set("Content-Type", "application/json") - resp, err := _httpClient.Do(req) + resp, err := getHTTPClient().Do(req) if err != nil { L.Push(lua.LNil) L.Push(lua.LString(err.Error()))