Skip to content

release: templating, messaging pub/sub, and the workers system#8

Merged
tgiachi merged 36 commits into
mainfrom
develop
Jun 23, 2026
Merged

release: templating, messaging pub/sub, and the workers system#8
tgiachi merged 36 commits into
mainfrom
develop

Conversation

@tgiachi

@tgiachi tgiachi commented Jun 23, 2026

Copy link
Copy Markdown
Owner

Summary

Release of three feature areas merged into develop since the last release.

SquidStd.Templating

Scriban-backed templating: ITemplateRenderer for ad-hoc and named (compiled/cached) templates, startup auto-load of templates/**/*.tmpl, AddTemplating() registration, README + DocFX article.

Messaging pub/sub + EventBus bridge

Transient fan-out topics alongside the existing competing-consumers queue: ITopicProvider/IMessageTopic, in-memory and RabbitMQ (fanout exchange) providers, and a one-way Topic→EventBus bridge (TopicMessageEvent). Bundled into AddInMemoryMessaging() / AddRabbitMqMessaging().

Workers system (4 packages)

  • SquidStd.Workers.Abstractions — shared contracts: JobRequest, WorkerHeartbeat, WorkerInfo, WorkerStatusType, WorkerChannels.
  • SquidStd.Workers — runtime: consumes jobs from the queue, dispatches to named IJobHandlers up to MaxConcurrency, publishes heartbeats on a topic. AddWorkers() / AddJobHandler<T>().
  • SquidStd.Workers.Manager — enqueues jobs, folds heartbeats into an in-memory WorkerInfo registry, marks workers Offline via a timer-wheel sweep, publishes WorkerStatusChangedEvent, and exposes opt-in ASP.NET endpoints (GET /workers, GET /workers/{id}, POST /jobs). AddWorkerManager() / MapWorkerManagerEndpoints().
  • READMEs + DocFX articles for all three workers packages.

Test Plan

  • Full suite green: 576/576
  • End-to-end RabbitMQ integration test (Testcontainers): manager enqueues a job → worker consumes and runs it (real queue) → worker heartbeat reaches the manager registry (real fan-out topic)
  • Unit coverage: dispatch, concurrency cap, Idle/Busy state, registry transitions (discovered/offline/return), sweep, HTTP handlers, DI registration, contract serialization round-trips
  • Solution builds clean (one pre-existing-style CA1716 informational warning on IWorkerRegistry.Get)

tgiachi added 30 commits June 23, 2026 11:08
@github-advanced-security

Copy link
Copy Markdown
Contributor

You are seeing this message because GitHub Code Scanning has recently been set up for this repository, or this pull request contains the workflow file for the Code Scanning tool.

What Enabling Code Scanning Means:

  • The 'Security' tab will display more code scanning analysis results (e.g., for the default branch).
  • Depending on your configuration and choice of analysis tool, future pull requests will be annotated with code scanning analysis results.
  • You will be able to see the analysis results for the pull request's branch on this overview once the scans have completed and the checks have passed.

For more information about GitHub Code Scanning, check out the documentation.

[Fact]
public async Task Collector_RecordsHeartbeat_AndPublishesDiscoveredEvent()
{
var container = new Container();
[Fact]
public async Task EnqueueAsync_PublishesJobRequestToConfiguredQueue()
{
var container = new Container();

private static JobScheduler NewScheduler()
{
var container = new Container();
public async Task AddTemplating_ResolvesRendererAndRenders()
{
using var temp = new TempDirectory();
var container = new Container();
{
private static (IMessageTopic topic, WorkerState state) NewMessaging(WorkersConfig config)
{
var container = new Container();
private readonly IWorkerState _state;
private readonly TimeSpan _interval;
private readonly string _topicName;
private CancellationTokenSource? _loopCts;
Comment on lines +112 to +115
catch (Exception ex)
{
_logger.Error(ex, "Failed to publish heartbeat; will retry on the next tick.");
}
public async Task StartAsync_AutoLoadsTemplatesFromDirectory()
{
using var temp = new TempDirectory();
var emails = Path.Combine(temp.Path, "templates", "emails");
using var temp = new TempDirectory();
var emails = Path.Combine(temp.Path, "templates", "emails");
Directory.CreateDirectory(emails);
await File.WriteAllTextAsync(Path.Combine(emails, "welcome.tmpl"), "Welcome {{ user.name }}");

public Task HandleAsync(SquidStd.Workers.Abstractions.Data.JobRequest job, CancellationToken cancellationToken)
{
Interlocked.Increment(ref Calls);
@tgiachi
tgiachi merged commit 2cb8b5a into main Jun 23, 2026
3 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