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

Error while recovering snapshots for actors with particular format for PersistenceId #7009

Closed
marcotod1410 opened this issue Nov 29, 2023 · 1 comment · Fixed by #7040
Closed

Comments

@marcotod1410
Copy link

Version Information
Akka.NET 1.4.49
Akka.NET.Persistence 1.4.49

Also replicated with:
Akka.NET 1.5.14
Akka.NET.Persistence 1.5.14

Describe the bug
I've got two actors with saved snapshots. When recovering them, it gives Error loading snapshot error from Akka.NET.
This seems to happen only if the PersistenceId of any actor contains hyphens.

To Reproduce
Paste the following code in a new C# console application project (no akka.conf needed).

internal class Program
{
    static void Main(string[] args)
    {
        var system = ActorSystem.Create("MySystem");

        var childOk1 = system.ActorOf(Props.Create<TestActor>("ok1"));
        var childOk2 = system.ActorOf(Props.Create<TestActor>("ok2"));

        var childBug1 = system.ActorOf(Props.Create<TestActor>("bug"));
        var childBug2 = system.ActorOf(Props.Create<TestActor>("bug-a"));

        childOk1.Tell(new SaveName());
        childOk2.Tell(new SaveName());

        childBug1.Tell(new SaveName());
        childBug2.Tell(new SaveName());

        Thread.Sleep(5_000);
    }
}

public record SaveName();

public class TestActor : ReceivePersistentActor
{
    public override string PersistenceId { get; }

    private bool saveSnapshot = true;

    public TestActor(string actorName)
    {

        PersistenceId = actorName;

        Recover<SnapshotOffer>(x =>
        {
            Console.WriteLine("Recovered " + x.Snapshot + " from persistence id " + PersistenceId);
            saveSnapshot = false;
        });

        Command<SaveName>(x =>
        {
            if (saveSnapshot)
            {
                SaveSnapshot(PersistenceId);
            }
        });

        Command<SaveSnapshotSuccess>(x =>
        {
            Console.WriteLine("Save snapshot success for " + PersistenceId);
        });
    }
}

Expected behavior
When it is executed the first time, expected output should be (without taking into account the line ordering):

Save snapshot success for ok2
Save snapshot success for ok1
Save snapshot success for bug
Save snapshot success for bug-a

Moreover, in the bin folder of the project, there should be 4 files inside the subfolder snapshots:

snapshot-bug-0-638368492390690142
snapshot-bug-a-0-638368492390684244
snapshot-ok1-0-638368492390688473
snapshot-ok2-0-638368492390649357

When executing the test file for a second time, expected output should be, without errors (without taking into account the line ordering):

Recovered ok2 from persistence id ok2
Recovered bug-a from persistence id bug-a
Recovered bug from persistence id bug
Recovered ok1 from persistence id ok1

Actual behavior
There is an error loading snapshots for PersistenceId bug-a, stating that the snapshot file is in use by another process. This only happens when executing the application after saving the snapshots in a previous execution.

[ERROR][11/29/2023 10:10:22.882Z][Thread 0035][akka://MySystem/system/akka.persistence.snapshot-store.local] Error loading snapshot [SnapshotMetadata<pid: bug-a, seqNr: 0, timestamp: 2023/11/29>], remaining attempts: [1]
Cause: System.IO.IOException: The process cannot access the file '[...]\TestAkkaSnapshotPersistence\bin\Debug\net6.0\snapshots\snapshot-bug-a-0-638368492390684244' because it is being used by another process.
   at Microsoft.Win32.SafeHandles.SafeFileHandle.CreateFile(String fullPath, FileMode mode, FileAccess access, FileShare share, FileOptions options)
   at Microsoft.Win32.SafeHandles.SafeFileHandle.Open(String fullPath, FileMode mode, FileAccess access, FileShare share, FileOptions options, Int64 preallocationSize)
   at System.IO.Strategies.OSFileStreamStrategy..ctor(String path, FileMode mode, FileAccess access, FileShare share, FileOptions options, Int64 preallocationSize)
   at Akka.Persistence.Snapshot.LocalSnapshotStore.Load(ImmutableArray`1 metadata)

Replaying the application for multiple times, it happens the same error with the remaining attempts set to zero. In this case, the application prints the following line:
Recovered bug-a from persistence id bug
that states that the actor bug is offered the snapshot that belongs to bug-a, which is incorrect.

Environment
Windows 10, .NET 6.0

@to11mtm
Copy link
Member

to11mtm commented Jan 1, 2024

Looks like an issue with GetSnapshotMetadata in LocalSnapshotStore, we aren't double-checking the wildcard filter for this case.

Adding the line that is commented below should fix the issue, I think.

        private IEnumerable<SnapshotMetadata> GetSnapshotMetadata(string persistenceId, SnapshotSelectionCriteria criteria)
        {
            var snapshots = GetSnapshotDir()
                .EnumerateFiles("snapshot-" + Uri.EscapeDataString(persistenceId) + "-*", SearchOption.TopDirectoryOnly)
                .Select(ExtractSnapshotMetadata)
//                .Where(m=>m.PersistenceId == persistenceId)
                .Where(metadata => metadata != null && criteria.IsMatch(metadata) && !_saving.Contains(metadata)).ToList();

            snapshots.Sort(SnapshotMetadata.Comparer);

            return snapshots;
        }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants