Пример #1
0
        // It should be called when cancellationToken is set.
        internal void StopRetentionManager()
        {
            try
            {
                // It is better if all the tasks running retentionSchedulerDict are deleted.
                this.tokenSource.Cancel();

                // Wait for all the running tasks to cancel.
                Task.Delay(TimeSpan.FromSeconds(waitTimeInSecondForTasksToClose));

                // Stop the timers.
                foreach (var tuple in this.RetentionSchedulerDict)
                {
                    RetentionScheduler retentionScheduler = tuple.Value;
                    retentionScheduler.Stop();
                }

                // Delete all the key value pairs.
                this.RetentionSchedulerDict.Clear();
            }
            catch (Exception ex)
            {
                BackupRestoreTrace.TraceSource.WriteError(TraceType, "RetentionManager was not stopped properly. ExceptionThrown: {0}", ex);
            }
            finally
            {
                this.tokenSource.Dispose();
            }
        }
Пример #2
0
        /// <summary>
        /// Gets called when a policy is updated
        /// </summary>
        internal async Task UpdatePolicyAsync(string backupPolicyName, TimeSpan timeout, CancellationToken cancellationToken, ITransaction transaction)
        {
            /**
             * Cases:
             * 1. UpdateRetention ----> Re-arm the timer.
             *    0. Add Retention.
             *    a. Remove retention --> dispose the timer.
             *    b. update the retention.
             * 2. UpdateStorage ---->
             * 3. Update Backup Schedule. --> no need to do anything/
             *
             */
            try
            {
                BackupRestoreTrace.TraceSource.WriteInfo(TraceType, " In UpdatePolicyAsync of Retention Manager for Backup policy: {0}", backupPolicyName);
                var backupPolicyStore = await BackupPolicyStore.CreateOrGetBackupPolicyStore(this.StatefulService);

                RetentionMetadata retentionMetadata = await this.RetentionStore.GetValueAsync(backupPolicyName, timeout, cancellationToken, transaction);

                BackupPolicy backupPolicy = await backupPolicyStore.GetValueAsync(backupPolicyName, timeout, cancellationToken, transaction);

                if (retentionMetadata == null)
                {
                    if (backupPolicy.RetentionPolicy != null)
                    {
                        retentionMetadata = new RetentionMetadata(backupPolicy.RetentionPolicy);
                        await this.RetentionStore.AddAsync(backupPolicyName, retentionMetadata, timeout, cancellationToken, transaction);

                        RetentionScheduler retentionScheduler = new RetentionScheduler(backupPolicy.Name, backupPolicy.RetentionPolicy, timerCallback);

                        // Here we have updated the policy to introduce retention.
                        retentionScheduler.ArmTimer(retentionMetadata, true);
                        if (!RetentionSchedulerDict.TryAdd(backupPolicyName, retentionScheduler))
                        {
                            // If we are not able to add retention in RetentionSchedulerDict then, stop timer in retention scheduler
                            retentionScheduler.Stop();
                            BackupRestoreTrace.TraceSource.WriteWarning(TraceType, "UpdatePolicyAsync, Not able to add retentionScheduler to dict for policy : {0} ", backupPolicyName);
                            throw new InvalidOperationException(string.Format("{0}: Key already exists.", backupPolicyName));
                        }
                    }
                }
                else if (backupPolicy.RetentionPolicy == null)
                {
                    // need to remove the retentionScheduler from RetentionStore.
                    Func <bool> condition = () =>
                    {
                        if (retentionMetadata.LastRetentionCompletionTime > retentionMetadata.LastRetentionStartTime || retentionMetadata.LastRetentionStartTime == DateTime.MinValue)
                        {
                            return(true);
                        }
                        return(false);
                    };

                    bool disposeComplete = await BackupRestoreUtility.TryPerformOperationWithWaitAsync(
                        (policyName, token) =>
                    {
                        return(DisposeRetentionScheduler(policyName, timeout, token, transaction));
                    },
                        condition,
                        backupPolicyName,
                        cancellationToken,
                        minimumWaitTimeForRetryOperationInMs,
                        maxRetryCountForDisposingRetention,
                        minimumWaitTimeForRetryOperationInMs);

                    if (!disposeComplete)
                    {
                        BackupRestoreTrace.TraceSource.WriteError(TraceType, "Dispose retention did not complete for {0}", backupPolicyName);
                        throw new FabricBackupRestoreLocalRetryException();
                    }
                }
                else
                {
                    if (retentionMetadata.UpdateRetentionPolicyMetadata(backupPolicy.RetentionPolicy))
                    {
                        // Update the retention Scheduler store and arm the timer.
                        RetentionScheduler retentionScheduler;
                        if (!RetentionSchedulerDict.TryGetValue(backupPolicyName, out retentionScheduler))
                        {
                            BackupRestoreTrace.TraceSource.WriteError(TraceType, "UpdateBackupPolicy: Not able to get retention scheduler for backupPolicy {0}", backupPolicyName);
                            throw new KeyNotFoundException();
                        }

                        retentionScheduler.RearmTimer(false, retentionMetadata);
                        await this.RetentionStore.UpdateValueAsync(backupPolicyName, retentionMetadata, timeout, cancellationToken, transaction);
                    }
                }
            }
            catch (Exception ex)
            {
                if (ex is OperationCanceledException)
                {
                    BackupRestoreTrace.TraceSource.WriteWarning(TraceType, " DisposeRetentionScheduler ended with Timeout as the operation was cencelled: {0}", backupPolicyName);
                    BackupRestoreTrace.TraceSource.WriteWarning(TraceType, " It could be because the retention was in progress and user tried to remove the retention policy during UpdatePolicy: {0}", backupPolicyName);
                }
                else
                {
                    // Check for the exceptions of DisposeRetentionScheduler Timeout Retries.
                    BackupRestoreTrace.TraceSource.WriteError(TraceType, " UpdateBackupPolicy resulted in the exception : {0}", backupPolicyName);
                }
                throw;
            }
        }