Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[DOC] Add Akka.Analyzers AK1006 documentation #7205

Merged
merged 4 commits into from
May 24, 2024

Conversation

Arkatufus
Copy link
Contributor


uid: AK1006
title: Akka.Analyzers Rule AK1006 - "Should not call Persist() or PersistAsync() inside a loop"

AK1006 - Warning

Calling Persist() or PersistAsync() inside a loop is an anti-pattern and is non-performant. Consider collecting all events in a collection and then call PersistAll() or PersistAllAsync() after the loop instead.

Cause

Akka.NET persistence tries its best to batch consecutive calls to Persist() or PersistAsync() methods, but there is no guarantee that all of them will be batched properly.

For example, lets assume that for each command, you generate 10 Persist() operations. This can potentially create 10 asynchronous database connection to complete:

using Akka.Persistence;

public class MyActor: ReceivePersistentActor
{
    public override string PersistenceId { get; }
    public MyActor(string persistenceId)
    {
        PersistenceId = persistenceId;
        CommandAny(obj =>
        {
            for (var i=0; i<10; i++)
            {
                Persist(i, o => {});
            }
        });
    }
}

Resolution

If you know that a group of events need to be batched, it is a lot more performant to batch all Persist() operations into a single PersistAll() operation after the loop

using Akka.Persistence;

public class MyActor: ReceivePersistentActor
{
    public override string PersistenceId { get; }
    public MyActor(string persistenceId)
    {
        PersistenceId = persistenceId;
        CommandAny(obj =>
        {
            var events = new List<int>();
            for (var i=0; i<10; i++)
            {
                events.Add(i);
            }
            PersistAll(events, o => {});
        });
    }
}

The persist success callback will be called for each event that are successfully persisted, so you do not need to change your logic inside the callback.

Copy link
Member

@Aaronontheweb Aaronontheweb left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@Aaronontheweb Aaronontheweb enabled auto-merge (squash) May 24, 2024 19:40
@Aaronontheweb Aaronontheweb added docs rosyln-analyzer Issues that should be addressed via user-exposed Roslyn analyzers. labels May 24, 2024
@Aaronontheweb Aaronontheweb added this to the 1.5.21 milestone May 24, 2024
@Aaronontheweb Aaronontheweb merged commit ef04e3a into akkadotnet:dev May 24, 2024
12 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
docs rosyln-analyzer Issues that should be addressed via user-exposed Roslyn analyzers.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants