Getting Started
This walkthrough takes the canonical HttpGetWorker worker from a clean checkout to a running deployment against a local WorkManager + Dapr stack.
Prerequisites
- .NET 10 SDK
- Python 3.11+ (for the deploy scripts)
- Docker (with the
docker.haenerconsulting.com/library/dotnet-crossbuild:10image available locally for AOT builds) - A running WorkManager + API + Dapr stack (the
docker-composerepo provides the canonicalprod.yaml)
1. Build the worker (managed)
git clone https://git.haenerconsulting.com/virtufin/workers.git
cd workers/HttpGetWorker
python3 scripts/build_managed.py
This runs dotnet publish on the managed csproj, then PackageWorker (an MSBuild target in the csproj) stages the output into <repo>/build/Virtufin.Worker.HttpGetWorker.Managed.nupkg/, computes SHA-256, and writes build_version.txt. Output:
==> PackageId: Virtufin.Worker.HttpGetWorker
==> LIBRARY_VERSION: 0.3.3 (cli=None env=None file=0.3.3)
==> Publishing .../Virtufin.Worker.HttpGetWorker.Managed.csproj ...
==> Built artefact: .../build/.../Virtufin.Worker.HttpGetWorker.nupkg (...)
==> SHA-256: ...
==> Version: 0.3.3-sha.<8hex>
2. Publish the nupkg
python3 scripts/publish.py
Uploads the nupkg to the Gitea NuGet feed (https://gitea.haenerconsulting.com/api/packages/virtufin/nuget/). Reads the Gitea credentials from the VIRTUFIN_REGISTRY_USER / VIRTUFIN_REGISTRY_TOKEN env vars.
3. Deploy and trigger it
python3 scripts/create_worker.py --api-client-host localhost --api-client-port 5002
# -> prints the new worker's id
python3 scripts/start_worker.py --api-client-host localhost --api-client-port 5002 --id <worker_id>
Trigger it by publishing a CloudEvent on command.httpgetworker whose data is {"url": "https://example.com/data"}:
from virtufin.api import ApiClient
async with ApiClient("localhost", 5002) as api:
result = await api.pubsub.publish_with_result_async(
topic="command.httpgetworker",
data={"url": "https://example.com/data"},
reply_topic="response.httpgetworker",
timeout=10.0,
)
print(result.data_as_json())
The worker performs the GET and publishes the response — datacontenttype mirrors the upstream response's own Content-Type, data is the body as text. See the README for the full response shape and error handling.
4. (Optional) Build the AOT variant
The same worker source can be built for NativeAOT. The AOT csproj sets <PublishAot>true</PublishAot> and produces a libHttpGetWorkerNative.so per RID. Build with:
python3 scripts/build_aot.py
This requires Docker to run the cross-build image (clang + cross-binutils). On an x86_64 host it works natively; on an arm64 host it works via qemu-x86_64 emulation and is slow.
5. (Optional) Build a single nupkg containing both layouts
python3 scripts/build_both.py
Produces a single nupkg with lib/net10.0/HttpGetWorker.dll AND runtimes/<rid>/native/libHttpGetWorker.so. Register under either or both MIME types at deploy time.
Next steps
- Worker Author Guide — author a new worker from scratch
- Packaging Modes — the trade-offs between managed, native, and both
- Engines — the DotNetDll vs NativeDll contrast in detail