Skip to content

Commit

Permalink
Add IWithTimers API with sender override (#7341)
Browse files Browse the repository at this point in the history
* Add IWithTimers API with sender override

* Update API Approval list
  • Loading branch information
Arkatufus authored Sep 24, 2024
1 parent 8e2e11d commit 554086c
Show file tree
Hide file tree
Showing 4 changed files with 113 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1183,8 +1183,11 @@ namespace Akka.Actor
void CancelAll();
bool IsTimerActive(object key);
void StartPeriodicTimer(object key, object msg, System.TimeSpan interval);
void StartPeriodicTimer(object key, object msg, System.TimeSpan interval, Akka.Actor.IActorRef sender);
void StartPeriodicTimer(object key, object msg, System.TimeSpan initialDelay, System.TimeSpan interval);
void StartPeriodicTimer(object key, object msg, System.TimeSpan initialDelay, System.TimeSpan interval, Akka.Actor.IActorRef sender);
void StartSingleTimer(object key, object msg, System.TimeSpan timeout);
void StartSingleTimer(object key, object msg, System.TimeSpan timeout, Akka.Actor.IActorRef sender);
}
public interface IUntypedActorContext : Akka.Actor.IActorContext, Akka.Actor.IActorRefFactory, Akka.Actor.ICanWatch
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1181,8 +1181,11 @@ namespace Akka.Actor
void CancelAll();
bool IsTimerActive(object key);
void StartPeriodicTimer(object key, object msg, System.TimeSpan interval);
void StartPeriodicTimer(object key, object msg, System.TimeSpan interval, Akka.Actor.IActorRef sender);
void StartPeriodicTimer(object key, object msg, System.TimeSpan initialDelay, System.TimeSpan interval);
void StartPeriodicTimer(object key, object msg, System.TimeSpan initialDelay, System.TimeSpan interval, Akka.Actor.IActorRef sender);
void StartSingleTimer(object key, object msg, System.TimeSpan timeout);
void StartSingleTimer(object key, object msg, System.TimeSpan timeout, Akka.Actor.IActorRef sender);
}
public interface IUntypedActorContext : Akka.Actor.IActorContext, Akka.Actor.IActorRefFactory, Akka.Actor.ICanWatch
{
Expand Down
46 changes: 46 additions & 0 deletions src/core/Akka/Actor/Scheduler/ITimerScheduler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,21 @@ public interface ITimerScheduler
/// <param name="interval">Interval</param>
void StartPeriodicTimer(object key, object msg, TimeSpan interval);

/// <summary>
/// Start a periodic timer that will send <paramref name="msg"/> to the "Self" actor at
/// a fixed <paramref name="interval"/>.
///
///Each timer has a key and if a new timer with same key is started
/// the previous is cancelled and it's guaranteed that a message from the
/// previous timer is not received, even though it might already be enqueued
/// in the mailbox when the new timer is started.
/// </summary>
/// <param name="key">Name of timer</param>
/// <param name="msg">Message to schedule</param>
/// <param name="interval">Interval</param>
/// <param name="sender">The sender override for the timer message</param>
void StartPeriodicTimer(object key, object msg, TimeSpan interval, IActorRef sender);

/// <summary>
/// Start a periodic timer that will send <paramref name="msg"/> to the "Self" actor at
/// a fixed <paramref name="interval"/>.
Expand All @@ -50,6 +65,22 @@ public interface ITimerScheduler
/// <param name="interval">Interval</param>
void StartPeriodicTimer(object key, object msg, TimeSpan initialDelay, TimeSpan interval);

/// <summary>
/// Start a periodic timer that will send <paramref name="msg"/> to the "Self" actor at
/// a fixed <paramref name="interval"/>.
///
/// Each timer has a key and if a new timer with same key is started
/// the previous is cancelled and it's guaranteed that a message from the
/// previous timer is not received, even though it might already be enqueued
/// in the mailbox when the new timer is started.
/// </summary>
/// <param name="key">Name of timer</param>
/// <param name="msg">Message to schedule</param>
/// <param name="initialDelay">Initial delay</param>
/// <param name="interval">Interval</param>
/// <param name="sender">The sender override for the timer message</param>
void StartPeriodicTimer(object key, object msg, TimeSpan initialDelay, TimeSpan interval, IActorRef sender);

/// <summary>
/// Start a timer that will send <paramref name="msg"/> once to the "Self" actor after
/// the given <paramref name="timeout"/>.
Expand All @@ -64,6 +95,21 @@ public interface ITimerScheduler
/// <param name="timeout">Interval</param>
void StartSingleTimer(object key, object msg, TimeSpan timeout);

/// <summary>
/// Start a timer that will send <paramref name="msg"/> once to the "Self" actor after
/// the given <paramref name="timeout"/>.
///
/// Each timer has a key and if a new timer with same key is started
/// the previous is cancelled and it's guaranteed that a message from the
/// previous timer is not received, even though it might already be enqueued
/// in the mailbox when the new timer is started.
/// </summary>
/// <param name="key">Name of timer</param>
/// <param name="msg">Message to schedule</param>
/// <param name="timeout">Interval</param>
/// <param name="sender">The sender override for the timer message</param>
void StartSingleTimer(object key, object msg, TimeSpan timeout, IActorRef sender);

/// <summary>
/// Check if a timer with a given <paramref name="key"/> is active.
/// </summary>
Expand Down
67 changes: 61 additions & 6 deletions src/core/Akka/Actor/Scheduler/TimerScheduler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,25 @@ public TimerScheduler(IActorContext ctx)
/// <param name="interval">Interval</param>
public void StartPeriodicTimer(object key, object msg, TimeSpan interval)
{
StartTimer(key, msg, interval, interval, true);
StartTimer(key, msg, interval, interval, true, ActorRefs.NoSender);
}

/// <summary>
/// Start a periodic timer that will send <paramref name="msg"/> to the "Self" actor at
/// a fixed <paramref name="interval"/>.
///
/// Each timer has a key and if a new timer with same key is started
/// the previous is cancelled and it's guaranteed that a message from the
/// previous timer is not received, even though it might already be enqueued
/// in the mailbox when the new timer is started.
/// </summary>
/// <param name="key">Name of timer</param>
/// <param name="msg">Message to schedule</param>
/// <param name="interval">Interval</param>
/// <param name="sender">The sender override for the timer message</param>
public void StartPeriodicTimer(object key, object msg, TimeSpan interval, IActorRef sender)
{
StartTimer(key, msg, interval, interval, true, sender);
}

/// <summary>
Expand All @@ -123,7 +141,26 @@ public void StartPeriodicTimer(object key, object msg, TimeSpan interval)
/// <param name="interval">Interval</param>
public void StartPeriodicTimer(object key, object msg, TimeSpan initialDelay, TimeSpan interval)
{
StartTimer(key, msg, interval, initialDelay, true);
StartTimer(key, msg, interval, initialDelay, true, ActorRefs.NoSender);
}

/// <summary>
/// Start a periodic timer that will send <paramref name="msg"/> to the "Self" actor at
/// a fixed <paramref name="interval"/>.
///
/// Each timer has a key and if a new timer with same key is started
/// the previous is cancelled and it's guaranteed that a message from the
/// previous timer is not received, even though it might already be enqueued
/// in the mailbox when the new timer is started.
/// </summary>
/// <param name="key">Name of timer</param>
/// <param name="msg">Message to schedule</param>
/// <param name="initialDelay">Initial delay</param>
/// <param name="interval">Interval</param>
/// <param name="sender">The sender override for the timer message</param>
public void StartPeriodicTimer(object key, object msg, TimeSpan initialDelay, TimeSpan interval, IActorRef sender)
{
StartTimer(key, msg, interval, initialDelay, true, sender);
}

/// <summary>
Expand All @@ -140,7 +177,25 @@ public void StartPeriodicTimer(object key, object msg, TimeSpan initialDelay, Ti
/// <param name="timeout">Interval</param>
public void StartSingleTimer(object key, object msg, TimeSpan timeout)
{
StartTimer(key, msg, timeout, TimeSpan.Zero, false);
StartTimer(key, msg, timeout, TimeSpan.Zero, false, ActorRefs.NoSender);
}

/// <summary>
/// Start a timer that will send <paramref name="msg"/> once to the "Self" actor after
/// the given <paramref name="timeout"/>.
///
/// Each timer has a key and if a new timer with same key is started
/// the previous is cancelled and it's guaranteed that a message from the
/// previous timer is not received, even though it might already be enqueued
/// in the mailbox when the new timer is started.
/// </summary>
/// <param name="key">Name of timer</param>
/// <param name="msg">Message to schedule</param>
/// <param name="timeout">Interval</param>
/// <param name="sender">The sender override for the timer message</param>
public void StartSingleTimer(object key, object msg, TimeSpan timeout, IActorRef sender)
{
StartTimer(key, msg, timeout, TimeSpan.Zero, false, sender);
}

/// <summary>
Expand Down Expand Up @@ -195,7 +250,7 @@ private void CancelTimer(Timer timer)
}


private void StartTimer(object key, object msg, TimeSpan timeout, TimeSpan initialDelay, bool repeat)
private void StartTimer(object key, object msg, TimeSpan timeout, TimeSpan initialDelay, bool repeat, IActorRef sender)
{
if (_timers.TryGetValue(key, out var timer))
CancelTimer(timer);
Expand All @@ -210,9 +265,9 @@ private void StartTimer(object key, object msg, TimeSpan timeout, TimeSpan initi

ICancelable task;
if (repeat)
task = _ctx.System.Scheduler.ScheduleTellRepeatedlyCancelable(initialDelay, timeout, _ctx.Self, timerMsg, ActorRefs.NoSender);
task = _ctx.System.Scheduler.ScheduleTellRepeatedlyCancelable(initialDelay, timeout, _ctx.Self, timerMsg, sender);
else
task = _ctx.System.Scheduler.ScheduleTellOnceCancelable(timeout, _ctx.Self, timerMsg, ActorRefs.NoSender);
task = _ctx.System.Scheduler.ScheduleTellOnceCancelable(timeout, _ctx.Self, timerMsg, sender);

var nextTimer = new Timer(key, msg, repeat, nextGen, task);

Expand Down

0 comments on commit 554086c

Please sign in to comment.