예제 #1
0
        /// <summary>
        /// Waits for a condition to be satisfied.
        /// </summary>
        /// <typeparam name="T">
        /// The changeType of object that will be operated on.
        /// </typeparam>
        /// <param name="client">
        /// The client instance this is extending.
        /// </param>
        /// <param name="poll">
        /// The function to poll the client for state.
        /// </param>
        /// <param name="continuePolling">
        /// A function to evaluate the state to see if it matches the condition.
        /// </param>
        /// <param name="notifyHandler">
        /// A notification handler used to rais events when the status changes.
        /// </param>
        /// <param name="interval">
        /// A time frame to wait between polls.
        /// </param>
        /// <param name="timeout">
        /// The amount of time to wait for the condition to be satisfied.
        /// </param>
        /// <param name="cancellationToken">
        /// A Cancelation Token that can be used to cancel the request.
        /// </param>
        /// <returns>
        /// An awaitable task.
        /// </returns>
        public static async Task WaitForCondition <T>(this IHDInsightManagementPocoClient client, Func <Task <T> > poll, Func <T, PollResult> continuePolling, Action <T> notifyHandler, TimeSpan interval, TimeSpan timeout, CancellationToken cancellationToken)
        {
            client.ArgumentNotNull("client");
            poll.ArgumentNotNull("poll");
            continuePolling.ArgumentNotNull("continuePolling");
            var        start                   = DateTime.Now;
            int        pollingFailures         = 0;
            const int  MaxPollingFailuresCount = 10;
            T          pollingResult           = default(T);
            PollResult result                  = PollResult.Continue;

            do
            {
                try
                {
                    pollingResult = await poll();

                    result = continuePolling(pollingResult);
                    if (notifyHandler.IsNotNull() && pollingResult.IsNotNull())
                    {
                        notifyHandler(pollingResult);
                    }
                    if (result == PollResult.Unknown || result == PollResult.Null)
                    {
                        pollingFailures++;
                        if (result == PollResult.Null)
                        {
                            client.LogMessage("Poll for cluster returned no cluster.  Current error weight (out of 10): " + pollingFailures.ToString(CultureInfo.InvariantCulture),
                                              Severity.Informational,
                                              Verbosity.Diagnostic);
                        }
                        cancellationToken.WaitForInterval(interval);
                    }
                    else if (result == PollResult.Continue)
                    {
                        pollingFailures = 0;
                        cancellationToken.WaitForInterval(interval);
                    }
                }
                catch (Exception ex)
                {
                    ex = ex.GetFirstException();
                    var hlex              = ex as HttpLayerException;
                    var httpEx            = ex as HttpRequestException;
                    var webex             = ex as WebException;
                    var timeOut           = ex as TimeoutException;
                    var taskCancled       = ex as TaskCanceledException;
                    var operationCanceled = ex as OperationCanceledException;
                    if (taskCancled.IsNotNull() && taskCancled.CancellationToken.IsNotNull() && taskCancled.CancellationToken.IsCancellationRequested)
                    {
                        throw;
                    }
                    if (operationCanceled.IsNotNull() && operationCanceled.CancellationToken.IsNotNull() && operationCanceled.CancellationToken.IsCancellationRequested)
                    {
                        throw;
                    }
                    if (hlex.IsNotNull() || httpEx.IsNotNull() || webex.IsNotNull() || taskCancled.IsNotNull() || timeOut.IsNotNull() || operationCanceled.IsNotNull())
                    {
                        pollingFailures += 5;
                        client.LogMessage("Poll for cluster a manageable exception.  Current error weight (out of 10): " + pollingFailures.ToString(CultureInfo.InvariantCulture),
                                          Severity.Informational,
                                          Verbosity.Diagnostic);
                        client.LogMessage(ex.ToString(), Severity.Informational, Verbosity.Diagnostic);
                        if (pollingFailures >= MaxPollingFailuresCount)
                        {
                            client.LogMessage("Polling error weight exceeded maximum allowed.  Aborting operation.", Severity.Error, Verbosity.Normal);
                            throw;
                        }
                    }
                    else
                    {
                        client.LogMessage("Poll for cluster returned an unmanageable exception.  Aborting operation.", Severity.Error, Verbosity.Normal);
                        client.LogException(ex);
                        throw;
                    }
                }
            }while ((result == PollResult.Continue || result == PollResult.Null || result == PollResult.Unknown) &&
                    DateTime.Now - start < timeout &&
                    pollingFailures <= MaxPollingFailuresCount);
            if (pollingFailures > MaxPollingFailuresCount)
            {
                client.LogMessage("Polling error weight exceeded maximum allowed.  Aborting operation.", Severity.Error, Verbosity.Normal);
            }
            if (notifyHandler.IsNotNull() && pollingResult.IsNotNull())
            {
                notifyHandler(pollingResult);
            }
        }