HoneyDrunk.Transport.StorageQueue 0.4.0

dotnet add package HoneyDrunk.Transport.StorageQueue --version 0.4.0
                    
NuGet\Install-Package HoneyDrunk.Transport.StorageQueue -Version 0.4.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="HoneyDrunk.Transport.StorageQueue" Version="0.4.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="HoneyDrunk.Transport.StorageQueue" Version="0.4.0" />
                    
Directory.Packages.props
<PackageReference Include="HoneyDrunk.Transport.StorageQueue" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add HoneyDrunk.Transport.StorageQueue --version 0.4.0
                    
#r "nuget: HoneyDrunk.Transport.StorageQueue, 0.4.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package HoneyDrunk.Transport.StorageQueue@0.4.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=HoneyDrunk.Transport.StorageQueue&version=0.4.0
                    
Install as a Cake Addin
#tool nuget:?package=HoneyDrunk.Transport.StorageQueue&version=0.4.0
                    
Install as a Cake Tool

HoneyDrunk.Transport

Validate PR License: MIT .NET 10

Reliable messaging and outbox infrastructure for the Hive - Transport unifies brokers, queues, and event buses under one contract ensuring delivery, order, and idempotence. It powers communication between Nodesβ€”Data, Pulse, Vault, and beyondβ€”so every message finds its way.

πŸ“¦ What Is This?

HoneyDrunk.Transport is the messaging backbone of HoneyDrunk.OS ("the Hive"). It provides a transport-agnostic abstraction layer over different message brokers with built-in resilience, observability, and exactly-once semantics.

What This Package Provides

  • Transport Abstraction - Unified ITransportPublisher and ITransportConsumer over Azure Service Bus, Azure Storage Queue, and InMemory
  • Middleware Pipeline - Onion-style message processing with logging, telemetry, correlation, and retry
  • Envelope Pattern - Immutable ITransportEnvelope with correlation/causation tracking and Grid context propagation
  • Grid Context Integration - Uses IGridContext from HoneyDrunk.Kernel for distributed context propagation
  • Transactional Outbox - IOutboxStore and IOutboxDispatcher contracts for exactly-once processing
  • Health Contributors - ITransportHealthContributor for Kubernetes probe integration
  • Observability - OpenTelemetry spans via ITransportMetrics and built-in telemetry middleware
  • Blob Fallback - Persist failed Service Bus publishes to Azure Blob Storage for later replay

What This Package Does Not Provide

  • Automatic message routing β€” Application responsibility; no built-in routing conventions
  • Message schema registry β€” No schema validation or evolution support in v0.1.0
  • Distributed transactions β€” Outbox provides eventual consistency, not two-phase commit
  • Non-Azure provider implementations β€” RabbitMQ and Kafka are planned but not available

⚠️ v0.1.0 Limitations

The following features exist as contracts only or have limitations in v0.1.0:

Feature Contract v0.1.0 Status
Transport publishing ITransportPublisher βœ… Implemented for Service Bus, Storage Queue, InMemory
Transport consuming ITransportConsumer βœ… Implemented for Service Bus, Storage Queue, InMemory
Transactional outbox IOutboxStore ⚠️ Contract only β€” application must implement against their database
Outbox dispatching IOutboxDispatcher βœ… DefaultOutboxDispatcher provided
Health aggregation ITransportHealthContributor ⚠️ Contributors exist β€” application wires into health system
Message serialization IMessageSerializer βœ… JsonMessageSerializer provided as default

Bottom line: v0.1.0 provides complete transport abstraction with Azure providers. Applications must implement:

  • IOutboxStore if using transactional outbox pattern (database-specific)
  • Health endpoint wiring for contributor aggregation
  • Custom IMessageSerializer if JSON is not suitable

πŸš€ Quick Start

Installation

# Azure Service Bus transport
dotnet add package HoneyDrunk.Transport.AzureServiceBus

# Or Azure Storage Queue transport
dotnet add package HoneyDrunk.Transport.StorageQueue

# Or InMemory transport (for testing)
dotnet add package HoneyDrunk.Transport.InMemory

# Or just the core abstractions (contracts only)
dotnet add package HoneyDrunk.Transport

Web API Setup

This example shows a web application with Kernel and Azure Service Bus. Simpler setups are possibleβ€”see package-specific documentation.

Registration order matters. Kernel must be registered before Transport. See DependencyInjection.md for details.

using HoneyDrunk.Kernel.DependencyInjection;
using HoneyDrunk.Transport.DependencyInjection;

var builder = WebApplication.CreateBuilder(args);

// 1. Kernel (required for Grid context)
builder.Services.AddHoneyDrunkCoreNode(nodeDescriptor);

// 2. Transport core (middleware pipeline, envelope factory)
builder.Services.AddHoneyDrunkTransportCore(options =>
{
    options.EnableTelemetry = true;
    options.EnableLogging = true;
});

// 3. Azure Service Bus provider
builder.Services.AddHoneyDrunkServiceBusTransport(options =>
{
    options.FullyQualifiedNamespace = "mynamespace.servicebus.windows.net";
    options.Address = "orders";
    options.EntityType = ServiceBusEntityType.Topic;
    options.SubscriptionName = "order-processor";
    options.MaxConcurrency = 10;
});

// 4. Register message handlers
builder.Services.AddMessageHandler<OrderCreatedEvent, OrderCreatedHandler>();

var app = builder.Build();
app.Run();

Abstractions-Only Usage

For libraries that only need contracts without runtime dependencies:

// Reference only HoneyDrunk.Transport
// No Kernel runtime, no broker SDK dependencies

public class OrderService
{
    private readonly ITransportPublisher _publisher;
    private readonly EnvelopeFactory _envelopeFactory;
    private readonly IMessageSerializer _serializer;

    public async Task PublishOrderCreatedAsync(Order order, CancellationToken ct)
    {
        var @event = new OrderCreatedEvent { OrderId = order.Id };
        var payload = _serializer.Serialize(@event);
        var envelope = _envelopeFactory.CreateEnvelope<OrderCreatedEvent>(payload);
        
        await _publisher.PublishAsync(
            envelope,
            EndpointAddress.Create("orders", "orders-topic"),
            ct);
    }
}

🎯 Key Features (v0.1.0)

πŸ“¨ Transport Envelope Pattern

All messages are wrapped in immutable ITransportEnvelope for distributed tracing:

public interface ITransportEnvelope
{
    string MessageId { get; }
    string? CorrelationId { get; }
    string? CausationId { get; }
    string MessageType { get; }
    ReadOnlyMemory<byte> Payload { get; }
    IReadOnlyDictionary<string, string> Headers { get; }
    DateTimeOffset Timestamp { get; }
}

// Create envelopes via factory (integrates with TimeProvider and Grid context)
var envelope = envelopeFactory.CreateEnvelopeWithGridContext<OrderCreatedEvent>(
    payload, gridContext);

Note: Always use EnvelopeFactory to create envelopes. It integrates with TimeProvider for deterministic timestamps and IGridContext for distributed context propagation.

πŸ”— Grid Context Integration

Transport is fully integrated with Kernel's IGridContext for distributed context propagation:

public class OrderCreatedHandler : IMessageHandler<OrderCreatedEvent>
{
    public async Task<MessageProcessingResult> HandleAsync(
        OrderCreatedEvent message,
        MessageContext context,
        CancellationToken ct)
    {
        // Access Grid context directly from MessageContext
        var grid = context.GridContext;
        
        _logger.LogInformation(
            "Processing order {OrderId} with CorrelationId {CorrelationId} on Node {NodeId}",
            message.OrderId,
            grid?.CorrelationId,
            grid?.NodeId);
        
        return MessageProcessingResult.Success;
    }
}

Note: Grid context is extracted from envelope headers by GridContextPropagationMiddleware and populated in MessageContext automatically.

πŸ§… Middleware Pipeline

Message processing follows an onion-style middleware pattern:

// Built-in middleware (executed in order)
// 1. GridContextPropagationMiddleware - Extracts IGridContext from envelope
// 2. TelemetryMiddleware - Distributed tracing via OpenTelemetry
// 3. LoggingMiddleware - Structured logging of message processing

// Custom middleware registration
builder.Services.AddHoneyDrunkTransportCore()
    .AddMiddleware<CustomRetryMiddleware>()
    .AddMiddleware<CustomValidationMiddleware>();

Note: Middleware order matters. GridContextPropagation must run before telemetry to ensure correlation IDs are available for tracing.

πŸ“€ Transactional Outbox

For exactly-once processing with database transactions:

public class OrderService(
    IOutboxStore outboxStore,
    EnvelopeFactory factory,
    IMessageSerializer serializer,
    IDbContext dbContext)
{
    public async Task CreateOrderAsync(CreateOrderCommand command, CancellationToken ct)
    {
        await using var transaction = await dbContext.BeginTransactionAsync(ct);
        
        // Save order to database
        var order = new Order { /* ... */ };
        await dbContext.Orders.AddAsync(order, ct);
        
        // Save message to outbox (same transaction)
        var payload = serializer.Serialize(new OrderCreatedEvent { OrderId = order.Id });
        var envelope = factory.CreateEnvelope<OrderCreatedEvent>(payload);
        
        await outboxStore.SaveAsync(
            EndpointAddress.Create("orders", "orders-topic"),
            envelope, ct);
        
        await dbContext.SaveChangesAsync(ct);
        await transaction.CommitAsync(ct);
        
        // DefaultOutboxDispatcher publishes from outbox in background
    }
}

Note: IOutboxStore is a contractβ€”application must implement against their database. DefaultOutboxDispatcher polls the store and publishes pending messages.

πŸ₯ Health Contributors

Transport providers include health monitoring for Kubernetes probes:

public interface ITransportHealthContributor
{
    string Name { get; }
    ValueTask<TransportHealthResult> CheckHealthAsync(CancellationToken ct);
}

// Each transport registers its own contributor
// - ServiceBusHealthContributor
// - StorageQueueHealthContributor
// - InMemoryHealthContributor

Note: Health contributors are passiveβ€”invoked by host health system on demand. Applications wire contributors into their health check infrastructure.


βš–οΈ Storage Queue vs Service Bus

Scenario Storage Queue Service Bus
Cost optimization βœ… $0.0004/10K ops ❌ Higher cost
High volume (millions/day) βœ… Excellent βœ… Good
Simple queue semantics βœ… Yes βœ… Yes
Message size < 64KB βœ… Yes βœ… Up to 100MB
Topics/subscriptions (fan-out) ❌ No βœ… Yes
Sessions (ordered processing) ❌ No βœ… Yes
Transactions ❌ No βœ… Yes
Duplicate detection ❌ No βœ… Yes

Choose Storage Queue for cost-effective, high-volume, simple queue scenarios.
Choose Service Bus for enterprise messaging with topics, sessions, or transactions.


πŸ“– Documentation

Package Documentation

  • Architecture - High-level architecture and design principles
  • Abstractions - Core contracts: ITransportEnvelope, IMessageHandler, MessageContext
  • Pipeline - Middleware pipeline and built-in middleware
  • Configuration - All options: TransportCoreOptions, RetryOptions, error strategies
  • Context - Grid context propagation and IGridContextFactory
  • Primitives - EnvelopeFactory, TransportEnvelope, serialization
  • Outbox - Transactional outbox pattern

Transport Providers

  • AzureServiceBus - Service Bus transport: sessions, topics, blob fallback
  • StorageQueue - Storage Queue transport: concurrency model, poison queues
  • InMemory - InMemory transport for testing

Runtime & Observability

  • Runtime - ITransportRuntime and consumer lifecycle
  • Health - Health monitoring with ITransportHealthContributor
  • Metrics - ITransportMetrics and OpenTelemetry integration
  • Testing - Test patterns and helpers

πŸ—οΈ Project Structure

HoneyDrunk.Transport/
β”œβ”€β”€ HoneyDrunk.Transport/                    # Core abstractions & pipeline
β”‚   β”œβ”€β”€ Abstractions/                        # Publisher, consumer, handler contracts
β”‚   β”œβ”€β”€ Pipeline/                            # Middleware execution engine
β”‚   β”œβ”€β”€ Configuration/                       # TransportCoreOptions, RetryOptions
β”‚   β”œβ”€β”€ Context/                             # Grid context factory and propagation
β”‚   β”œβ”€β”€ Primitives/                          # EnvelopeFactory, TransportEnvelope
β”‚   β”œβ”€β”€ Outbox/                              # IOutboxStore, DefaultOutboxDispatcher
β”‚   β”œβ”€β”€ Runtime/                             # ITransportRuntime host
β”‚   β”œβ”€β”€ Health/                              # ITransportHealthContributor
β”‚   β”œβ”€β”€ Metrics/                             # ITransportMetrics
β”‚   β”œβ”€β”€ Telemetry/                           # OpenTelemetry integration
β”‚   └── DependencyInjection/                 # AddHoneyDrunkTransportCore()
β”‚
β”œβ”€β”€ HoneyDrunk.Transport.AzureServiceBus/    # Azure Service Bus provider
β”‚   β”œβ”€β”€ Publishing/                          # ServiceBusTransportPublisher
β”‚   β”œβ”€β”€ Consuming/                           # ServiceBusTransportConsumer
β”‚   β”œβ”€β”€ BlobFallback/                        # Blob storage for failed publishes
β”‚   β”œβ”€β”€ Health/                              # ServiceBusHealthContributor
β”‚   └── DependencyInjection/                 # AddHoneyDrunkServiceBusTransport()
β”‚
β”œβ”€β”€ HoneyDrunk.Transport.StorageQueue/       # Azure Storage Queue provider
β”‚   β”œβ”€β”€ Publishing/                          # StorageQueueTransportPublisher
β”‚   β”œβ”€β”€ Consuming/                           # StorageQueueTransportConsumer
β”‚   β”œβ”€β”€ Health/                              # StorageQueueHealthContributor
β”‚   └── DependencyInjection/                 # AddHoneyDrunkTransportStorageQueue()
β”‚
β”œβ”€β”€ HoneyDrunk.Transport.InMemory/           # In-memory provider (testing)
β”‚   β”œβ”€β”€ InMemoryBroker                       # Thread-safe in-memory message store
β”‚   β”œβ”€β”€ Health/                              # InMemoryHealthContributor
β”‚   └── DependencyInjection/                 # AddHoneyDrunkInMemoryTransport()
β”‚
└── HoneyDrunk.Transport.Tests/              # xUnit test suite

πŸ†• What's New in v0.1.0

Core Transport

  • ITransportPublisher and ITransportConsumer transport abstraction
  • ITransportEnvelope immutable message wrapper with Grid context
  • EnvelopeFactory integrating TimeProvider and IGridContext
  • IMessagePipeline with onion-style middleware execution
  • IMessageHandler<T> and MessageProcessingResult for handler contracts
  • GridContextPropagationMiddleware, TelemetryMiddleware, LoggingMiddleware
  • IOutboxStore and DefaultOutboxDispatcher for transactional outbox
  • ITransportHealthContributor for health check participation
  • ITransportMetrics for OpenTelemetry integration

Azure Service Bus Provider

  • ServiceBusTransportPublisher with topic and queue support
  • ServiceBusTransportConsumer with session and subscription support
  • BlobFallbackPublisher for failed publish persistence
  • ServiceBusHealthContributor for connectivity health checks
  • AzureServiceBusOptions with retry and prefetch configuration

Azure Storage Queue Provider

  • StorageQueueTransportPublisher with base64 encoding
  • StorageQueueTransportConsumer with concurrent polling
  • StorageQueueHealthContributor for connectivity health checks
  • StorageQueueOptions with dequeue count and visibility timeout

InMemory Provider

  • InMemoryBroker thread-safe message store for testing
  • InMemoryTransportPublisher and InMemoryTransportConsumer
  • InMemoryHealthContributor always-healthy contributor

Project Relationship
HoneyDrunk.Kernel Transport depends on Kernel for IGridContext and TimeProvider
HoneyDrunk.Standards Analyzers and coding conventions
HoneyDrunk.Data Data access and persistence (in development)
HoneyDrunk.Auth Authentication and authorization (in development)

Note: HoneyDrunk.Transport depends only on HoneyDrunk.Kernel.Abstractions (contracts, no runtime). Transport providers depend on their respective Azure SDKs.


πŸ“„ License

This project is licensed under the MIT License.


<div align="center">

Built with 🍯 by HoneyDrunk Studios

GitHub β€’ Issues

</div>

Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
0.4.0 96 1/25/2026
0.3.1 94 1/18/2026
0.3.0 428 12/8/2025
0.2.0 175 11/22/2025
0.1.3 418 11/18/2025
0.1.2 407 11/17/2025

v0.4.0: Kernel v0.4.0 upgrade with IGridContext.AddBaggage() API change, fail-fast envelope validation, and updated Azure.Storage.Queues to 12.25.0.