Skip to content

Commit 6b9e1e8

Browse files
committed
Feature flag factory accessible from outside of the module
1 parent 9c3b7c5 commit 6b9e1e8

1 file changed

Lines changed: 57 additions & 57 deletions

File tree

  • packages/shared/pkg/featureflags

packages/shared/pkg/featureflags/flags.go

Lines changed: 57 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -50,15 +50,15 @@ func (f JSONFlag) Fallback() ldvalue.Value {
5050
return f.fallback
5151
}
5252

53-
func newJSONFlag(name string, fallback ldvalue.Value) JSONFlag {
53+
func NewJSONFlag(name string, fallback ldvalue.Value) JSONFlag {
5454
flag := JSONFlag{name: name, fallback: fallback}
5555
builder := launchDarklyOfflineStore.Flag(flag.name).ValueForAll(fallback)
5656
launchDarklyOfflineStore.Update(builder)
5757

5858
return flag
5959
}
6060

61-
var CleanNFSCache = newJSONFlag("clean-nfs-cache", ldvalue.Null())
61+
var CleanNFSCache = NewJSONFlag("clean-nfs-cache", ldvalue.Null())
6262

6363
// RateLimitConfigFlag provides per-team rate limit overrides.
6464
// JSON format:
@@ -69,7 +69,7 @@ var CleanNFSCache = newJSONFlag("clean-nfs-cache", ldvalue.Null())
6969
// }
7070
//
7171
// When non-null, values override the code defaults. Target specific teams in LaunchDarkly.
72-
var RateLimitConfigFlag = newJSONFlag("rate-limit-config", ldvalue.Null())
72+
var RateLimitConfigFlag = NewJSONFlag("rate-limit-config", ldvalue.Null())
7373

7474
type BoolFlag struct {
7575
name string
@@ -88,7 +88,7 @@ func (f BoolFlag) Fallback() bool {
8888
return f.fallback
8989
}
9090

91-
func newBoolFlag(name string, fallback bool) BoolFlag {
91+
func NewBoolFlag(name string, fallback bool) BoolFlag {
9292
flag := BoolFlag{name: name, fallback: fallback}
9393
builder := launchDarklyOfflineStore.Flag(flag.name).VariationForAll(fallback)
9494
launchDarklyOfflineStore.Update(builder)
@@ -97,28 +97,28 @@ func newBoolFlag(name string, fallback bool) BoolFlag {
9797
}
9898

9999
var (
100-
MetricsWriteFlag = newBoolFlag("sandbox-metrics-write", true)
101-
MetricsReadFlag = newBoolFlag("sandbox-metrics-read", true)
102-
SnapshotFeatureFlag = newBoolFlag("use-nfs-for-snapshots", env.IsDevelopment())
103-
TemplateFeatureFlag = newBoolFlag("use-nfs-for-templates", env.IsDevelopment())
104-
EnableWriteThroughCacheFlag = newBoolFlag("write-to-cache-on-writes", false)
105-
UseNFSCacheForBuildingTemplatesFlag = newBoolFlag("use-nfs-for-building-templates", env.IsDevelopment())
106-
BestOfKCanFitFlag = newBoolFlag("best-of-k-can-fit", true)
107-
BestOfKTooManyStartingFlag = newBoolFlag("best-of-k-too-many-starting", false)
108-
EdgeProvidedSandboxMetricsFlag = newBoolFlag("edge-provided-sandbox-metrics", false)
109-
CreateStorageCacheSpansFlag = newBoolFlag("create-storage-cache-spans", env.IsDevelopment())
110-
SandboxAutoResumeFlag = newBoolFlag("sandbox-auto-resume", env.IsDevelopment())
100+
MetricsWriteFlag = NewBoolFlag("sandbox-metrics-write", true)
101+
MetricsReadFlag = NewBoolFlag("sandbox-metrics-read", true)
102+
SnapshotFeatureFlag = NewBoolFlag("use-nfs-for-snapshots", env.IsDevelopment())
103+
TemplateFeatureFlag = NewBoolFlag("use-nfs-for-templates", env.IsDevelopment())
104+
EnableWriteThroughCacheFlag = NewBoolFlag("write-to-cache-on-writes", false)
105+
UseNFSCacheForBuildingTemplatesFlag = NewBoolFlag("use-nfs-for-building-templates", env.IsDevelopment())
106+
BestOfKCanFitFlag = NewBoolFlag("best-of-k-can-fit", true)
107+
BestOfKTooManyStartingFlag = NewBoolFlag("best-of-k-too-many-starting", false)
108+
EdgeProvidedSandboxMetricsFlag = NewBoolFlag("edge-provided-sandbox-metrics", false)
109+
CreateStorageCacheSpansFlag = NewBoolFlag("create-storage-cache-spans", env.IsDevelopment())
110+
SandboxAutoResumeFlag = NewBoolFlag("sandbox-auto-resume", env.IsDevelopment())
111111

112112
// PeerToPeerChunkTransferFlag enables peer-to-peer chunk routing.
113-
PeerToPeerChunkTransferFlag = newBoolFlag("peer-to-peer-chunk-transfer", false)
113+
PeerToPeerChunkTransferFlag = NewBoolFlag("peer-to-peer-chunk-transfer", false)
114114
// PeerToPeerAsyncCheckpointFlag makes Checkpoint upload fire-and-forget instead
115115
// of synchronous. Only safe to enable after PeerToPeerChunkTransferFlag is ON.
116-
PeerToPeerAsyncCheckpointFlag = newBoolFlag("peer-to-peer-async-checkpoint", false)
116+
PeerToPeerAsyncCheckpointFlag = NewBoolFlag("peer-to-peer-async-checkpoint", false)
117117

118-
PersistentVolumesFlag = newBoolFlag("can-use-persistent-volumes", env.IsDevelopment())
119-
ExecutionMetricsOnWebhooksFlag = newBoolFlag("execution-metrics-on-webhooks", false) // TODO: Remove NLT 20250315
120-
SandboxLabelBasedSchedulingFlag = newBoolFlag("sandbox-label-based-scheduling", false)
121-
OptimisticResourceAccountingFlag = newBoolFlag("sandbox-placement-optimistic-resource-accounting", false)
118+
PersistentVolumesFlag = NewBoolFlag("can-use-persistent-volumes", env.IsDevelopment())
119+
ExecutionMetricsOnWebhooksFlag = NewBoolFlag("execution-metrics-on-webhooks", false) // TODO: Remove NLT 20250315
120+
SandboxLabelBasedSchedulingFlag = NewBoolFlag("sandbox-label-based-scheduling", false)
121+
OptimisticResourceAccountingFlag = NewBoolFlag("sandbox-placement-optimistic-resource-accounting", false)
122122
)
123123

124124
type IntFlag struct {
@@ -138,7 +138,7 @@ func (f IntFlag) Fallback() int {
138138
return f.fallback
139139
}
140140

141-
func newIntFlag(name string, fallback int) IntFlag {
141+
func NewIntFlag(name string, fallback int) IntFlag {
142142
flag := IntFlag{name: name, fallback: fallback}
143143
builder := launchDarklyOfflineStore.Flag(flag.name).ValueForAll(ldvalue.Int(fallback))
144144
launchDarklyOfflineStore.Update(builder)
@@ -147,63 +147,63 @@ func newIntFlag(name string, fallback int) IntFlag {
147147
}
148148

149149
var (
150-
MaxSandboxesPerNode = newIntFlag("max-sandboxes-per-node", 200)
151-
GcloudConcurrentUploadLimit = newIntFlag("gcloud-concurrent-upload-limit", 8)
152-
GcloudMaxTasks = newIntFlag("gcloud-max-tasks", 16)
153-
ClickhouseBatcherMaxBatchSize = newIntFlag("clickhouse-batcher-max-batch-size", 100)
154-
ClickhouseBatcherMaxDelay = newIntFlag("clickhouse-batcher-max-delay", 1000) // 1s in milliseconds
155-
ClickhouseBatcherQueueSize = newIntFlag("clickhouse-batcher-queue-size", 1000)
156-
BestOfKSampleSize = newIntFlag("best-of-k-sample-size", 3) // Default K=3
157-
BestOfKMaxOvercommit = newIntFlag("best-of-k-max-overcommit", 400) // Default R=4 (stored as percentage, max over-commit ratio)
158-
BestOfKAlpha = newIntFlag("best-of-k-alpha", 50) // Default Alpha=0.5 (stored as percentage for int flag, current usage weight)
159-
EnvdInitTimeoutMilliseconds = newIntFlag("envd-init-request-timeout-milliseconds", 50) // Timeout for envd init request in milliseconds
160-
HostStatsSamplingInterval = newIntFlag("host-stats-sampling-interval", 5000) // Host stats sampling interval in milliseconds (default 5s)
161-
MaxCacheWriterConcurrencyFlag = newIntFlag("max-cache-writer-concurrency", 10)
150+
MaxSandboxesPerNode = NewIntFlag("max-sandboxes-per-node", 200)
151+
GcloudConcurrentUploadLimit = NewIntFlag("gcloud-concurrent-upload-limit", 8)
152+
GcloudMaxTasks = NewIntFlag("gcloud-max-tasks", 16)
153+
ClickhouseBatcherMaxBatchSize = NewIntFlag("clickhouse-batcher-max-batch-size", 100)
154+
ClickhouseBatcherMaxDelay = NewIntFlag("clickhouse-batcher-max-delay", 1000) // 1s in milliseconds
155+
ClickhouseBatcherQueueSize = NewIntFlag("clickhouse-batcher-queue-size", 1000)
156+
BestOfKSampleSize = NewIntFlag("best-of-k-sample-size", 3) // Default K=3
157+
BestOfKMaxOvercommit = NewIntFlag("best-of-k-max-overcommit", 400) // Default R=4 (stored as percentage, max over-commit ratio)
158+
BestOfKAlpha = NewIntFlag("best-of-k-alpha", 50) // Default Alpha=0.5 (stored as percentage for int flag, current usage weight)
159+
EnvdInitTimeoutMilliseconds = NewIntFlag("envd-init-request-timeout-milliseconds", 50) // Timeout for envd init request in milliseconds
160+
HostStatsSamplingInterval = NewIntFlag("host-stats-sampling-interval", 5000) // Host stats sampling interval in milliseconds (default 5s)
161+
MaxCacheWriterConcurrencyFlag = NewIntFlag("max-cache-writer-concurrency", 10)
162162

163163
// BuildCacheMaxUsagePercentage the maximum percentage of the cache disk storage
164164
// that can be used before the cache starts evicting items.
165-
BuildCacheMaxUsagePercentage = newIntFlag("build-cache-max-usage-percentage", 85)
166-
BuildProvisionVersion = newIntFlag("build-provision-version", 0)
165+
BuildCacheMaxUsagePercentage = NewIntFlag("build-cache-max-usage-percentage", 85)
166+
BuildProvisionVersion = NewIntFlag("build-provision-version", 0)
167167

168168
// NBDConnectionsPerDevice the number of NBD socket connections per device
169-
NBDConnectionsPerDevice = newIntFlag("nbd-connections-per-device", 1)
169+
NBDConnectionsPerDevice = NewIntFlag("nbd-connections-per-device", 1)
170170

171171
// MemoryPrefetchMaxFetchWorkers is the maximum number of parallel fetch workers per sandbox for memory prefetching.
172172
// Fetching is I/O bound so we can have more parallelism.
173-
MemoryPrefetchMaxFetchWorkers = newIntFlag("memory-prefetch-max-fetch-workers", 16)
173+
MemoryPrefetchMaxFetchWorkers = NewIntFlag("memory-prefetch-max-fetch-workers", 16)
174174

175175
// MemoryPrefetchMaxCopyWorkers is the maximum number of parallel copy workers per sandbox for memory prefetching.
176176
// Copy uses uffd syscalls, so we limit parallelism to avoid overwhelming the system.
177-
MemoryPrefetchMaxCopyWorkers = newIntFlag("memory-prefetch-max-copy-workers", 8)
177+
MemoryPrefetchMaxCopyWorkers = NewIntFlag("memory-prefetch-max-copy-workers", 8)
178178

179179
// TCPFirewallMaxConnectionsPerSandbox is the maximum number of concurrent TCP firewall
180180
// connections allowed per sandbox. Negative means no limit.
181-
TCPFirewallMaxConnectionsPerSandbox = newIntFlag("tcpfirewall-max-connections-per-sandbox", -1)
181+
TCPFirewallMaxConnectionsPerSandbox = NewIntFlag("tcpfirewall-max-connections-per-sandbox", -1)
182182

183183
// SandboxMaxIncomingConnections is the maximum number of concurrent HTTP proxy
184184
// connections allowed per sandbox. Negative means no limit.
185-
SandboxMaxIncomingConnections = newIntFlag("sandbox-max-incoming-connections", -1)
185+
SandboxMaxIncomingConnections = NewIntFlag("sandbox-max-incoming-connections", -1)
186186

187187
// BuildBaseRootfsSizeLimitMB is the maximum size of the base rootfs filesystem created from the OCI image, in MB.
188-
BuildBaseRootfsSizeLimitMB = newIntFlag("build-base-rootfs-size-limit-mb", 25000)
188+
BuildBaseRootfsSizeLimitMB = NewIntFlag("build-base-rootfs-size-limit-mb", 25000)
189189

190190
// MinAutoResumeTimeoutSeconds is the minimum auto-resume timeout in seconds.
191191
// This prevents thrashing from very short timeouts.
192-
MinAutoResumeTimeoutSeconds = newIntFlag("minimum-autoresume-timeout", 300)
192+
MinAutoResumeTimeoutSeconds = NewIntFlag("minimum-autoresume-timeout", 300)
193193

194194
// BuildReservedDiskSpaceMB is the amount of disk space in MB reserved for root on the guest filesystem.
195195
// Reserved blocks are only usable by root (uid 0), protecting the guest OS from disk-full conditions.
196-
BuildReservedDiskSpaceMB = newIntFlag("build-reserved-disk-space-mb", 0)
196+
BuildReservedDiskSpaceMB = NewIntFlag("build-reserved-disk-space-mb", 0)
197197

198198
// MaxConcurrentSnapshotUpserts limits concurrent UpsertSnapshot calls (pause + snapshot template paths).
199199
// 0 or negative disables throttling (unlimited concurrency).
200-
MaxConcurrentSnapshotUpserts = newIntFlag("max-concurrent-snapshot-upserts", 0)
200+
MaxConcurrentSnapshotUpserts = NewIntFlag("max-concurrent-snapshot-upserts", 0)
201201
// MaxConcurrentSandboxListQueries limits concurrent GetSnapshotsWithCursor calls in the sandbox list path.
202202
// 0 or negative disables throttling (unlimited concurrency).
203-
MaxConcurrentSandboxListQueries = newIntFlag("max-concurrent-sandbox-list-queries", 0)
203+
MaxConcurrentSandboxListQueries = NewIntFlag("max-concurrent-sandbox-list-queries", 0)
204204
// MaxConcurrentSnapshotBuildQueries limits concurrent GetSnapshotBuilds calls (e.g. sandbox delete).
205205
// 0 or negative disables throttling (unlimited concurrency).
206-
MaxConcurrentSnapshotBuildQueries = newIntFlag("max-concurrent-snapshot-build-queries", 0)
206+
MaxConcurrentSnapshotBuildQueries = NewIntFlag("max-concurrent-snapshot-build-queries", 0)
207207
)
208208

209209
type StringFlag struct {
@@ -223,7 +223,7 @@ func (f StringFlag) Fallback() string {
223223
return f.fallback
224224
}
225225

226-
func newStringFlag(name string, fallback string) StringFlag {
226+
func NewStringFlag(name string, fallback string) StringFlag {
227227
flag := StringFlag{name: name, fallback: fallback}
228228
builder := launchDarklyOfflineStore.Flag(flag.name).ValueForAll(ldvalue.String(fallback))
229229
launchDarklyOfflineStore.Update(builder)
@@ -253,11 +253,11 @@ var FirecrackerVersionMap = map[string]string{
253253

254254
// BuildIoEngine Sync is used by default as there seems to be a bad interaction between Async and a lot of io operations.
255255
var (
256-
BuildFirecrackerVersion = newStringFlag("build-firecracker-version", env.GetEnv("DEFAULT_FIRECRACKER_VERSION", DefaultFirecrackerVersion))
257-
BuildIoEngine = newStringFlag("build-io-engine", "Sync")
258-
DefaultPersistentVolumeType = newStringFlag("default-persistent-volume-type", "")
259-
BuildNodeInfo = newJSONFlag("preferred-build-node", ldvalue.Null())
260-
FirecrackerVersions = newJSONFlag("firecracker-versions", ldvalue.FromJSONMarshal(FirecrackerVersionMap))
256+
BuildFirecrackerVersion = NewStringFlag("build-firecracker-version", env.GetEnv("DEFAULT_FIRECRACKER_VERSION", DefaultFirecrackerVersion))
257+
BuildIoEngine = NewStringFlag("build-io-engine", "Sync")
258+
DefaultPersistentVolumeType = NewStringFlag("default-persistent-volume-type", "")
259+
BuildNodeInfo = NewJSONFlag("preferred-build-node", ldvalue.Null())
260+
FirecrackerVersions = NewJSONFlag("firecracker-versions", ldvalue.FromJSONMarshal(FirecrackerVersionMap))
261261
)
262262

263263
// ResolveFirecrackerVersion resolves the firecracker version using the FirecrackerVersions feature flag.
@@ -297,7 +297,7 @@ var defaultTrackedTemplates = map[string]bool{
297297
// should be tracked in sandbox start time metrics. Templates not in this list
298298
// will be grouped under "other" to reduce metric cardinality.
299299
// JSON format: {"base": true, "code-interpreter-v1": true, ...}
300-
var TrackedTemplatesForMetrics = newJSONFlag("tracked-templates-for-metrics", ldvalue.FromJSONMarshal(defaultTrackedTemplates))
300+
var TrackedTemplatesForMetrics = NewJSONFlag("tracked-templates-for-metrics", ldvalue.FromJSONMarshal(defaultTrackedTemplates))
301301

302302
// GetTrackedTemplatesSet fetches the TrackedTemplatesForMetrics flag and returns it as a set for efficient lookup.
303303
// Only keys with a truthy value are included; keys set to false are ignored.
@@ -323,7 +323,7 @@ func GetTrackedTemplatesSet(ctx context.Context, ff *Client) map[string]struct{}
323323
// so it takes effect immediately.
324324
//
325325
// JSON format: {"useStreaming": false, "minReadBatchSizeKB": 16}
326-
var ChunkerConfigFlag = newJSONFlag("chunker-config", ldvalue.FromJSONMarshal(map[string]any{
326+
var ChunkerConfigFlag = NewJSONFlag("chunker-config", ldvalue.FromJSONMarshal(map[string]any{
327327
"useStreaming": false,
328328
"minReadBatchSizeKB": 16,
329329
}))
@@ -335,7 +335,7 @@ var ChunkerConfigFlag = newJSONFlag("chunker-config", ldvalue.FromJSONMarshal(ma
335335
//
336336
// Ops bucket (packets): effective rate = ops.bucketSize * 1000 / ops.refillTimeMs ops/s.
337337
// Bandwidth bucket (bytes): effective rate = bandwidth.bucketSize * 1000 / bandwidth.refillTimeMs bytes/s.
338-
var TCPFirewallEgressThrottleConfig = newJSONFlag("tcpfirewall-egress-throttle-config", ldvalue.FromJSONMarshal(map[string]any{
338+
var TCPFirewallEgressThrottleConfig = NewJSONFlag("tcpfirewall-egress-throttle-config", ldvalue.FromJSONMarshal(map[string]any{
339339
"ops": map[string]any{"bucketSize": -1, "oneTimeBurst": 0, "refillTimeMs": 1000},
340340
"bandwidth": map[string]any{"bucketSize": -1, "oneTimeBurst": 0, "refillTimeMs": 1000},
341341
}))
@@ -396,7 +396,7 @@ func GetTCPFirewallEgressThrottleConfig(ctx context.Context, ff *Client) TCPFire
396396
//
397397
// Ops bucket (IOPS): effective rate = ops.bucketSize * 1000 / ops.refillTimeMs ops/s.
398398
// Bandwidth bucket (bytes): effective rate = bandwidth.bucketSize * 1000 / bandwidth.refillTimeMs bytes/s.
399-
var BlockDriveThrottleConfig = newJSONFlag("block-drive-throttle-config", ldvalue.FromJSONMarshal(map[string]any{
399+
var BlockDriveThrottleConfig = NewJSONFlag("block-drive-throttle-config", ldvalue.FromJSONMarshal(map[string]any{
400400
"ops": map[string]any{"bucketSize": -1, "oneTimeBurst": 0, "refillTimeMs": 1000},
401401
"bandwidth": map[string]any{"bucketSize": -1, "oneTimeBurst": 0, "refillTimeMs": 1000},
402402
}))

0 commit comments

Comments
 (0)