Skip to content

Latest commit

 

History

73 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Kuestenlogik.Bowire.Protocol.Akka

CI codecov NuGet License Bowire

Bowire protocol plugin for Akka.NET actor systems. Streams every message that lands in a tap-mailboxed actor's mailbox — plus the actor system's dead letters — into the Bowire workbench, so you can watch a live actor system the same way you watch gRPC streams or MQTT topics.

What it does

  • Mailbox tap — a custom Akka.NET MailboxType (BowireTapMailbox) wraps the standard unbounded queue and forwards every enqueue to a per-actor-system extension. Opt in globally (default-mailbox swap) or per actor (Props.WithMailbox(...)).
  • DeadLetters capture — the extension subscribes to the actor system's EventStream and republishes every Akka.Event.DeadLetter through the same channel with IsDeadLetter = true, so undeliverable messages surface without any per-actor opt-in.
  • IExtension integrationBowireAkkaExtension owns the active subscriber list and the dead-letter bridge. When nobody is watching, each enqueue costs a single subscriber-count check; the message is only marshalled once at least one subscriber is attached.
  • Bowire streaming paneBowireAkkaProtocol exposes one server-streaming method, Tap/MonitorMessages, that yields TappedMessage envelopes as JSON.

How it works

actor mailbox ─enqueue─▶ BowireTapMailbox ─▶ BowireAkkaExtension ─fan-out─▶ subscriber channels ─▶ Tap/MonitorMessages ─JSON─▶ Bowire UI
                                                    ▲
             EventStream DeadLetter ────────────────┘

BowireTapMailbox wraps Akka's UnboundedMessageQueue; the dequeue path is untouched, so the tap never changes delivery order or semantics. On each enqueue it hands a TappedMessage to the process-wide BowireAkkaExtension, which fans out to every subscribed Bowire client over a bounded, drop-oldest channel — a slow viewer can never stall the actor system. Dead letters reach the same fan-out through an EventStream subscription.

Requirements

  • .NET 10
  • Akka.NET ≥ 1.5
  • A Bowire-enabled host — Kuestenlogik.Bowire ≥ 2.2.1, < 3.0 (see the compatibility matrix)

Install

dotnet add package Kuestenlogik.Bowire.Protocol.Akka

Use

1. Register the actor system in DI

using Akka.Actor;
using Microsoft.Extensions.DependencyInjection;

var system = ActorSystem.Create("MyApp", hocon);
builder.Services.AddSingleton(system);
builder.Services.AddBowire(); // discovers this plugin automatically

2. Opt actors into the tap mailbox

Per actor — surgical, and keeps dead-letter capture working:

akka.actor.bowire-tap = {
  mailbox-type = "Kuestenlogik.Bowire.Protocol.Akka.BowireTapMailbox, Kuestenlogik.Bowire.Protocol.Akka"
}
var orders = system.ActorOf(
    Props.Create<OrdersActor>().WithMailbox("akka.actor.bowire-tap"),
    "orders");

Globally — every actor created afterwards is tapped:

akka.actor.default-mailbox.mailbox-type = "Kuestenlogik.Bowire.Protocol.Akka.BowireTapMailbox, Kuestenlogik.Bowire.Protocol.Akka"

Note — as the global default mailbox, BowireTapMailbox is created for the root guardian during bootstrap, before the actor system is navigable. The extension degrades gracefully there: live mailbox taps work end-to-end, but dead-letter capture is silently disabled. Use the per-actor (or a named-mailbox) opt-in if you need dead letters in the stream.

3. Watch in Bowire

Open the Bowire workbench (/bowire in embedded mode, or the bowire CLI), pick the Akka.NET tab, and stream Tap/MonitorMessages. Every message landing in a tapped mailbox — and every dead letter — appears in real time.

The envelope

Each observation is a TappedMessage, serialized to JSON:

{
  "Recipient": "akka://Harbor/user/dock-1",
  "Sender": "akka://Harbor/user/harbor-master",
  "MessageType": "Kuestenlogik.Bowire.Protocol.Akka.Sample.Actors.ScheduleArrival",
  "Payload": "ScheduleArrival { ShipId = 101, ShipName = Nordstern }",
  "Timestamp": "2026-07-06T09:14:22.187Z",
  "IsDeadLetter": false
}

Payload is a best-effort ToString() rendering today; typed serializer round-tripping is on the roadmap.

Sample

A runnable end-to-end sample lives under samples/Kuestenlogik.Bowire.Protocol.Akka.Sample — three actors in a small harbour workflow plus a 2-second port-call ticker, so the live stream is never quiet.

dotnet run --project samples/Kuestenlogik.Bowire.Protocol.Akka.Sample

Then open http://localhost:5080/bowire and stream the Akka.NET tab.

Documentation

  • ROADMAP.md — shipped and planned versions
  • COVERAGE.md — what the plugin taps from Akka's surface, and what it deliberately doesn't (yet)

License

Apache-2.0

About

Akka.NET protocol plugin for Bowire — taps every message landing in a BowireTapMailbox-wrapped actor plus the system's DeadLetters event stream, and surfaces them as a Bowire workbench stream.

Topics

Resources

Code of conduct

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages