HoneyDrunk.Transport.StorageQueue 0.3.0

There is a newer version of this package available.
See the version list below for details.
dotnet add package HoneyDrunk.Transport.StorageQueue --version 0.3.0
                    
NuGet\Install-Package HoneyDrunk.Transport.StorageQueue -Version 0.3.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.3.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.3.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.3.0
                    
#r "nuget: HoneyDrunk.Transport.StorageQueue, 0.3.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.3.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.3.0
                    
Install as a Cake Addin
#tool nuget:?package=HoneyDrunk.Transport.StorageQueue&version=0.3.0
                    
Install as a Cake Tool

HoneyDrunk.Transport

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.

Signal Quote: "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:

  • βœ… Transport Abstraction - Unified ITransportPublisher and ITransportConsumer over Azure Service Bus, Azure Storage Queue, and InMemory
  • βœ… Middleware Pipeline - Onion-style processing with logging, telemetry, correlation, and retry
  • βœ… Envelope Pattern - Immutable ITransportEnvelope with correlation/causation tracking
  • βœ… Transactional Outbox - Exactly-once processing with database transactions
  • βœ… Kernel Integration - Uses TimeProvider and IGridContext from HoneyDrunk.Kernel for deterministic timestamps and distributed context
  • βœ… Observability - OpenTelemetry spans and pluggable ITransportMetrics
  • βœ… Blob Fallback for Service Bus - Persist failed publishes to Azure Blob Storage for later replay

πŸš€ Quick Start

Installation

<ItemGroup>
  <PackageReference Include="HoneyDrunk.Transport" Version="0.1.0" />
  <PackageReference Include="HoneyDrunk.Transport.AzureServiceBus" Version="0.1.0" />
  <PackageReference Include="HoneyDrunk.Transport.StorageQueue" Version="0.1.0" />
  <PackageReference Include="HoneyDrunk.Transport.InMemory" Version="0.1.0" />
</ItemGroup>

Configure in Program.cs

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

var builder = WebApplication.CreateBuilder(args);

// 1. Register Kernel node
builder.Services.AddHoneyDrunkCoreNode(nodeDescriptor);

// 2. Register Transport core
builder.Services.AddHoneyDrunkTransportCore(options =>
{
    options.EnableTelemetry = true;
    options.EnableLogging = true;
    options.EnableCorrelation = true;
});

// 3. Choose a transport

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

    options.ServiceBusRetry.Mode = ServiceBusRetryMode.Exponential;
    options.ServiceBusRetry.MaxRetries = 3;
});

// OR Azure Storage Queue
builder.Services
    .AddHoneyDrunkTransportStorageQueue(
        builder.Configuration["StorageQueue:ConnectionString"]!,
        "orders")
    .WithMaxDequeueCount(5)
    .WithConcurrency(10);

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

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

πŸ“– Usage Examples

Publishing Messages

public class OrderService(
    ITransportPublisher publisher,
    EnvelopeFactory envelopeFactory,
    IMessageSerializer serializer,
    IGridContext gridContext)
{
    public async Task CreateOrderAsync(CreateOrderCommand command, CancellationToken ct)
    {
        // Create order...
        
        // Publish event
        var @event = new OrderCreatedEvent { OrderId = orderId, Total = total };
        var payload = serializer.Serialize(@event);
        var envelope = envelopeFactory.CreateEnvelopeWithGridContext<OrderCreatedEvent>(
            payload, gridContext);
        
        await publisher.PublishAsync(
            envelope,
            EndpointAddress.Create("orders", "orders-topic"),
            ct);
    }
}

Handling Messages

public class OrderCreatedHandler : IMessageHandler<OrderCreatedEvent>
{
    private readonly ILogger<OrderCreatedHandler> _logger;
    
    public OrderCreatedHandler(ILogger<OrderCreatedHandler> logger)
    {
        _logger = logger;
    }
    
    public async Task<MessageProcessingResult> HandleAsync(
        OrderCreatedEvent message,
        MessageContext context,
        CancellationToken cancellationToken)
    {
        var grid = context.GridContext;
        
        _logger.LogInformation(
            "Processing order {OrderId} with CorrelationId {CorrelationId} on Node {NodeId}",
            message.OrderId,
            grid?.CorrelationId,
            grid?.NodeId);
        
        await SendConfirmationEmailAsync(message.OrderId, cancellationToken);
        return MessageProcessingResult.Success;
    }
}

Transactional Outbox

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);
        
        try
        {
            // 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);
            var destination = EndpointAddress.Create("orders", "orders-topic");
            
            await outboxStore.SaveAsync(destination, envelope, ct);
            
            await dbContext.SaveChangesAsync(ct);
            await transaction.CommitAsync(ct);
            
            // DefaultOutboxDispatcher publishes from outbox in background
        }
        catch
        {
            await transaction.RollbackAsync(ct);
            throw;
        }
    }
}

🎯 Features

πŸ” Core Components

Component Purpose Key Types
Transport Abstraction Unified publisher/consumer interface ITransportPublisher, ITransportConsumer
Message Pipeline Middleware execution engine IMessagePipeline, IMessageMiddleware
Envelope System Immutable message wrapping ITransportEnvelope, EnvelopeFactory
Grid Context Correlation/causation tracking IGridContext, IGridContextFactory
Serialization Pluggable message serialization IMessageSerializer, JsonMessageSerializer
Outbox Pattern Transactional outbox support IOutboxStore, DefaultOutboxDispatcher

πŸ”— Kernel Integration

HoneyDrunk.Transport extends HoneyDrunk.Kernel with messaging primitives:

Kernel Service How Transport Uses It
TimeProvider Deterministic message timestamps via EnvelopeFactory
IGridContext Correlation, causation, Node/Studio/Tenant propagation
IGridContextFactory Creates Grid context for outbound messages
ILogger<T> Structured logging throughout pipeline
IMeterFactory OpenTelemetry metrics via ITransportMetrics

πŸš€ Available Transports

Transport Package Status
Azure Service Bus HoneyDrunk.Transport.AzureServiceBus βœ… Available
Azure Storage Queue HoneyDrunk.Transport.StorageQueue βœ… Available
In-Memory HoneyDrunk.Transport.InMemory βœ… Available (Testing)
RabbitMQ HoneyDrunk.Transport.RabbitMQ 🚧 Planned
Kafka HoneyDrunk.Transport.Kafka 🚧 Planned

πŸ§ͺ Testing

Use InMemory transport and DI for tests:

var services = new ServiceCollection();
services.AddHoneyDrunkCoreNode(TestNodeDescriptor);
services.AddHoneyDrunkTransportCore()
    .AddHoneyDrunkInMemoryTransport();

services.AddMessageHandler<OrderCreatedEvent>((msg, ctx, ct) =>
{
    // Assert in handler
    return Task.FromResult(MessageProcessingResult.Success);
});

await using var provider = services.BuildServiceProvider();

var broker = provider.GetRequiredService<InMemoryBroker>();
var publisher = provider.GetRequiredService<ITransportPublisher>();
var pipeline = provider.GetRequiredService<IMessagePipeline>();

// Use broker for broker-level tests, pipeline for pipeline-level tests

See Testing.md for complete patterns including unit tests, integration tests, and test helpers.


πŸ“š Documentation

Document Description
Architecture.md High-level architecture and design principles
Abstractions.md Core contracts: ITransportEnvelope, IMessageHandler, MessageContext
Pipeline.md Middleware pipeline and built-in middleware
Configuration.md All options: TransportCoreOptions, RetryOptions, error strategies
Context.md Grid context propagation and IGridContextFactory
Primitives.md EnvelopeFactory, TransportEnvelope, serialization
AzureServiceBus.md Service Bus transport: sessions, topics, blob fallback
StorageQueue.md Storage Queue transport: concurrency model, poison queues
InMemory.md InMemory transport for testing
Outbox.md Transactional outbox pattern
Runtime.md ITransportRuntime and consumer lifecycle
Health.md Health monitoring with ITransportHealthContributor
Metrics.md ITransportMetrics and OpenTelemetry integration
Testing.md Test patterns and helpers

πŸ› οΈ Repository Layout

HoneyDrunk.Transport/
β”œβ”€β”€ HoneyDrunk.Transport/                    # Core abstractions & pipeline
β”‚   β”œβ”€β”€ Abstractions/                        # Contracts & interfaces
β”‚   β”œβ”€β”€ Pipeline/                            # Middleware execution engine
β”‚   β”œβ”€β”€ Configuration/                       # Options & settings
β”‚   β”œβ”€β”€ Context/                             # Grid context integration
β”‚   β”œβ”€β”€ Primitives/                          # Envelope & factory
β”‚   β”œβ”€β”€ Outbox/                              # Transactional outbox
β”‚   β”œβ”€β”€ Runtime/                             # ITransportRuntime host
β”‚   β”œβ”€β”€ Health/                              # Health contributors
β”‚   β”œβ”€β”€ Metrics/                             # ITransportMetrics
β”‚   β”œβ”€β”€ Telemetry/                           # OpenTelemetry integration
β”‚   └── DependencyInjection/                 # DI registration
β”œβ”€β”€ HoneyDrunk.Transport.AzureServiceBus/    # Azure Service Bus provider
β”œβ”€β”€ HoneyDrunk.Transport.StorageQueue/       # Azure Storage Queue provider
β”œβ”€β”€ HoneyDrunk.Transport.InMemory/           # In-memory provider
β”œβ”€β”€ HoneyDrunk.Transport.Tests/              # Test project
└── docs/                                    # Documentation

βš–οΈ 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.


πŸ“„ License

MIT

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.7.1 94 5/27/2026
0.7.0 90 5/26/2026
0.6.0 94 5/18/2026
0.5.0 101 5/4/2026
0.4.0 123 1/25/2026
0.3.1 117 1/18/2026
0.3.0 451 12/8/2025
0.2.0 196 11/22/2025
0.1.3 439 11/18/2025
0.1.2 430 11/17/2025

v0.3.0: BREAKING - Kernel v0.3.0 integration with TenantId/ProjectId in JSON envelope schema. Drain queues before upgrading. See CHANGELOG.md.