Search Results for

    Show / Hide Table of Contents

    AK2002 - Warning

    Context.Materializer() should not be invoked multiple times, use a cached value instead.

    Cause

    Calling Context.Materializer() inside an actor will create a new instance of streams ActorMaterializer. When you create multiple streams, most likely you will only need a single actor materializer; creating multiple ActorMaterializer would only create memory pressure and potential memory leak if they're not disposed properly.

    Note

    Using ActorSystem.Materializer() is safe because it is cached internally and disposed of during shutdown.

    An example:

    using Akka.Actor;
    using Akka.Streams;
    using Akka.Streams.Dsl;
    
    public sealed class MyActor : ReceiveActor
    {
        public MyActor()
        {
            ReceiveAsync<string>(
                s => s == "hello",
                async _ =>
                {
                    await Source.Single(1)
                        .Select(x => x + 1)
                        .ToMaterialized(Sink.ForEach<int>(_ => { }), Keep.Right)
                        .Run(Context.Materializer());
                });
        }
    }
    

    Resolution

    There are two ways to resolve this problem:

    using Akka.Actor;
    using Akka.Streams;
    using Akka.Streams.Dsl;
    
    public sealed class MyActor : ReceiveActor
    {
        private readonly ActorMaterializer _materializer;
        
        public MyActor()
        {
            _materializer = Context.Materializer();
            
            ReceiveAsync<string>(
                s => s == "hello",
                async _ =>
                {
                    await Source.Single(1)
                        .Select(x => x + 1)
                        .ToMaterialized(Sink.ForEach<int>(_ => { }), Keep.Right)
                        .Run(_materializer); // Use a cached ActorMaterializer
                });
        }
    
        protected override void PostStop()
        {
            _materializer.Dispose(); // Dispose the ActorMaterializer when the actor is stopped.
        }
    }
    
    using Akka.Actor;
    using Akka.Streams;
    using Akka.Streams.Dsl;
    
    public sealed class MyActor : ReceiveActor
    {
        public MyActor()
        {
            ReceiveAsync<string>(
                s => s == "hello",
                async _ =>
                {
                    await Source.Single(1)
                        .Select(x => x + 1)
                        .ToMaterialized(Sink.ForEach<int>(_ => { }), Keep.Right)
                        .Run(Context.System.Materializer()); // Use ActorSystem.Materializer(), this is cached internally
                });
        }
    }
    
    In this article
    • githubEdit this page
    Back to top
    Contribute
    • Project Chat
    • Discussion Forum
    • Source Code
    Support
    • Akka.NET Support Plans
    • Akka.NET Observability Tools
    • Akka.NET Training & Consulting
    Maintained By
    • Petabridge - The Akka.NET Company
    • Learn Akka.NET