akka-aspire-configurat…
Configure Akka.NET with .NET Aspire for local development and production deployments. Covers actor system setup, clustering, persistence, Akka.Management…
Critical Akka.NET best practices including EventStream vs DistributedPubSub, supervision strategies, error handling, Props vs DependencyResolver, work distribution patterns, and cluster/local mode abstractions for testability.
$ npx -y skills add aaronontheweb/dotnet-skills --skill akka-best-practices --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
/akka-best-practicesContext preview
The summary Claude sees to decide when to auto-load this skill.
Critical Akka.NET best practices including EventStream vs DistributedPubSub, supervision strategies, error handling, Props vs DependencyResolver, work distribution patterns, and cluster/local mode abstractions for testability.
name: akka-net-best-practices description: Critical Akka.NET best practices including EventStream vs DistributedPubSub, supervision strategies, error handling, Props vs DependencyResolver, work distribution patterns, and cluster/local mode abstractions for testability. invocable: false
Use this skill when:
---
`Context.System.EventStream` is **local to a single ActorSystem process**. It does NOT work across cluster nodes.
// BAD: This only works on a single server // When you add a second server, subscribers on server 2 won't receive events from server 1 Context.System.EventStream.Subscribe(Self, typeof(PostCreated)); Context.System.EventStream.Publish(new PostCreated(postId, authorId));
**When EventStream is appropriate:**
For events that must reach actors across multiple cluster nodes, use `Akka.Cluster.Tools.PublishSubscribe`:
using Akka.Cluster.Tools.PublishSubscribe;
public class TimelineUpdatePublisher : ReceiveActor
{
private readonly IActorRef _mediator;
public TimelineUpdatePublisher()
{
// Get the DistributedPubSub mediator
_mediator = DistributedPubSub.Get(Context.System).Mediator;
Receive<PublishTimelineUpdate>(msg =>
{
// Publish to a topic - reaches all subscribers across all nodes
_mediator.Tell(new Publish($"timeline:{msg.UserId}", msg.Update));
});
}
}builder.WithDistributedPubSub(role: null); // Available on all roles, or specify a role
| Pattern | Topic Format | Use Case | |---------|--------------|----------| | Per-user | `timeline:{userId}` | Timeline updates, notifications | | Per-entity | `post:{postId}` | Post engagement updates | | Broadcast | `system:announcements` | System-wide notifications | | Role-based | `workers:rss-poller` | Work distribution |
---
A supervision strategy defined on an actor dictates **how that actor supervises its children**, NOT how the actor itself is supervised.
public class ParentActor : ReceiveActor
{
// This strategy applies to children of ParentActor, NOT to ParentActor itself
protected override SupervisorStrategy SupervisorStrategy()
{
return new OneForOneStrategy(
maxNrOfRetries: 10,
withinTimeRange: TimeSpan.FromSeconds(30),
decider: ex => ex switch
{
ArithmeticException => Directive.Resume,
NullReferenceException => Directive.Restart,
ArgumentException => Directive.Stop,
_ => Directive.Escalate
});
}
}The default `OneForOneStrategy` already includes rate limiting:
**You rarely need a custom strategy** unless you have specific requirements.
**Good reasons:**
**Bad reasons:**
---
**Use try-catch when:**
public class RssFeedPollerActor : ReceiveActor
{
public RssFeedPollerActor()
{
ReceiveAsync<PollFeed>(async msg =>
{
try
{
var feed = await _httpClient.GetStringAsync(msg.FeedUrl);
var items = ParseFeed(feed);
// Process items...
}
catch (HttpRequestException ex)
{
// Expected failure - log and schedule retry
_log.Warning("Feed {Url} unavailable: {Error}", msg.FeedUrl, ex.Message);
Context.System.Scheduler.ScheduleTellOnce(
TimeSpan.FromMinutes(5), Self, msg, Self);
}
catch (XmlException ex)
{
// Invalid feed format - log and mark as bad
_log.Error("Feed {Url} has invalid format: {Error}", msg.FeedUrl, ex.Message);
Sender.Tell(newA comprehensive AI coding plugin with 30 skills and 5 specialized agents for professional .NET development. Battle-tested patterns from production systems covering C#, Akka.NET, Aspire, EF Core, testing, and performance optimization.
Configure Akka.NET with .NET Aspire for local development and production deployments. Covers actor system setup, clustering, persistence, Akka.Management…
Patterns for building entity actors with Akka.Hosting - GenericChildPerEntityParent, message extractors, cluster sharding abstraction, akka-reminders, and…
Akka.Management for cluster bootstrapping, service discovery (Kubernetes, Azure, Config), health checks, and dynamic cluster formation without static seed…
Write unit and integration tests for Akka.NET actors using modern Akka.Hosting.TestKit patterns. Covers dependency injection, TestProbes, persistence testing,…
Guidelines for making .NET libraries and applications trimming-safe and Native AOT compatible. Covers the trimming/AOT model, the MSBuild properties that…
Configure Aspire AppHost to emit explicit app config via environment variables; keep app code free of Aspire clients and service discovery.