Search Results for

    Show / Hide Table of Contents

    AK1007 - Error

    Creating timer registration using Timers.StartSingleTimer() or `` in Timers.StartPeriodicTimer() will not be honored because they will be cleared immediately. Move timer creation to PostRestart() instead.

    Cause

    When implementing the IWithTimers interface in your actor, a TimerScheduler instance will be injected into your actor and you can access it through the public ITimerScheduler Timers { get; set; } property. This TimerScheduler manages all the timers by tracking them using a dictionary when its StartSingleTimer() and StartPeriodicTimer() methods were invoked, and automatically removing them when the actor is being restarted or stopped.

    Any calls to Timers.StartSingleTimer() or Timers.StartPeriodicTimer() inside the actor lifecycle methods AroundPreRestart() or the PreRestart() will not work because the TimerScheduler state will be cleared immediately after.

    Example:

    using System;
    using Akka.Actor;
    
    public sealed class MyActor : ReceiveActor, IWithTimers
    {
        private sealed class TimerKey
        {
            public static readonly TimerKey Instance = new();
            private TimerKey() { }
        }
        
        private sealed class TimerMessage
        {
            public static readonly TimerMessage Instance = new();
            private TimerMessage() { }
        }
    
        public MyActor()
        {
            Receive<TimerMessage>(_ =>
            {
                // Timer callback code will never be executed
            });
        }
        
        public ITimerScheduler Timers { get; set; }
        
        protected override void PreRestart(Exception reason, object message)
        {
            base.PreRestart(reason, message);
            
            // This timer will never be fired
            Timers.StartSingleTimer(
                key: TimerKey.Instance, 
                msg: TimerMessage.Instance, 
                timeout: TimeSpan.FromSeconds(3));
        }
    }
    

    Resolution

    Move the timer registration to the actor PostRestart() lifecycle method instead:

    using System;
    using Akka.Actor;
    
    public sealed class MyActor : ReceiveActor, IWithTimers
    {
        private sealed class TimerKey
        {
            public static readonly TimerKey Instance = new();
            private TimerKey() { }
        }
        
        private sealed class TimerMessage
        {
            public static readonly TimerMessage Instance = new();
            private TimerMessage() { }
        }
    
        public MyActor()
        {
            Receive<TimerMessage>(_ =>
            {
                // Timer callback code
            });
        }
        
        public ITimerScheduler Timers { get; set; }
        
        protected override void PostRestart(Exception reason)
        {
            base.PostRestart(reason);
            
            // Timer registration moved to here
            Timers.StartSingleTimer(
                key: TimerKey.Instance, 
                msg: TimerMessage.Instance, 
                timeout: TimeSpan.FromSeconds(3));
        }
    }
    
    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