Repository navigation
Conversation
Adds a `[local.services.<service>.container]` table with `memory` and `cpus`. Container runtimes apply them as `--memory`, `--memory-swap`, and `--cpus` on every launch, so limits survive stop and start; the native runtime ignores the table. Limit edits show as configuration drift in `stack status` until the next stop and start.
…managed-local-stack-cpu-and-memory # Conflicts: # apps/cli/src/config/cli-config-key.ts
CLI benchmark (Lightweight Commands): no changes foundCommit
API calls: unchanged for all 8 commands. Binary size: 134.8 MB, up 8.0 KB from 134.8 MB. Details: timing ranges, API calls per command, slowest phasesTiming ranges
API calls per command
Slowest phasesNo command moved beyond noise, so there are no phase deltas. Comment |
7ttp
left a comment
There was a problem hiding this comment.
gave this a spin and it works nicely! limits stick across stop and start 😄
tho i've left a few smol nits inline:
| pin: creation.pin, | ||
| endpoints: withSharedApiPort(creation, sharedPort), | ||
| config, | ||
| container: creation.container, |
There was a problem hiding this comment.
a limit edit on a native stack still shows up as drift, even though native ignores limits
ig leave container out of the comparison when the stack runs natively?
| const withContainerLimits = (creation: ServiceCreationType): ServiceCreationType => { | ||
| const container = validatedConfig.local?.services?.[creation.service]?.container; | ||
| return container === undefined | ||
| ? creation | ||
| : { | ||
| ...creation, | ||
| container: { | ||
| ...(container.memory === undefined | ||
| ? {} | ||
| : { memoryBytes: ramInBytes(container.memory) }), | ||
| ...(container.cpus === undefined ? {} : { cpus: container.cpus }), | ||
| }, | ||
| }; |
There was a problem hiding this comment.
nit: an empty [local.services.auth.container] turns into container: {}, so a running stack reports it as drift
could it just return creation when neither memory nor cpus is set?
| Schema.makeFilter((value: string) => { | ||
| const bytes = sizeInBytes(value); | ||
| return bytes === undefined || (bytes >= 1 && Number.isSafeInteger(bytes)) | ||
| ? undefined | ||
| : "must be at least 1 byte and less than 8 PiB"; | ||
| }), | ||
| ); | ||
|
|
||
| const cpus = Schema.Finite.annotate({ | ||
| description: | ||
| "CPU limit for the service container, in CPUs; fractions are allowed (for example `0.5`).", | ||
| examples: [0.5, 1, 2], | ||
| tags, | ||
| }).check(Schema.isGreaterThan(0, { message: "must be greater than 0" })); |
There was a problem hiding this comment.
small one: memory = "1" and cpus = 0.001 pass here, but docker needs at least 6MiB and 0.01 cpus so stack start fails, prob worth rejecting those here so it fails at config load?
|
|
||
| const memory = Schema.String.annotate({ | ||
| description: | ||
| "Memory limit for the service container, as a size such as `512MiB` or `1GiB` (1024-based, case-insensitive; a bare number is bytes). Swap is limited to the same amount.", |
There was a problem hiding this comment.
this says swap is limited to the same amount, but --memory-swap equal to --memory means no swap at all
how about js "Swap is disabled"?
| export const SUGGEST_CONTAINER_MEMORY_LIMIT = | ||
| "The container ran out of memory and was killed. Raise the memory allocated to your container runtime (Docker Desktop: Settings > Resources), or free up memory on the host, and try again."; | ||
| "The container ran out of memory and was killed. Raise the memory allocated to your container runtime (Docker Desktop: Settings > Resources), raise `memory` in `[local.services.<service>.container]` if you set one, or free up memory on the host, and try again."; |
There was a problem hiding this comment.
maybe for later: this hint only shows in legacy functions serve, which ignores the table, and a stack service over its limit just exits with 137 and no hint
what if legacy kept its old hint and the memory one went on that stack error?
Summary
Local stack services can now be given container resource limits in
config.toml:memoryis a 1024-based size (512MiB,1GiB; a bare number is bytes). Swap is capped at the same amount, so the limit is not silently doubled.cpusis a positive number of CPUs; fractions are allowed.stack stopandstack start. Editing them shows as configuration drift instack statusuntil the stack is stopped and started again.config.tomlkeeps working with both runtimes.memorysetting.