Akka.NET Documentation
repository·dev·Indexed 26 days ago
https://github.com/akkadotnet/akka.netAn idiomatic .NET port of the Akka project providing a toolkit for building highly concurrent, distributed, and fault-tolerant systems using the Actor Model. Features include Akka.Streams for stream processing, Akka.Persistence for event sourcing and CQRS, Akka.Remote for location transparency, and Akka.Cluster for high availability. Includes specialized support for F# via Akka.FSharp and integration with Microsoft.Extensions via Akka.Hosting.
What's inside Akka.NET
- Akka.Persistence.Query provides a universal asynchronous stream-based query interface that allows you to query data from various journal plugins. It is primarily used to implement the 'read side' (query side) in CQRS architectures, helping to migrate or project data from the write side (Akka Persistence) to a separate query-optimized datastore.
Overview of Akka.NET capabilities
devAkka.NET is an idiomatic .NET implementation of the actor model. It is designed for high-throughput, low-latency systems and can be used for:
- Concurrency: Actors process messages one-at-a-time in FIFO order, ensuring thread-safety for internal state without manual locks.
- Stream Processing: Using Akka.NET actors and Akka.Streams to process data or live event streams.
- Event-Driven Programming: Building applications where message-processing routines express the design.
- Event Sourcing and CQRS: Using Akka.Persistence for state re-entrancy/recoverability and Akka.Persistence.Query for CQRS projections.
- Location Transparency: Using Akka.Remote to allow actors in remote processes to communicate transparently.
- Distributed Systems: Using Akka.Cluster and Akka.Cluster.Sharding to build highly available, fault-tolerant systems.
Overview of Akka.NET Libraries and Modules
devAkka.NET is a collection of integrated libraries designed to handle concurrency and distribution. The core model is based on Actors, which encapsulate both state and execution, communicating via message passing rather than method calls. This model provides a consistent way to build high-performance, concurrent, and distributed systems across all Akka.NET modules.Use Akka.NET Cluster Singleton for unique cluster services
devCluster Singleton ensures that exactly one instance of a specific service/actor runs within the entire cluster. If the host system fails, the singleton is automatically migrated to another available system. This is useful for tasks that must be centralized, though it can become a scaling bottleneck.Understand Akka Streams Back-Pressure
devAkka Streams implements an asynchronous, non-blocking back-pressure protocol based on the Reactive Streams specification. This protocol automatically manages the flow of data between stages, ensuring that a producer does not overwhelm a consumer.
Key Concepts
- Demand: The number of elements a downstream
Subscriberis able to receive and buffer. - Source (Publisher): Guarantees it will never emit more elements than the total received demand.
- Sink (Subscriber): Signals demand upstream to control the rate of data flow.
- Flow (Processor): Acts as a processing stage between a Source and a Sink.
Back-Pressure Modes
Akka Streams operates in a "dynamic push / pull mode" depending on the relative speeds of the components:
- Push-mode (Slow Publisher, Fast Subscriber): When the subscriber is faster than the publisher, the subscriber sends
Request(int n)signals frequently (often batching them). The publisher can continue producing elements as fast as possible because demand is recovered just-in-time. - Pull-mode (Fast Publisher, Slow Subscriber): When the subscriber cannot keep up, the publisher is forced to abide by the signaled demand. The publisher must then choose a strategy:
- Stop generating elements (if production rate is controllable).
- Buffer elements in a bounded manner.
- Drop elements.
- Tear down the stream.
Managing Overflow
While back-pressure is automatic, you can explicitly add buffer stages with overflow strategies to influence how the stream behaves when buffers are full. This is critical in complex graphs or those containing loops.
- Demand: The number of elements a downstream
Understand Location Transparency and RemoteActorRef
devAkka.NET provides Location Transparency through the
RemoteActorRef. This means your actor code does not need to change whether an actor is local or remote.- Behavior: A
RemoteActorRefimplementsIActorRef, making a remote actor look and feel exactly like a local one. - Implementation: When you
Tella message to aRemoteActorRef, the message is passed to a localEndpointWriter, which delivers it over the network to anEndpointReaderon the remote side. TheEndpointReaderthen routes it to the correct local actor. - Replies: When a remote actor replies using
Sender.Tell(), Akka.NET automatically creates aRemoteActorReffor the recipient, allowing the reply to travel back across the network transparently.
- Behavior: A
Understand the Actor System Hierarchy and Guardians
devAn Akka.NET actor system starts with three top-level guardians that manage different scopes:
/user(The Guardian Actor): The parent of all user-created actors. When this terminates, all normal actors in the system shut down./system(The System Guardian): Ensures an orderly shutdown so that logging (which is actor-based) remains active while user actors terminate. It watches the/userguardian and shuts down upon receiving aTerminatedmessage. Its default strategy restarts indefinitely for most exceptions, except forActorInitializationExceptionandActorKilledException./(The Root Guardian): The grandparent of all top-level actors. It usesSupervisorStrategy.StoppingStrategy(terminating children on any exception). If it fails, it escalates to the 'bubble-walker', a synthetic entity that stops the child and sets the actor system'sisTerminatedstatus totrue.
Understand Router Pools vs. Groups
devAkka.NET provides two primary ways to manage routees:
- Pools: The router creates and manages its own worker actors. You specify the number of instances, and the router handles creation. Because the router creates them, it also acts as their supervisor.
- Groups: You create the routees yourself and provide their paths to the router via configuration. The router sends messages to these paths using
ActorSelection. Group routers do not have children and do not supervise the routees; if a routee dies, the group router is unaware.
Supervision Note: Pool routers use a custom strategy that returns
Escalatefor all exceptions. If the router's parent decides to restart the router, all pool workers will be recreated.Understand Remote Deployment and Actor Paths
devIn remote deployments, an actor's supervisor might be a remote actor reference. In these cases,
context.Parent(the supervisor reference) andcontext.Path.Parent(the parent node in the actor's path) will not represent the same actor.Despite this, looking up a child's name within the supervisor will correctly find the actor on the remote node, preserving the logical hierarchy for unresolved actor references.
Use Akka.NET Persistence for state recovery and Event Sourcing
devPersistence enables actors to save their state by persisting the events that lead to that state. This allows actors to restore their state after a crash or restart by replaying the event stream.
Common use cases:
- Implementing CQRS (Command Query Responsibility Segregation).
- Implementing Event Sourcing.
- Ensuring reliable message delivery in the face of network or system failures.
Core Concepts of Akka Streams
devAkka Streams is a library for processing and transferring sequences of elements using bounded buffer space. This boundedness ensures that processing entities execute independently while only buffering a limited number of elements, preventing memory exhaustion.
Key Terminology
- Stream: An active process moving and transforming data.
- Element: The basic processing unit. Buffer sizes are expressed as a count of elements.
- Back-pressure: A non-blocking, asynchronous flow-control mechanism where consumers notify producers of their availability, slowing down the upstream to match consumption speeds.
- Graph: A description of the stream processing topology (the pathways elements follow).
- Processing Stage: The building blocks of a Graph (e.g.,
Select(),Where(),Merge,Broadcast).
Understand the MessagePack V2 serialization migration strategy
devAkka.NET is migrating subsystems from legacy Protobuf to a native source-generated MessagePack V2 serializer.
Key behaviors to note:
- Write-side control: The
serialization-bindingsconfiguration only controls which serializer is used for writes. - Read-side compatibility: Both legacy and V2 serializers are registered unconditionally on v1.6 nodes. This means a v1.6 node can decode both Protobuf and MessagePack messages regardless of which one was used to write them.
- No feature flags: There is no
v2feature flag. Migration is handled by flipping the defaultserialization-bindingsin a subsystem'sreference.conf. Operators control this via standardapplication.confoverrides. - Rolling Upgrades: For a safe v1.5 $\rightarrow$ v1.6 rolling upgrade, you should apply the
application.confoverride (pinning writes to legacy) on v1.6 nodes until all nodes in the cluster have been upgraded to v1.6.
- Write-side control: The