Skip to content

SW-Serverless 10.2.2: memory and CPU limits for adapters run locally - #168

Merged
samerzughul merged 4 commits into
mainfrom
release/10.2.1
Oct 10, 2026
Merged

samerzughul merged 4 commits into
mainfrom
release/10.2.1

Conversation

@samerzughul

@samerzughul samerzughul commented Oct 10, 2026 •

Copy link
Copy Markdown
Member

What's in 10.2.2

  • Limits for local runs. LocalAdapterHost.StartAsync(..., limits:) and ConformanceOptions.Limits take a new LocalAdapterLimits:

    • MemoryLimitBytes
    • CpuPercentLimit
    • CpuLimitSamples
    • SampleInterval (1 s by default)

    With limits set, the watchdog samples every interval and stops an adapter that goes over. Bitween's adapter editor uses this to cap the drafts it checks and tries on the server.

  • Python hard memory cap on Linux. When a hard limit is set, the host passes SW_SERVERLESS_MEMORY_LIMIT_BYTES and the Python SDK applies it as RLIMIT_DATA. It isn't RLIMIT_AS because that counts malloc arenas and thread stacks, and would break ordinary adapters. Elsewhere the watchdog applies.

  • Clear stop reasons. An adapter stopped for memory, CPU or missed heartbeats raises AdapterStoppedException (an IOException) with the reason, for example: stopped: it was using 167 MB, over its memory limit of 150 MB, and was killed. Previously each of these was Adapter stream closed.

  • Version. The SDKs are at 10.2.2: sw-serverless and @simplyworks/sw-serverless.

Compatibility

Backward compatible:

  • The 10.2.0 LocalAdapterHost.StartAsync signature is kept as its own overload.
  • Without limits, behaviour is unchanged, and the memory variable is never inherited from the host's environment.
  • AdapterStoppedException derives from IOException, so existing catch (IOException) still catches it.

Tests

Suite Result
Installer 136/136, including 5 new LocalLimitsTests: Python over memory and over CPU, Node over memory, no limits unchanged, conformance with limits
The 5 limit tests on Linux (Docker) pass, including the real RLIMIT_DATA path
Compatibility 29/29
Unit 169/169
Python SDK 21/21 on Linux
Node SDK 8/8

Bitween's suites also pass against the locally packed 10.2.2.

After merge

Publish the 10.2.2 NuGet packages. Bitween's releases/r10.0-staging waits on them. For the Python and Node SDKs, tag sdk-v10.2.2.

Why 10.2.2

The merge of #167 already published 10.2.1 to nuget.org, without these changes, because the workflow numbers each publish from main. So this release is 10.2.2.

A call cut short because the host stopped the adapter (its hard or soft
memory limit, its CPU limit, or missed heartbeats) failed with a bare
"Adapter stream closed." It now fails with AdapterStoppedException, an
IOException as before, whose message names the limit and what the adapter
was using; ResidentAdapterInstance.StopReason keeps the reason. Calls made
after the stop say it too.

Python has no heap ceiling of its own. The host now hands the hard memory
limit to a Python adapter as SW_SERVERLESS_MEMORY_LIMIT_BYTES, and never
passes one on when there is no limit. The SDK sets it as RLIMIT_DATA on
Linux, so an allocation past it raises MemoryError, which the call reports
as running out of memory under the limit. RLIMIT_AS would count reserved
address space (malloc arenas, thread stacks): an adapter using 26 MB with a
few worker threads has over 600 MB of it. Off Linux the watchdog applies.
LocalAdapterHost.StartAsync takes LocalAdapterLimits (limits:), and
ConformanceOptions.Limits passes them through: a memory limit, a CPU limit
as a share of the machine, the samples in a row before the CPU limit trips,
and how often the process is sampled. A tool that builds and tries drafts on
a shared server can hold them to a budget.

With limits, the host samples every second rather than every fifteen, so a
short try is caught; the missed heartbeats allowed grow to keep 45 seconds
of tolerance, and an adapter asked to stop at its CPU limit is killed after
two samples. A call cut short says which limit, also when the adapter died
at its runtime's own ceiling. Without limits nothing changes, and the
existing StartAsync signature still binds for code built against 10.2.0.
The conformance kit no longer counts a stopped adapter as refusing an
unknown command.
The packages, and the Python and Node SDKs with them: the Python SDK now
applies the memory limit the host hands it, so its version moves with the
host's. The CLI install examples keep naming the released 10.2.0 binary.
@coderabbitai

coderabbitai Bot commented Oct 10, 2026 •

Copy link
Copy Markdown

Review in Change Stack →Review in Change Stack →

Note

Currently processing new changes in this PR. This may take a few minutes, please wait...

⚙️ Run configuration
  • Configuration used: Repository: simplify9/coderabbit/.coderabbit.yaml
  • Review profile: ASSERTIVE
  • Plan: Advanced
  • Run ID: 35f923d5-c5c3-4926-8631-ee1cd669c31d

📥 Commits

Reviewing files that changed from the base of the PR and between cadc7c1 and 7ee95ad.


📒 Files selected for processing (21)
  • SW.Serverless.Installer.UnitTests/LocalLimitsTests.cs
  • SW.Serverless.Tooling/Conformance/ConformanceOptions.cs
  • SW.Serverless.Tooling/Conformance/ConformanceRunner.cs
  • SW.Serverless.Tooling/LocalAdapterHost.cs
  • SW.Serverless.Tooling/LocalAdapterLimits.cs
  • SW.Serverless.Tooling/Scaffolding/Scaffolder.cs
  • SW.Serverless/Resident/ResidentAdapterHost.cs
  • SW.Serverless/Resident/ResidentAdapterInstance.cs
  • SW.Serverless/Runtimes/AdapterRuntimes.cs
  • docs/cli.md
  • docs/compatibility.md
  • docs/contracts.md
  • docs/extending.md
  • docs/hosting.md
  • docs/manifest.md
  • docs/protocol.md
  • sdk/node/package.json
  • sdk/node/src/index.js
  • sdk/python/pyproject.toml
  • sdk/python/src/sw_serverless/_runner.py
  • sdk/python/tests/test_memory_limit.py

  • 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

Comment @coderabbitai help to get the list of available commands.

@samerzughul samerzughul changed the title SW-Serverless 10.2.1: memory and CPU limits for adapters run locally SW-Serverless 10.2.2: memory and CPU limits for adapters run locally Oct 10, 2026
@samerzughul
samerzughul merged commit d04256f into main Oct 10, 2026
8 of 10 checks passed
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.

1 participant