Repository navigation
SW-Serverless 10.2.0: Python and Node adapters, sw-serverless CLI, standalone from Bitween - #166
Merged
Merged
Conversation
Adapters in Python 3.12+ declare settings with sw.expect, mark commands with @sw.command, and run with sw.run, which serves --describe and otherwise the host that started it. Resident adapters add start, stop, status and reset; a call's context publishes events, keeps state and records metrics, and Python logging reaches the host. It has no dependencies. The protocol is one gRPC stream over a Unix socket, so the SDK carries its own protobuf codec for adapter.proto's messages and a small HTTP/2 client with HPACK and flow control in both directions. It vendors into a package as plain files, for any platform, with nothing to fetch.
Classic sessions as Bitween runs handlers, a resident instance with status, events, state, reset and drain, payloads well past the HTTP/2 window both ways, errors with their types, a cancelled call, concurrent calls on one instance, --describe, and the Bitween handler, validator and receiver written with simplyworks-bitween.
serverless init --lang python writes a working adapter of any Bitween kind. serverless build packages a Python adapter: its files as they are, the SDK and the Bitween kinds vendored from copies the CLI carries, requirements.txt vendored with pip, and an entry that puts them on the path. Pure-Python requirements are vendored once and the package runs anywhere; native ones are vendored per target platform, linux-x64 and linux-arm64 unless adapter.json names others, and the manifest lists them. The adapter describes itself on the build machine, with its requirements installed there only for that when it isn't a target. test and run build a Python project folder first, as a .NET one. Scaffolded files end in a newline.
A protobuf map can't hold a null, and Ready's startup values were copied in as given: Bitween's gateway runs validators with no correlation id, so any gRPC adapter used as a validator there failed before it was ready, its stream ended by an exception in Attach. Null values are left out, and read as absent, which is what null meant.
Adapters in JavaScript or TypeScript on Node 22+ declare settings with expect, commands in a static commands map with how each argument and result is encoded, and run with run(), which serves --describe and otherwise the host that started it. Resident adapters add start, stop, status and reset; a call's context publishes events, keeps state, records metrics and has a signal that aborts when the host gives up on the call; logs reach the host. No dependencies: Node's http2 carries the gRPC stream and the SDK its own protobuf codec, whose bytes match the Python SDK's. Typings ship with it.
The same ground as the Python tests, with the adapters built by serverless build: classic sessions, a resident instance, large payloads both ways, errors, a cancelled call, concurrent calls, and the Bitween handler and receiver in JavaScript and validator in TypeScript. Tests needing Node to strip TypeScript types are inconclusive on a Node older than 22.13.
serverless init --lang node or typescript writes a working adapter of any Bitween kind; the TypeScript one is an ES module checked by tsc --noEmit. serverless build packages it: its files as they are, TypeScript turned into JavaScript by Node's own type stripping, so no compiler is needed and syntax that would need compiling is refused; the SDK and Bitween kinds vendored into node_modules from copies the CLI carries; and package.json's other dependencies installed by npm without running their scripts. A dependency with native code is refused unless the adapter is limited to the platform it is built on. test and run build a Node project folder first.
AdapterRepository and the package publish took the adapters folder to be "adapters" always, while hosts are configured with their own. Both now take it, defaulting to "adapters", so Bitween can publish where its hosts read; the static members stay as they were.
SW-Serverless knew one application by name: its CLI scaffolded Bitween's
kinds, vendored Bitween's Python and Node packages into every build and
carried Bitween's contract in its conformance kit, and its manifest had a
minBitweenVersion. None of it belongs to a library any application can use.
- The CLI is sw-serverless. init writes a generic adapter — two settings,
two commands — in .NET, Python, JavaScript or TypeScript.
- The kit carries no contract. One is handed to it with --contract or
ConformanceOptions.Contracts, or registered once by an application's own
tool (ContractDocument.Register, FromJson).
- The build vendors only the SDK; an application hands it its own packages
(BuildRequest.Packages), which requirements.txt and package.json may then
name without being fetched.
- The scaffolder takes an application's templates (Scaffold with Templates)
and keeps its checks and layout.
- compatibility.applications gives each application's minimum version;
manifests written with minBitweenVersion stay readable through
MinVersionOf("bitween").
- The Python and Node SDKs are sw-serverless (import sw_serverless) and
@simplyworks/sw-serverless, 10.2.0. Python gains sw.implements to declare
a contract and its kinds.
- Tests use a sample "orders" contract of their own, and nothing reads
../Bitween-api. The release is 10.2.0: public members were removed.
Where an adapter is published — flags, then the -c file, then SWSL_* variables — was worked out in the sw-serverless project, so a CLI built on Tooling had to copy it. It is StorageResolver and StorageFlags in Tooling now; the command line's resolver delegates to it.
A self-contained single-file build has no runtime assemblies on disk, so the older publish form read an adapter's types against nothing and took every adapter for a classic one with no kinds. It now reads them against an installed .NET when its own runtime has no files: DOTNET_ROOT, the usual folders, or what dotnet --list-runtimes reports. A .NET adapter needs one to run anyway.
A tag cli-v<version> builds the command for Linux (x64, arm64, musl x64), macOS (x64, arm64) and Windows (x64), single-file and self-contained, and publishes them on a release with SHA256SUMS. scripts/install-cli.sh installs the latest, checking it against the checksums.
Start was awaited inside the loop that reads the host's frames, so a start that asked the host for anything — its state, an event's ack — waited for an answer that loop could never read, and the adapter hung. Start now runs beside it: commands wait until it has returned, a stop waits for it within its own deadline, and a start that fails stops the adapter as before. The Python and Node test residents now read and write state from start.
The default locator took the installer when it was built, which needs ServerlessOptions and storage, so a host giving every adapter by path could not start. It takes the installer only when it installs from storage, and says what is missing then.
- Manifests no longer carry isResident, which is worked out from lifecycle. - A package's Lang metadata is its runtime, not always dotnet. - test says when a contract file can't be read, instead of crashing. - --allow and --contract say they take several values separated by spaces. - musl platforms are no longer offered for Python builds, which manifests and hosts don't recognise. - Comments no longer cite a design document this repository doesn't have, or name other products; InternalsVisibleTo names sw-serverless and the packages point at this repository.
A README and docs written for anyone building a host or an adapter, with no particular application in mind: concepts, hosting, writing adapters in .NET, Python and Node, the sw-serverless CLI, the manifest, packaging and storage, contracts and the conformance kit, the protocol, extending the tooling with an application's own CLI, and compatibility. Installing the CLI from its GitHub releases. The resident adapters design, written for one application, moves to that application's repository.
|
Important Review skippedToo many files! This PR contains 134 files, which is 34 over the limit of 100. To get a review, reduce the PR to 100 files or fewer by splitting it into smaller PRs or changing its base branch. Upgrade to a paid plan to raise the limit. This review couldn't start because sufficient usage credits or metered capacity aren't available. Add credits or update usage-based reviews in the billing tab, then retry. ⚙️ Run configuration
📒 Files selected for processing (134)
You can disable this status message by setting the
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. Comment |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What's in 10.2.0
sw-serverless(PyPI) and@simplyworks/sw-serverless(npm), run by the host over gRPC on a Unix domain socket, as classic or resident adapters. Tested through the real host.sw-serverlessCLI. It scaffolds, builds, tests, runs and publishes adapters in .NET, Python and Node. It is released on GitHub as self-contained binaries (Linux x64/arm64, glibc and musl; macOS; Windows), withSHA256SUMS, by.github/workflows/cli-release.ymlon acli-v<version>tag.ContractDocument), templates and vendored packages throughSimplyWorks.Serverless.Tooling. The manifest'scompatibility.applicationsreplacesminBitweenVersion, which is still read.AddServerless.sw-serverless.docs/describe SW-Serverless on its own.Compatibility
Backward compatible: existing .NET adapters, packages and manifests keep working. A Python or Node adapter is published to versions and the catalog only, so hosts older than 10.1 never see it.
Tests
Compatibility 29, Installer 131 and Unit 169 pass, plus the Python and Node SDK tests.
After merge
Publish the 10.2.0 NuGet packages. Bitween's
releases/r10.0-stagingdepends on them. PyPI/npm publishing and the firstcli-vtag come later.Commits