Monorepo for Tangled
0

Configure Feed

Select the types of activity you want to include in your feed.

spindle/engines/nixery: make engine fully lazy

Signed-off-by: dawn <dawn@tangled.org>

authored by

dawn and committed by
Tangled
(Jul 17, 2026, 12:51 PM +0300) f217a2f5 59fbe4c4

+49 -9
+24 -9
spindle/engines/nixery/engine.go
··· 35 35 type cleanupFunc func(context.Context) error 36 36 37 37 type Engine struct { 38 - docker client.APIClient 39 - l *slog.Logger 40 - cfg *config.Config 38 + dockerMu sync.Mutex 39 + docker client.APIClient 40 + l *slog.Logger 41 + cfg *config.Config 41 42 42 43 slotter engine.WorkflowSlotter 43 44 ··· 164 165 } 165 166 166 167 func New(ctx context.Context, cfg *config.Config) (*Engine, error) { 167 - dcli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation()) 168 - if err != nil { 169 - return nil, err 170 - } 171 - 172 168 l := log.FromContext(ctx).With("component", "spindle") 173 169 174 170 e := &Engine{ 175 - docker: dcli, 176 171 l: l, 177 172 cfg: cfg, 178 173 slotter: engine.NewSemaphoreSlotter(cfg.NixeryPipelines.MaxConcurrentWorkflows), ··· 181 176 e.cleanup = make(map[string][]cleanupFunc) 182 177 183 178 return e, nil 179 + } 180 + 181 + func (e *Engine) ensureDocker() (client.APIClient, error) { 182 + e.dockerMu.Lock() 183 + defer e.dockerMu.Unlock() 184 + 185 + if e.docker != nil { 186 + return e.docker, nil 187 + } 188 + 189 + dcli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation()) 190 + if err != nil { 191 + return nil, err 192 + } 193 + e.docker = dcli 194 + return dcli, nil 184 195 } 185 196 186 197 func (e *Engine) AcquireWorkflowSlot( ··· 214 225 err = fmt.Errorf("Failed to setup container:\n%w", err) 215 226 } 216 227 }() 228 + 229 + if _, err := e.ensureDocker(); err != nil { 230 + return err 231 + } 217 232 218 233 /// -------------------------NETWORK CREATION--------------------------------------- 219 234 _, err = e.docker.NetworkCreate(ctx, networkName(wid), network.CreateOptions{
+25
spindle/engines/nixery/engine_test.go
··· 1 + package nixery 2 + 3 + import ( 4 + "context" 5 + "testing" 6 + 7 + "tangled.org/core/spindle/config" 8 + ) 9 + 10 + func TestNewDefersDockerClientUntilWorkflowSetup(t *testing.T) { 11 + t.Setenv("DOCKER_HOST", "tcp://127.0.0.1:2376") 12 + t.Setenv("DOCKER_TLS_VERIFY", "1") 13 + t.Setenv("DOCKER_CERT_PATH", t.TempDir()) 14 + 15 + e, err := New(context.Background(), &config.Config{}) 16 + if err != nil { 17 + t.Fatal(err) 18 + } 19 + if e.docker != nil { 20 + t.Fatal("docker client initialized during engine initialization") 21 + } 22 + if _, err := e.ensureDocker(); err == nil { 23 + t.Fatal("expected incomplete Docker TLS configuration to fail when first used") 24 + } 25 + }