Skip to content

feat(gonsole): hand a program's processor and memory limits to Go - #115

Merged
SirLouen merged 2 commits into
mainfrom
feat/114
Oct 31, 2026
Merged

SirLouen merged 2 commits into
mainfrom
feat/114

Conversation

@SirLouen

@SirLouen SirLouen commented Oct 31, 2026 •

Copy link
Copy Markdown
Member

Closes #114

What

  • Env.RuntimeLimits reads MAX_PROCS (1 to the number of CPUs) and MEMORY_LIMIT_MB (1 to 1073741824). Each stays unset unless named.
  • Main hands them to runtime.GOMAXPROCS and debug.SetMemoryLimit before the command runs. Each only lowers what Go holds, so a container's CPU quota or a tighter GOMEMLIMIT still wins. It applies neither when one cannot be read, and nothing when both are unset.
  • check and serve refuse a value out of range, and check names it beside the program's other bad settings. Every other command runs without it.

Why

Go reads GOMAXPROCS and GOMEMLIMIT before main, and a program loads its .env inside main. On a host where .env is the only way in, a program had no way to cap its processors or its memory.

Testing

  • go test -race ./... in gonsole, coverage 100%.
  • A test runs the test binary as a small program that prints what Go holds: procs 1 memory 67108864 with both limits set, Go's own limits when one cannot be read, and a tighter GOMEMLIMIT kept. It fails without the call in Main.
  • go vet on Windows, macOS and 386.
  • golangci-lint with the module's config, cyclop included: 0 issues.

Summary by CodeRabbit

  • New Features
    • Configure Go runtime processor and memory limits with MAX_PROCS and MEMORY_LIMIT_MB. Limits are applied when the settings can be read and only tighten existing runtime limits.
  • Bug Fixes
    • The check and serve commands now report invalid runtime-limit settings before proceeding. Processor values must be between 1 and the available CPU count; memory values must be between 1 and 1,073,741,824 MiB.
  • Documentation
    • Added changelog guidance for runtime-limit settings and validation ranges.

@coderabbitai

coderabbitai Bot commented Oct 31, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

No actionable comments were generated in the recent review.

Recent review info
Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Organization UI
  • Review profile: ASSERTIVE
  • Plan: Advanced
  • Run ID: 0a91d0af-6971-467d-8cf2-a84896365156
Commits

Reviewing files that changed from the base of the PR and between 75b34a6 and 19dbd28.

Files selected for processing: 7
  • gonsole/CHANGELOG.md
  • gonsole/base.go
  • gonsole/exec_test.go
  • gonsole/limits.go
  • gonsole/limits_internal_test.go
  • gonsole/limits_test.go
  • gonsole/program.go

Included review availability: This review used your included allowance. Your plan provides up to 1 included review per hour; 0 remain after this review.

Walkthrough

The program now reads MAX_PROCS and MEMORY_LIMIT_MB and applies readable limits to Go before running a command. The check and serve commands validate those settings and return errors for invalid values.

Changes: Runtime limits

Layer / File(s) Summary
Read and apply runtime limits
gonsole/limits.go, gonsole/program.go, gonsole/limits_internal_test.go, gonsole/limits_test.go, gonsole/CHANGELOG.md
Adds RuntimeLimits and Env.RuntimeLimits. Main applies readable limits before running the program. Processor limits use runtime.GOMAXPROCS; memory limits convert MiB to bytes and use debug.SetMemoryLimit. Both settings only lower the limits held by Go. Tests cover parsing and application.
Validate limits in check and serve
gonsole/base.go, gonsole/exec_test.go, gonsole/limits_test.go
check combines runtime-limit errors with optional settings-validation errors. serve returns limit errors before invoking the server. Tests cover invalid and valid settings and command behavior.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Change: Feature

Sequence Diagram(s)

sequenceDiagram
  participant Main
  participant Env.RuntimeLimits
  participant GoRuntime
  participant runner.check
  participant runner.serve
  participant Program.Serve
  Main->>Env.RuntimeLimits: read limits and apply them to GoRuntime
  Main->>runner.check: run check command
  runner.check->>Env.RuntimeLimits: validate configured limits
  Main->>runner.serve: run serve command
  runner.serve->>Env.RuntimeLimits: validate configured limits
  runner.serve->>Program.Serve: start server when limits are valid
Loading

Suggested reviewers: codescene-access

Merge Risk: Minimal · up to 19dbd

No actionable merge-blocking risk remains from the reviewed runtime-limit changes.

Pre-merge checks: Passed 4 · Failed 1

Failed Failed checks: 1 warning

Check name Status Explanation Resolution
Docstring Coverage Warning Docstring coverage is 13.04% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff with cyclomatic complexity of at least 2. Documenta… Write docstrings for the functions missing them to satisfy the coverage threshold.
Passed Passed checks: 4 passed
Check name Status Explanation
Description Check Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check Passed The title clearly and concisely describes the main change: applying a program's processor and memory limits to Go.
Linked Issues check Passed [#114] Objectives checked at head 19dbd28.

1. Read MAX_PROCS (at most runtime.NumCPU()) and MEMORY_LIMIT_MB under the program prefix, each unset unless named. Impleme…
Out of Scope Changes check Passed All changed files relate to [#114]. gonsole/limits.go holds the new RuntimeLimits type, the RuntimeLimits method, and the apply logic. gonsole/program.go adds the Main call. gonsole/base.go adds the c…
Full details: Linked Issues check

Explanation

[#114] Objectives checked at head 19dbd28.

  1. Read MAX_PROCS (at most runtime.NumCPU()) and MEMORY_LIMIT_MB under the program prefix, each unset unless named. Implemented in gonsole/limits.go: Env.RuntimeLimits calls e.Count for both names with default 0. The prefix is applied by Env.Count, which was not inspected directly.
  2. Hand both limits to Go in Main before the command runs, leaving Go's defaults when unset. Implemented: gonsole/program.go Main calls applyRuntimeLimits(p.Env, liveRuntime()) before signal setup and p.Run. RuntimeLimits.apply skips zero values, so unset limits leave Go's defaults.
  3. Refuse out-of-range values in check and serve. Implemented in gonsole/base.go: runner.check joins the RuntimeLimits error with the Validate error and returns it before plugin loading; runner.serve returns the RuntimeLimits error before calling program.Serve.
  4. Other commands run without the limit. Main ignores the RuntimeLimits error and applies nothing in that case, so other commands run.

Design notes, not failures: apply lowers limits only, so a tighter existing GOMAXPROCS or GOMEMLIMIT wins. The issue asks for caps, which is consistent with this. When either value is unreadable, neither is applied. The issue does not state this case, so it is a reasonable reading.

Residual uncertainty: an explicitly set 0 is read as unset by the default of 0. The issue range starts at 1. Whether Env.Count rejects an explicit 0 was not verified.

Full details: Out of Scope Changes check

Explanation

All changed files relate to [#114]. gonsole/limits.go holds the new RuntimeLimits type, the RuntimeLimits method, and the apply logic. gonsole/program.go adds the Main call. gonsole/base.go adds the check and serve validation. gonsole/CHANGELOG.md documents the new settings. gonsole/exec_test.go adds a TestMain branch that runs limitsProgram as a subprocess, which supports the subprocess tests. gonsole/limits_internal_test.go and gonsole/limits_test.go test the parsing, application, and command behavior. No change was found that is unrelated to the issue. Assessment relies on the AI-generated summary of changes for the file list. The full diff was not read.

Full details: Docstring Coverage

Explanation

Docstring coverage is 13.04% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff with cyclomatic complexity of at least 2. Documentation-only edits and deletions within surviving functions are included; unchanged diff context and fully deleted functions are excluded. Analyzed 23 functions across 6 files. (1 skipped: 1 unsupported.)

Resolution

Write docstrings for the functions missing them to satisfy the coverage threshold.

Finishing Touches
Generate docstrings
  • Commit to this branch
  • Create a new PR
Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

Share

codescene-access[bot]

This comment was marked as outdated.

@greptile-apps

greptile-apps Bot commented Oct 31, 2026 •

Copy link
Copy Markdown

RetriggerView in GreptileConfidence Score: 5/5

[Medium impact] No blocking findings remain. The changes since the previous review regroup existing tests without changing production behavior.

Summary

Adds processor and memory settings that Main passes to Go without raising its current limits.

  • Programs can set Go’s processor and memory limits from their environment.
  • The check and serve commands validate runtime limits.

Reviews (2) · Last reviewed commit: "test(gonsole): move the limit runs out o..." · Reviewed by Greptile

@codescene-access codescene-access Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Gates Passed
4 Quality Gates Passed

See analysis details in CodeScene

Quality Gate Profile: Clean Code Collective
Install CodeScene MCP: safeguard and uplift AI-generated code. Catch issues early with our IDE extension and CLI tool.

@SirLouen
SirLouen merged commit e499419 into main Oct 31, 2026
46 checks passed
@SirLouen
SirLouen deleted the feat/114 branch October 31, 2026 14:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Hand a program's processor and memory limits to Go once its .env has loaded

1 participant