Skip to content

Changelog

All notable changes to UKBatch are documented here. The format is based on Keep a Changelog, and the project adheres to Semantic Versioning.

  • Scheduled jobs no longer fire twice. Two distinct duplicate-fire bugs were found and fixed: a clock-skew race (the timer completing marginally before the wall-clock deadline fired an occurrence early and re-armed the same occurrence) and a duplicate registration (a job registered explicitly under a custom name was registered a second time by attribute discovery under its attribute-derived name, arming its cron twice).
  • A scheduler fire that fails to enqueue no longer strands a Pending execution row — the created row is compensated to Failed with a descriptive error.
  • Lifecycle hardening for the scheduler and the runtime host: bounded shutdown waits, one-shot start guards, safe disposal of the linked stopping sources, and startup aborts that reach the worker loops.
  • Cron documentation corrected. Examples are now six-field (seconds first — the default format rejects five-field crontab expressions at startup), the format is stated explicitly, and CronFormat.Standard is documented for five-field expressions.
  • The API samples run with a plain dotnet run — launch profiles pin the port and the Development environment, and the readmes document the -f flag.
  • Official server Docker imageghcr.io/nspukcode-hub/ukbatch-server (multi-platform: linux/amd64 + linux/arm64), published automatically alongside the NuGet packages on every release. The demo Compose stack still builds its images from source (now tagged :local).
  • Documentation website — the site you are reading.
  • Approval role claims are read only from an authenticated principal — an unauthenticated request can no longer present role claims to the approval endpoints.
  • HTTP transport request-body buffering is cappedMaxBodyBytes is validated into the 1 byte – 16 MB range, bounding pre-authentication memory use.
  • HTTP transport dedupe cache no longer grows unbounded — the message-id dedupe cache is a self-contained LRU whose result map is evicted in lock-step with the id set.
  • RabbitMQ refuses insecure defaults against a remote broker — connecting to a non-loopback broker with the default guest/guest credentials now fails at host start unless the new AllowInsecureBroker=true option is set explicitly (loopback brokers are exempt). If your deployment relied on a remote demo broker with default credentials, set this option or — better — create a dedicated broker user.
  • Abrupt host shutdown no longer races disposal in two background pumps — the SignalR status fan-out and the RabbitMQ consumer pump now guard their cancellation source against concurrent stop/dispose, eliminating spurious ObjectDisposedExceptions.
  • A cancelled HTTP transport subscription is treated as a graceful stop during shutdown instead of being logged as an error.
  • The dashboard no longer flashes a spurious “Disconnected” banner on first load. The service conductor was connecting to the (embedded) SignalR hub before the host had finished starting, so the initial connect failed and the banner stayed red until a manual reconnect or the 60-second retry. The initial connect is now deferred until the host has started, and the retry interval is shortened, so the dashboard connects cleanly on first load.
  • Typed partitioned-job batch stepsRunPartitionedJob<TJob>() and ThenRunPartitionedJob<TJob>() on the batch, parallel-group, and on-failure builders, so a partitioned job can be added to a batch by type like a regular job. Backed by a new IPartitionedJobMarker base interface.
  • AddUKBatchDevAuth() — an opt-in, header-based development authentication scheme in UKBatch.AspNetCore, so an embedded host can exercise the approval buttons in a demo without hand-writing an authentication handler. It trusts X-Dev-User / X-Dev-Roles with no verification and refuses to start in the Production environment unless explicitly allowed.
  • OpenAPI servers URLs no longer carry a trailing slash, so a Postman / OpenAPI client importing the document no longer builds double-slashed request paths that 404.
  • A dashboard service BaseUrl is normalized to a trailing slash automaticallyhttp://host/api now behaves the same as http://host/api/, removing a long-standing configuration footgun.
  • Approval gates reject an inconsistent timeout configuration — choosing an AutoApprove or Hold on-timeout action now requires a timeout duration, validated on both the dashboard and the server; the run-detail panel shows “no timeout — waits indefinitely” when a gate has none.
  • The dashboard sidebar and breadcrumb update immediately when switching services — the layout now reacts to the current-service change instead of lagging one navigation behind.
  • CI workflows updated to the current GitHub Actions majors (Node 24 runtime).
  • A job completing immediately after startup could be missed by the awaiter, leaving a caller waiting until its timeout. The process-wide watch subscription is now registered synchronously before StartAsync returns.
  • UKBatch.Dashboard now raises build warning UKBATCH001 when a .NET 10 host has not set <RequiresAspNetWebAssets>true</>, instead of failing silently with a runtime 404 for _framework/blazor.web.js. The property must be set by the host project — NuGet cannot supply it during restore — and the docs now say so plainly. (.NET 8 hosts are unaffected.)

First public preview of the UKBatch package family.

  • Multi-targeting — every package ships net8.0 and net10.0 builds in a single NuGet package; the consuming app’s target framework picks the right build automatically. On net8.0 the EF Core adapter rides the EF Core 8 (LTS) line.
  • UKBatch.Abstractions — zero-dependency contracts (interfaces, attributes, DTOs) shared by every package.
  • UKBatch.Core — the runtime: dispatcher, cron scheduler, per-job retries, sequential/parallel/approval-gate workflows, partitioned data-parallel jobs, the in-memory store, and the in-process transport.
  • UKBatch.AspNetCore — host integration with HttpContext-aware TriggeredBy enrichment, W3C trace propagation, and a readiness health check.
  • UKBatch.Api — REST endpoints, an OpenAPI document, and a SignalR hub for live job-status updates.
  • UKBatch.Dashboard — a Blazor Server UI for monitoring, triggering, approvals, a visual drag-and-drop batch editor, a live DAG view, and multi-service support.
  • UKBatch.WorkerUseWorkerMode to turn a microservice into a worker, with a worker identity, a heartbeat, and a startup transport guard.
  • UKBatch.Transport.Http — HMAC-SHA256-signed cross-service messaging with retry and circuit-breaker resilience.
  • UKBatch.Transport.RabbitMQ — durable quorum queues, request-reply RPC, and effectively-once dedupe.
  • UKBatch.Storage.EntityFrameworkCore — PostgreSQL and SQLite persistence with design-time migrations.
  • UKBatch.Server — a standalone, configuration-driven Docker application, plus a docker-compose setup for a server + workers deployment.

This is a 0.1.x-alpha preview. The current limitations:

  • No OpenAPI document on .NET 8. Built-in OpenAPI generation requires .NET 9+; on the net8.0 target the REST + SignalR surface is identical, but /openapi/v1.json is not produced (layer Swashbuckle yourself if needed).
  • No durable workflow resume. After a host restart, batch definitions and completed history persist (with persistent storage), but in-flight executions are marked Failed by the orphan reaper and paused approval gates do not resume.
  • No step output forwarding. A step’s output is not passed as input to subsequent steps. The cross-service HTTP sample’s orderId illustrates this: it is generated but not forwarded.
  • No cross-service progress forwarding. Per-item progress counters of a job running on a remote worker appear in the worker’s logs but do not flow back to the dashboard.
  • Rejected approval gate with successful compensation. When a gate is rejected and its compensation steps succeed, the overall run reports as Completed; the rejection is visible in the approvals history, not in the final run status.
  • In-memory transport dedupe. Transport message-dedupe caches are in-memory per process and reset on restart.
  • Single-node orphan reaper. The orphaned-execution reaper assumes a single orchestrator node.
  • Adapters not yet available. Kafka, Azure Service Bus, and Redis adapters are not part of this release.