コード例 #1
0
        private async Task RegisterOrUpdateReminderAsync(ActorReminder actorReminder, TimeSpan remainingDueTime,
                                                         bool saveState = true)
        {
            this.ThrowIfClosed();

            ActorTrace.Source.WriteInfoWithId(
                TraceType,
                this.traceId,
                "Registering reminder for actor: ({0}), reminderName: ({1}), remainingDueTime: ({2}),  saveState {3}",
                actorReminder.OwnerActorId,
                actorReminder.Name,
                remainingDueTime,
                saveState);

            var reminderDictionary = this.remindersByActorId.GetOrAdd(actorReminder.OwnerActorId,
                                                                      k => new ConcurrentDictionary <string, ActorReminder>());

            reminderDictionary.AddOrUpdate(
                actorReminder.Name,
                actorReminder,
                (k, v) =>
            {
                v.CancelTimer();
                return(actorReminder);
            });

            try
            {
                if (saveState)
                {
                    await this.StateProvider.SaveReminderAsync(actorReminder.OwnerActorId, actorReminder);
                }

                actorReminder.ArmTimer(remainingDueTime);
            }
            catch (Exception ex)
            {
                actorReminder.CancelTimer();
                reminderDictionary.TryRemove(actorReminder.Name, out actorReminder);

                if (!(ex is FabricNotPrimaryException))
                {
                    ActorTrace.Source.WriteWarningWithId(
                        TraceType,
                        this.traceId,
                        "Failed to register reminder for actor {0}, reminderName {1}, saveState {2}. Error={3}.",
                        actorReminder.OwnerActorId,
                        actorReminder.Name,
                        saveState,
                        ex.ToString());
                }

                throw;
            }
        }
コード例 #2
0
        public async void FireReminder(ActorReminder reminder)
        {
            var rearmTimer = true;

            try
            {
                using (var actorScope = this.GetActor(reminder.OwnerActorId, true, false))
                {
                    var actorBase = actorScope.Actor;

                    // if Actor is deleted, reminder should not be fired or armed again.
                    // Its an optimization so that we don't fire the reminder if the actor
                    // is marked for deletion.
                    if (actorBase.MarkedForDeletion)
                    {
                        rearmTimer = false;
                        return;
                    }

                    if (this.actorService.ActorTypeInformation.IsRemindable)
                    {
                        var actor = (IRemindable)actorBase;

                        await this.DispatchToActorAsync(
                            reminder.OwnerActorId,
                            this.reminderMethodContext,
                            false,
                            (async(a, cancellationTkn) =>
                        {
                            await actor.ReceiveReminderAsync(reminder.Name, reminder.State, reminder.DueTime, reminder.Period);

                            return(null);
                        }),
                            Guid.NewGuid().ToString(),
                            false,
                            CancellationToken.None);
                    }
                }
            }
            catch (ActorDeletedException)
            {
                rearmTimer = false;
            }
            catch (Exception e)
            {
                ActorTrace.Source.WriteWarningWithId(
                    TraceType,
                    this.traceId,
                    "Firing reminder {0} for actor {1} caused exception: {2}",
                    reminder.Name,
                    reminder.OwnerActorId,
                    e.ToString());
            }

            // User may delete or update reminder during ReceiveReminderAsync() call.
            // Rearm only if it is still valid.
            if (reminder.IsValid() && rearmTimer)
            {
                if (this.ActorService.Settings.ReminderSettings.AutoDeleteOneTimeReminders && this.IsOneTimeReminder(reminder))
                {
                    await this.UnregisterOneTimeReminderAsync(reminder);
                }
                else
                {
                    await this.UpdateReminderLastCompletedTimeAsync(reminder);

                    reminder.ArmTimer(reminder.Period);
                }
            }
        }