Monorepo for Tangled
0

Configure Feed

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

spindle/config: add role selector and mill settings

dawn (Jul 13, 2026, 4:21 PM +0300) 87f6bde0 208e4d31

+42
+42
spindle/config/config.go
··· 2 2 3 3 import ( 4 4 "context" 5 + "fmt" 5 6 "time" 6 7 7 8 "github.com/bluesky-social/indigo/atproto/syntax" ··· 93 94 UploadURL string `env:"UPLOAD_URL"` 94 95 } 95 96 97 + // Role selects the spindle mode. set explicitly via SPINDLE_ROLE. 98 + type Role string 99 + 100 + const ( 101 + RoleStandalone Role = "standalone" 102 + RoleMill Role = "mill" 103 + RoleExecutor Role = "executor" 104 + ) 105 + 106 + // Mill config is shared by all roles; which fields matter depends on Role. 107 + type Mill struct { 108 + URL string `env:"URL"` // mill websocket endpoint (executor) 109 + SharedSecret string `env:"SHARED_SECRET"` // executor bearer token; mill dev bootstrap seed 110 + MaxPending int `env:"MAX_PENDING, default=100"` // mill: pending job cap 111 + ReconnectGrace time.Duration `env:"RECONNECT_GRACE, default=45s"` // mill: reconnect window before failing leases 112 + Seats int `env:"SEATS, default=4"` // executor: seat count advertised to the mill 113 + Labels []string `env:"LABELS"` // executor: runs_on labels 114 + } 115 + 96 116 type Config struct { 117 + Role Role `env:"SPINDLE_ROLE, default=standalone"` 97 118 Server Server `env:",prefix=SPINDLE_SERVER_"` 98 119 NixeryPipelines NixeryPipelines `env:",prefix=SPINDLE_NIXERY_PIPELINES_"` 99 120 MicroVMPipelines MicroVMPipelines `env:",prefix=SPINDLE_MICROVM_PIPELINES_"` 100 121 NixCache NixCache `env:",prefix=SPINDLE_NIX_CACHE_"` 101 122 S3 S3 `env:",prefix=SPINDLE_S3_"` 123 + Mill Mill `env:",prefix=SPINDLE_MILL_"` 124 + } 125 + 126 + // validate fails fast on bad role config. 127 + func (c *Config) validate() error { 128 + switch c.Role { 129 + case RoleStandalone, RoleMill: 130 + if c.Mill.URL != "" { 131 + return fmt.Errorf("SPINDLE_MILL_URL is set but SPINDLE_ROLE=%s; only an executor dials a mill", c.Role) 132 + } 133 + case RoleExecutor: 134 + if c.Mill.URL == "" { 135 + return fmt.Errorf("SPINDLE_ROLE=executor requires SPINDLE_MILL_URL (the mill to dial)") 136 + } 137 + default: 138 + return fmt.Errorf("unknown SPINDLE_ROLE %q (want standalone, mill, or executor)", c.Role) 139 + } 140 + return nil 102 141 } 103 142 104 143 func Load(ctx context.Context) (*Config, error) { 105 144 var cfg Config 106 145 err := envconfig.Process(ctx, &cfg) 107 146 if err != nil { 147 + return nil, err 148 + } 149 + if err := cfg.validate(); err != nil { 108 150 return nil, err 109 151 } 110 152