Skip to content

Give resident adapters the host's ServerlessOptions - #181

Merged
AhmadRAbuhussein merged 1 commit into
mainfrom
muhannad/resident-serverless-options
Oct 27, 2026
Merged

AhmadRAbuhussein merged 1 commit into
mainfrom
muhannad/resident-serverless-options

Conversation

@mmalkhatib

Copy link
Copy Markdown
Contributor

A classic adapter gets the host's ServerlessOptions on argv[1] and reads it as Runner.ServerlessOptions, for example its cloud-files settings to fetch an attachment from the host's storage. A resident process never got it, so Runner.ServerlessOptions stayed null there, and an adapter that reads it threw on first use. Traxis's DHL label adapter reads it on every call, which is what blocks DHL from going resident.

Change

  • Ready gets string serverless_options = 4: the host's ServerlessOptions as JSON, the same content classic sends on argv[1]. It goes over the socket like the startup values, so it stays off the command line.
  • ResidentAdapterHost takes the registered ServerlessOptions. The constructor parameter is optional; with none registered, nothing is sent.
  • The SDK sets Runner.ServerlessOptions from Ready. If the host sent none, it falls back to defaults, as the classic runner does when argv[1] can't be read.
  • docs/protocol.md documents the field.

Compatibility

  • An adapter built before this ignores the field (proto3).
  • A host built before this sends nothing, and the SDK then uses defaults.

Tests

  • New: The_hosts_serverless_options_reach_the_runner. The Ticker sample, running resident, reads the host's AdapterRemotePath through Runner.ServerlessOptions.
  • Resident tests: 16/16 pass. Compatibility tests: 29/29 pass.
  • The full unit suite shows 7 classic/describe failures on this machine. The same 7 fail on unmodified main here and pass when run alone, so they're local test-environment issues, not this change.

A classic adapter gets the host's ServerlessOptions on argv[1] and reads it through
Runner.ServerlessOptions, e.g. its cloud-files settings to fetch an attachment from the host's
storage. A resident process never got it, so Runner.ServerlessOptions stayed null and such an
adapter threw the first time it read it (Traxis's DHL label adapter reads it on every call).

Ready now carries it as JSON (serverless_options, field 4), over the socket as the startup values
already are, so it stays off the command line. ResidentAdapterHost takes the registered
ServerlessOptions (optional; none sends nothing), and the SDK sets Runner.ServerlessOptions from
Ready, falling back to defaults when the host sent none, as the classic runner does when argv[1]
can't be read. An adapter built before this ignores the field; a host built before sends none.

Test: the Ticker sample, resident, reads the host's AdapterRemotePath through
Runner.ServerlessOptions. Resident tests 16/16 and compatibility tests 29/29 pass. The full unit
suite has the same 7 classic/describe failures on unmodified main on this machine; they pass alone.
@coderabbitai

coderabbitai Bot commented Oct 27, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

Caution

Review failed

The pull request is closed.

📝 Summary

Summary

ResidentAdapterHost can pass the host’s ServerlessOptions to resident adapters as JSON in the Ready.serverless_options field. The SDK deserializes the field into Runner.ServerlessOptions and uses defaults when the field is empty or cannot be parsed. The field is additive, so older hosts can omit it and older adapters can ignore it.

Risk

risk:medium. The change adds a socket-protocol field and JSON deserialization during resident startup. Parse failures fall back to defaults.

Security-sensitive areas

Host configuration now crosses the resident socket connection. Review how sensitive values in ServerlessOptions are handled and whether the socket’s existing protections are sufficient. No authentication or transport-security changes are described.

Test coverage impact

The PR adds a test that checks the host’s AdapterRemotePath reaches the resident runner. The author reports 16/16 resident tests and 29/29 compatibility tests passed. The author also reports seven full-unit-suite failures that reproduced on unmodified main and passed when run alone.

Deployment and operations

No migration is described. Older hosts send no value, and the SDK uses defaults. Confirm deployments that need host settings run a host version that populates the new field. Rollback impact is not specified.

The resident Ready frame now carries the host’s ServerlessOptions as JSON. The SDK loads the options into Runner.ServerlessOptions, with defaults used when the value is empty or cannot be parsed. The ticker sample, a resident adapter test, and the protocol documentation cover the new field.

Changes: Resident options handoff

Layer / File(s) Summary
Define and send options
SW.Serverless.Contract/Protos/adapter.proto, SW.Serverless/Resident/ResidentAdapterHost.cs, SW.Serverless/Resident/ResidentAdapterInstance.cs, docs/protocol.md
The Ready contract adds serverless_options. The host serializes its options and passes them to each resident instance, which includes them in the initial Ready frame. The protocol documentation describes the field and empty-value behavior.
Load options in the SDK
SW.Serverless.Sdk/Resident/ResidentRunner.cs, SW.Serverless.Sdk/Runner.cs
ResidentRunner forwards the Ready value to Runner.UseResidentOptions. The method deserializes nonempty JSON, logs a warning on parse failure, and uses a new ServerlessOptions instance when no value is loaded.
Exercise and document the options
SW.Serverless.Samples.Ticker/Handler.cs, SW.Serverless.UnitTests/ResidentAdapterTests.cs
The ticker sample exposes the remote path and bucket name. The resident adapter test checks that the remote path is "adapters".

Priority: Not assessed

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

Change: Bug fix

Suggested labels: security, risk:medium

Suggested reviewers: samerzughul

Merge Risk: Minimal · up to c0387

No actionable merge-blocking risk remains from the reviewed change.

- [ ] Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Warning

Some tools did not complete. Review the errors below.

Buf (1.73.0)

Lint configuration: default BASIC rules with the repository root as the protobuf import root; no repository Buf configuration was found. These results do not establish the project's lint policy or build configuration. For unresolved imports or symbols, check the project's declared import roots and dependencies before concluding that its build fails.

SW.Serverless.Contract/Protos/adapter.proto

fatal: unable to access 'https://github.com/simplify9/SW-Serverless.git/': Failed to connect to github.com:443 over proxy 127.0.0.1 after 0 ms: Could not connect to server
fatal: could not fetch 3d2b7d9bbbfdb8109f69693f5d4d91697a60251e from promisor remote

CODERABBIT_BUF_COMPATIBILITY_PHASE=materialize-base

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.

@AhmadRAbuhussein
AhmadRAbuhussein merged commit 33ebbbb into main Oct 27, 2026
5 of 6 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.

2 participants