private IVersionedKeyValue UpdateCache(Guid activityId, IVersionedKeyValue vkv)
        {
            lock (locker)
            {
                if (cachedProperties.ContainsKey(vkv.Key))
                {
                    var existingVkv = cachedProperties[vkv.Key];

                    if (existingVkv.Version >= vkv.Version)
                    {
                        traceType.WriteWarning(
                            "UpdateCache ignored for store name '{0}'. Current local cache data is newer than data to be updated. Current local cache data: {1}{2}Data to be updated: {3}{4}ActivityId: {5}",
                            storeName,
                            existingVkv,
                            Environment.NewLine,
                            vkv,
                            Environment.NewLine,
                            activityId);

                        return(existingVkv);
                    }
                }

                cachedProperties[vkv.Key] = vkv;
                return(vkv);
            }
        }
Beispiel #2
0
        public async Task <string> ExecuteCommandAsync(string input, bool allowAdminCommands)
        {
            input.Validate("input");

            traceType.WriteInfo("ExecuteCommandAsync: {0}, allow admin commands: {1}", input, allowAdminCommands);

            // Command format is "CommandName:Arguments"
            string[] tokens      = input.Split(CommandTokenDelimiter, 2);
            string   commandName = tokens[0];

            string args = string.Empty;

            if (tokens.Length > 1)
            {
                args = tokens[1];
            }

            try
            {
                CommandHandlerEntry handlerEntry;
                if (Commands.TryGetValue(commandName, out handlerEntry))
                {
                    if (allowAdminCommands || !handlerEntry.IsAdminCommand)
                    {
                        string result = await handlerEntry.CommandHandlerAsync(args).ConfigureAwait(false);

                        return(result);
                    }

                    string text = string.Format(CultureInfo.InvariantCulture, "Permission denied for command: {0}", commandName);
                    traceType.WriteWarning(text);
                    throw new ArgumentException(text, commandName);
                }

                string text2 = string.Format(CultureInfo.InvariantCulture, "Unrecognized command: {0}", commandName);
                traceType.WriteWarning(text2);
                throw new ArgumentException(text2, commandName);
            }
            catch (Exception e)
            {
                traceType.WriteWarning("Command handler for {0} threw exception: {1}", commandName, e);
                throw;
            }
        }
Beispiel #3
0
        private async Task <IInfrastructureCoordinator> InitializeCoordinator(TimeSpan timeout, CancellationToken token)
        {
            Stopwatch watch = Stopwatch.StartNew();

            while (true)
            {
                try
                {
                    IInfrastructureCoordinator innerCoordinator = factory(factoryArgs);
                    return(innerCoordinator);
                }
                catch (Exception e)
                {
                    string message = "Failed to create infrastructure coordinator: {0}".ToString(e);
                    traceType.WriteWarning("{0}", message);

                    if (this.configSection.ReadConfigValue(ConfigKeyWarnOnInitFailure, true))
                    {
                        this.UpdateCoordinatorStatusHealthProperty(
                            HealthState.Warning,
                            message);
                    }
                    else
                    {
                        this.UpdateCoordinatorStatusHealthProperty(
                            HealthState.Ok,
                            "Coordinator is not expected to run.");
                    }
                }

                if (watch.Elapsed > timeout)
                {
                    traceType.WriteWarning("Timed out trying to create coordinator; exiting process");
                    ProcessCloser.ExitEvent.Set();
                }

                TimeSpan retryDelay = GetRetryDelay();
                traceType.WriteInfo("Retrying in {0}; remaining until timeout = {1}", retryDelay, timeout - watch.Elapsed);
                await Task.Delay(retryDelay, token).ConfigureAwait(false);
            }
        }
Beispiel #4
0
        /// <summary>
        /// Reads the configuration value.
        /// </summary>
        /// <typeparam name="T">The type of the converted result.</typeparam>
        /// <param name="keyName">Name of the key.</param>
        /// <param name="defaultValue">The default value to be used if read was not successful.</param>
        /// <returns>The configuration value or the provided default value.</returns>
        public T ReadConfigValue <T>(
            string keyName,
            T defaultValue = default(T))
        {
            keyName.Validate("keyName");

            T result = defaultValue;

            string configValue = this.ConfigStore.ReadUnencryptedString(this.Name, keyName);

            if (string.IsNullOrEmpty(configValue))
            {
                return(result);
            }

            Exception ex = null;

            try
            {
                if (typeof(T).GetTypeInfo().IsEnum)
                {
                    result = (T)Enum.Parse(typeof(T), configValue, true);
                }
                else if (typeof(T) == typeof(TimeSpan))
                {
                    result = (T)(object)TimeSpan.Parse(configValue);
                }
                else
                {
                    result = (T)Convert.ChangeType(configValue, typeof(T), CultureInfo.InvariantCulture);
                }
            }
            catch (ArgumentException e)
            {
                ex = e;
            }
            catch (InvalidCastException e)
            {
                ex = e;
            }
            catch (FormatException e)
            {
                ex = e;
            }
            catch (OverflowException e)
            {
                ex = e;
            }

            if (ex != null)
            {
                traceType.WriteWarning(
                    "Error converting value '{0}' from config section/key name '{1}/{2}'. Returning default value: {3}. Error details: {4}",
                    configValue,
                    this.Name,
                    keyName,
                    result,
                    ex);
            }
            else
            {
                traceType.WriteNoise(
                    "Converted value '{0}' from config section/key name '{1}/{2}'. Returning converted value: {3}",
                    configValue,
                    this.Name,
                    keyName,
                    result);
            }

            return(result);
        }
Beispiel #5
0
        public async Task <JobImpactTranslationMode> EvaluateJobImpactAsync(IManagementNotificationContext notification)
        {
            notification.Validate("notification");

            if (notification.NotificationType != NotificationType.StartJobStep)
            {
                // this is a coding error
                throw new ArgumentException("Notification not relevant. Notification: {0}".ToString(notification.ToShortDisplayString()));
            }

            if (DoesAssessmentMatchNotification(notification))
            {
                return(currentJobImpactData.AssessedImpact);
            }

            traceType.WriteInfo(
                "JobImpactData doesn't match, starting new evaluation. Notification: {0}, Current JobImpactData: {1}",
                notification.ToShortDisplayString(), currentJobImpactData != null ? currentJobImpactData.ToString() : "<null>");

            var now = DateTimeOffset.UtcNow;

            // There is already retry built into the QueryClient wrapper. If it goes beyond retry boundaries,
            // we'll let the caller handle this
            IList <INode> nodeList = await QueryClient.GetNodeListAsync(now).ConfigureAwait(false);

            var queriedNodes = nodeList.ToDictionary(e => e.NodeName, StringComparer.OrdinalIgnoreCase);

            Dictionary <string, INode> nodesToBeImpacted = GetNodesInNotification(notification, queriedNodes);

            var newJobImpactData = new JobImpactData
            {
                JobId          = notification.ActiveJobId,
                JobType        = notification.ActiveJobType,
                UD             = notification.ActiveJobStepTargetUD,
                AssessedNodes  = nodesToBeImpacted,
                Timestamp      = now,
                AssessedImpact = JobImpactTranslationMode.Default,
            };

            // no previous data
            if (currentJobImpactData == null)
            {
                currentJobImpactData = newJobImpactData;

                traceType.WriteInfo(
                    "New assessed job impact stored. Returning {0}, JobImpactData: {1}, Notification: {2}",
                    currentJobImpactData.AssessedImpact,
                    currentJobImpactData,
                    notification.ToShortDisplayString());

                return(currentJobImpactData.AssessedImpact);
            }

            // has too much time passed after assessment?
            bool expired = HasPreviousEvaluationExpired(now, currentJobImpactData);

            if (expired)
            {
                currentJobImpactData = newJobImpactData;

                traceType.WriteWarning(
                    "New assessed job impact stored. Time since last assessment is either invalid or has exceeded expiration time. Returning {0}. JobImpactData: {1}, Notification: {2}",
                    currentJobImpactData.AssessedImpact,
                    currentJobImpactData,
                    notification.ToShortDisplayString());

                return(currentJobImpactData.AssessedImpact);
            }

            bool?restarted = DidPreviouslyAssessedNodesRestart(queriedNodes, currentJobImpactData);

            if (restarted == null)
            {
                traceType.WriteInfo(
                    "Unable to assess job impact, continuing to use previous assessment. Returning {0}, JobImpactData: {1}, Notification: {2}",
                    currentJobImpactData.AssessedImpact,
                    currentJobImpactData,
                    notification.ToShortDisplayString());

                return(currentJobImpactData.AssessedImpact);
            }

            currentJobImpactData = newJobImpactData;

            currentJobImpactData.AssessedImpact = restarted.Value
                ? JobImpactTranslationMode.Default
                : JobImpactTranslationMode.Optimized;

            traceType.WriteInfo(
                "New assessed job impact stored. Returning {0}, JobImpactData: {1}, Notification: {2}",
                currentJobImpactData.AssessedImpact,
                currentJobImpactData,
                notification.ToShortDisplayString());

            return(currentJobImpactData.AssessedImpact);
        }