Example #1
0
        public Reminder(ReminderSettings settings)
        {
            this.UpdateState = e =>
            {
                switch (e)
                {
                case Scheduled scheduled:
                    this.state = state.AddEntry(scheduled.Entry);
                    break;

                case Completed completed:
                    this.state = state.RemoveEntry(completed.TaskId);
                    break;
                }
            };

            this.settings    = settings;
            PersistenceId    = settings.PersistenceId;
            JournalPluginId  = settings.JournalPluginId;
            SnapshotPluginId = settings.SnapshotPluginId;

            tickTask = Context.System.Scheduler.ScheduleTellRepeatedlyCancelable(settings.TickInterval, settings.TickInterval, Self, Tick.Instance, ActorRefs.NoSender);

            Command <Tick>(_ =>
            {
                var now = DateTime.UtcNow;
                foreach (var schedule in state.Entries.Values.Where(e => ShouldTrigger(e, now)))
                {
                    Log.Info("Sending message [{0}] to recipient [{1}]", schedule.Message, schedule.Recipient);

                    var selection = Context.ActorSelection(schedule.Recipient);
                    selection.Tell(schedule.Message, ActorRefs.NoSender);

                    Emit(new Completed(schedule.TaskId, now), UpdateState);

                    var next = schedule.WithNextTriggerDate(now);
                    if (next != null)
                    {
                        Emit(new Scheduled(next), UpdateState);
                    }
                }
            });
            Command <Schedule>(schedule =>
            {
                var sender = Sender;
                try
                {
                    Emit(new Scheduled(schedule.WithoutAck()), e =>
                    {
                        UpdateState(e);
                        //NOTE: use `schedule`, not `e` - latter contains a version with ACK explicitly erased to avoid storing ack in persistent memory
                        if (schedule.Ack != null)
                        {
                            sender.Tell(schedule.Ack);
                        }
                    });
                }
                catch (Exception error)
                {
                    Log.Error(error, "Failed to schedule: [{0}]", schedule);
                    if (schedule.Ack != null)
                    {
                        sender.Tell(new Status.Failure(error));
                    }
                }
            });
            Command <GetState>(_ =>
            {
                Sender.Tell(state);
            });
            Command <Cancel>(cancel =>
            {
                var sender = Sender;
                try
                {
                    Emit(new Completed(cancel.TaskId, DateTime.UtcNow), e =>
                    {
                        UpdateState(e);
                        if (cancel.Ack != null)
                        {
                            sender.Tell(cancel.Ack);
                        }
                    });
                }
                catch (Exception error)
                {
                    Log.Error(error, "Failed to cancel task: [{0}]", cancel.TaskId);
                    if (cancel.Ack != null)
                    {
                        sender.Tell(new Status.Failure(error));
                    }
                }
            });
            Command <SaveSnapshotSuccess>(success =>
            {
                Log.Debug("Successfully saved reminder snapshot. Removing all events before seqNr [{0}]", success.Metadata.SequenceNr);
                DeleteMessages(success.Metadata.SequenceNr - 1);
            });
            Command <SaveSnapshotFailure>(failure =>
            {
                Log.Error(failure.Cause, "Failed to save reminder snapshot");
            });
            Recover <Scheduled>(UpdateState);
            Recover <Completed>(UpdateState);
            Recover <SnapshotOffer>(offer =>
            {
                if (offer.Snapshot is State state)
                {
                    this.state = state;
                }
            });
        }
Example #2
0
 /// <summary>
 /// An actor <see cref="Akka.Actor.Props"/> for <see cref="Reminder"/> class setup using provided <paramref name="settings"/>.
 /// </summary>
 public static Props Props(ReminderSettings settings) => Actor.Props.Create(() => new Reminder(settings));
Example #3
0
 public Reminder() : this(ReminderSettings.Create(Context.System.Settings.Config.GetConfig("akka.persistence.reminder")))
 {
 }
        public Reminder(ReminderSettings settings)
        {
            this.settings    = settings;
            PersistenceId    = settings.PersistenceId;
            JournalPluginId  = settings.JournalPluginId;
            SnapshotPluginId = settings.SnapshotPluginId;

            tickTask = Context.System.Scheduler.ScheduleTellRepeatedlyCancelable(settings.TickInterval, settings.TickInterval, Self, Tick.Instance, ActorRefs.NoSender);

            Command <Tick>(_ =>
            {
                var now = DateTime.UtcNow;
                foreach (var entry in state.Entries.Values.Where(e => ShouldTrigger(e, now)))
                {
                    Log.Info("Sending message [{0}] to recipient [{1}]", entry.Message, entry.Recipient);

                    var selection = Context.ActorSelection(entry.Recipient);
                    selection.Tell(entry.Message, ActorRefs.NoSender);

                    Emit(new Completed(entry.TaskId, now), UpdateState);

                    if (entry.RepeatInterval.HasValue)
                    {
                        var next = now + entry.RepeatInterval.Value;
                        Emit(new Scheduled(entry.WithNextTriggerDate(next)), UpdateState);
                    }
                }
            });
            Command <Schedule>(schedule =>
            {
                var entry  = new Entry(schedule.TaskId, schedule.Recipient, schedule.Message, schedule.TriggerDateUtc, schedule.RepeatInterval);
                var sender = Sender;
                Emit(new Scheduled(entry), e =>
                {
                    UpdateState(e);
                    if (schedule.Ack != null)
                    {
                        sender.Tell(schedule.Ack);
                    }
                });
            });
            Command <GetState>(_ =>
            {
                Sender.Tell(state);
            });
            Command <Cancel>(cancel =>
            {
                var sender = Sender;
                Emit(new Completed(cancel.TaskId, DateTime.UtcNow), e =>
                {
                    UpdateState(e);
                    if (cancel.Ack != null)
                    {
                        sender.Tell(cancel.Ack);
                    }
                });
            });
            Command <SaveSnapshotSuccess>(success =>
            {
                Log.Debug("Successfully saved reminder snapshot. Removing all events before seqNr [{0}]", success.Metadata.SequenceNr);
                DeleteMessages(success.Metadata.SequenceNr - 1);
            });
            Command <SaveSnapshotFailure>(failure =>
            {
                Log.Error(failure.Cause, "Failed to save reminder snapshot");
            });
            Recover <Scheduled>(scheduled => UpdateState(scheduled));
            Recover <Completed>(completed => UpdateState(completed));
            Recover <SnapshotOffer>(offer =>
            {
                if (offer.Snapshot is State offerred)
                {
                    state = offerred;
                }
            });
        }