Skip to content

Nuspec Reference

The virtufin* extension elements in the worker nupkg's .nuspec are read by Virtufin.Worker.DevKit (the VirtufinWorkerNuspec class) and by the WM's WorkerNupkgLoader. They tell the WM which file in the nupkg is the worker (DLL or .so), what C-ABI function names to resolve, and what ABI version the worker targets.

The fields

Field Type Purpose
<id> string The NuGet package id (e.g. Virtufin.Worker.WebSocketManagerController). The build script reads this from the csproj's <PackageId>.
<version> string The content-addressed version (<LIBRARY_VERSION>-sha.<8hex>). The build script writes this — the csproj emits a placeholder.
<authors> string "Virtufin".
<description> string "WebSocketManagerController worker for the WorkManager" (managed) or "...(NativeAOT)" (AOT).
<virtufinAbiVersion> int The native worker ABI version. Default 1. The WM's NativeDllEngine rejects a nupkg whose value isn't in VirtufinWorkerNuspec.SupportedAbiVersions.
<virtufinEntryPoint> string The C-ABI function name for the dispatch entry point. Default "Process". The WM calls NativeLibrary.GetExport(handle, "Process") to resolve it.
<virtufinFreeResult> string The C-ABI function name for the result-free callback. Default "FreeResult". The WM calls NativeLibrary.GetExport(handle, "FreeResult") after each Process call.
<virtufinLibrary> string The basename of the worker file (no extension). For a managed nupkg, this is the worker DLL's basename (e.g. WebSocketManagerController). For an AOT nupkg, this is the basename of the .so (e.g. WebSocketManagerController — the AOT build renames WebSocketManagerController.so to libWebSocketManagerController.so at build time).

The contract

The nupkg must have exactly one virtufinLibrary value. The PackageWorker and PackageWorkerNative MSBuild targets both emit the same virtufinLibrary value, so a --format both nupkg has a single virtufinLibrary that resolves to either the managed DLL or the AOT .so depending on which engine loads the nupkg.

The other virtufin* fields are advisory for the AOT path only (the managed engine doesn't read them — it uses reflection on IWorker to discover the worker class). For a managed-only nupkg, the virtufinEntryPoint / virtufinFreeResult / virtufinLibrary fields are still required by the schema but are not read at load time.

Defaults

The build scripts default the virtufin* fields to: - virtufinAbiVersion = 1 - virtufinEntryPoint = Process - virtufinFreeResult = FreeResult - virtufinLibrary = <AssemblyName> (the csproj's assembly basename)

These match the VirtufinWorkerNuspec.Default* constants. Override them in the csproj's <NuspecProperties> if your worker exports different names (e.g. you have multiple C-ABI entry points and want to mark a custom one).

The full nuspec shape (managed)

<?xml version="1.0" encoding="utf-8"?>
<package xmlns="http://schemas.microsoft.com/packaging/2013/05/nuspec.xsd">
  <metadata>
    <id>Virtufin.Worker.WebSocketManagerController</id>
    <version>0.0.8-sha.bbaf1313</version>
    <authors>Virtufin</authors>
    <description>WebSocketManagerController worker for the WorkManager.</description>
    <virtufinAbiVersion>1</virtufinAbiVersion>
    <virtufinEntryPoint>Process</virtufinEntryPoint>
    <virtufinFreeResult>FreeResult</virtufinFreeResult>
    <virtufinLibrary>WebSocketManagerController</virtufinLibrary>
  </metadata>
</package>

The full nuspec shape (AOT, combined-managed-and-AOT nupkg)

<?xml version="1.0" encoding="utf-8"?>
<package xmlns="http://schemas.microsoft.com/packaging/2013/05/nuspec.xsd">
  <metadata>
    <id>Virtufin.Worker.WebSocketManagerController</id>
    <version>0.0.8-sha.<8hex></version>
    <authors>Virtufin</authors>
    <description>Virtufin worker nupkg (managed + NativeAOT).</description>
    <virtufinAbiVersion>1</virtufinAbiVersion>
    <virtufinEntryPoint>Process</virtufinEntryPoint>
    <virtufinFreeResult>FreeResult</virtufinFreeResult>
    <virtufinLibrary>WebSocketManagerController</virtufinLibrary>
  </metadata>
</package>

The <description> text varies by mode; the rest is identical.

The wire contract summary

Surface Owner Where it lives
<PackageId> (NuGet id) wire config.json script_url_template + config/last_published.version
<version> wire build_version.txt (build script writes it)
<virtufinLibrary> wire csproj <AssemblyName> (managed and AOT must agree)
<virtufinAbiVersion> engine csproj <NuspecProperties> (build script default 1)
<virtufinEntryPoint> engine csproj <NuspecProperties> (build script default Process)
<virtufinFreeResult> engine csproj <NuspecProperties> (build script default FreeResult)

The wire rows are the contract between worker author and consumer (the script that downloads + uses the nupkg). The engine rows are the contract between worker author and the WM's NativeDllEngine.

See also