< Summary

Class:Microsoft.Azure.Batch.TaskStateMonitor
Assembly:Microsoft.Azure.Batch
File(s):C:\Git\azure-sdk-for-net\sdk\batch\Microsoft.Azure.Batch\src\TaskStateMonitor.cs
Covered lines:49
Uncovered lines:16
Coverable lines:65
Total lines:251
Line coverage:75.3% (49 of 65)
Covered branches:10
Total branches:14
Branch coverage:71.4% (10 of 14)

Metrics

MethodCyclomatic complexity Line coverage Branch coverage
.ctor()-0%100%
.ctor(...)-100%100%
get_CustomBehaviors()-100%100%
WhenAll()-75%50%
WhenAll()-85.71%100%
WaitAll(...)-0%100%
WhenAllImplAsync()-81.25%75%

File(s)

C:\Git\azure-sdk-for-net\sdk\batch\Microsoft.Azure.Batch\src\TaskStateMonitor.cs

#LineLine coverage
 1// Copyright (c) Microsoft Corporation. All rights reserved.
 2// Licensed under the MIT License. See License.txt in the project root for license information.
 3
 4namespace Microsoft.Azure.Batch
 5{
 6    using System;
 7    using System.Collections.Generic;
 8    using System.Globalization;
 9    using System.Threading;
 10    using System.Threading.Tasks;
 11
 12    /// <summary>
 13    /// Provides utilities to help monitor CloudTask states.
 14    /// </summary>
 15    public class TaskStateMonitor : IInheritedBehaviors
 16    {
 17        private readonly Utilities _parentUtilities;
 18
 19#region constructors
 20
 021        private TaskStateMonitor()
 22        {
 023        }
 24
 325        internal TaskStateMonitor(Utilities parentUtilities, IEnumerable<BatchClientBehavior> baseBehaviors)
 26        {
 327            _parentUtilities = parentUtilities;
 28
 29            // inherit from parent
 330            InheritUtil.InheritClientBehaviorsAndSetPublicProperty(this, baseBehaviors);
 331        }
 32
 33#endregion constructors
 34
 35
 36#region IInheritedBehaviors
 37
 38        /// <summary>
 39        /// Gets or sets a list of behaviors that modify or customize requests to the Batch service
 40        /// made via this <see cref="TaskStateMonitor"/>.
 41        /// </summary>
 42        /// <remarks>
 43        /// <para>These behaviors are inherited by child objects.</para>
 44        /// <para>Modifications are applied in the order of the collection. The last write wins.</para>
 45        /// </remarks>
 646        public IList<BatchClientBehavior> CustomBehaviors { get; set; }
 47
 48        #endregion IInheritedBehaviors
 49
 50        #region TaskStateMonitor
 51
 52        /// <summary>
 53        /// Monitors a <see cref="CloudTask"/> collection until each of its members has reached a desired state at least
 54        /// </summary>
 55        /// <remarks>
 56        /// <para>
 57        /// The state of each <see cref="CloudTask"/> instance is assumed to be authoritative at the time of the call.
 58        /// Instances that are already at the <paramref name="desiredState"/> are ignored.
 59        /// The <see cref="CloudTask"/> instances in the collection are treated as read-only.
 60        /// This means that when the call completes (timeout or not) the <see cref="CloudTask"/> instances should be ref
 61        /// </para>
 62        /// <para>
 63        /// This method runs asynchronously.
 64        /// </para>
 65        /// </remarks>
 66        /// <param name="tasksToMonitor">The collection of tasks to monitor.</param>
 67        /// <param name="desiredState">The target state of the tasks. The method will exit when all tasks have reached t
 68        /// <param name="timeout">The maximum amount of time this call will wait before timing out.</param>
 69        /// <param name="controlParams">Controls various settings of the monitor, such as delay between each poll.</para
 70        /// <param name="additionalBehaviors">A collection of <see cref="BatchClientBehavior"/> instances that are appli
 71        /// <returns>A <see cref="System.Threading.Tasks.Task"/> that represents the asynchronous operation.</returns>
 72        /// <exception cref="TimeoutException">Thrown if the <paramref name="timeout"/> has elapsed.</exception>
 73        public async Task WhenAll(
 74            IEnumerable<CloudTask> tasksToMonitor,
 75            Common.TaskState desiredState,
 76            TimeSpan timeout,
 77            ODATAMonitorControl controlParams = null,
 78            IEnumerable<BatchClientBehavior> additionalBehaviors = null)
 79        {
 180            using (CancellationTokenSource tokenSource = new CancellationTokenSource(timeout))
 81            {
 82                try
 83                {
 184                    await this.WhenAllImplAsync(
 185                        tasksToMonitor,
 186                        desiredState,
 187                        tokenSource.Token,
 188                        controlParams,
 189                        additionalBehaviors).ConfigureAwait(continueOnCapturedContext: false);
 090                }
 191                catch (OperationCanceledException cancellationException)
 92                {
 193                    if (cancellationException.CancellationToken == tokenSource.Token)
 94                    {
 195                        throw new TimeoutException(
 196                            string.Format(CultureInfo.InvariantCulture, BatchErrorMessages.ODataMonitorTimedOut, timeout
 197                            cancellationException);
 98                    }
 99
 0100                    throw;
 101                }
 0102            }
 0103        }
 104
 105        /// <summary>
 106        /// Monitors a <see cref="CloudTask"/> collection until each of its members has reached a desired state at least
 107        /// </summary>
 108        /// <remarks>
 109        /// <para>
 110        /// The state of each <see cref="CloudTask"/> instance is assumed to be authoritative at the time of the call.
 111        /// Instances that are already at the <paramref name="desiredState"/> are ignored.
 112        /// The <see cref="CloudTask"/> instances in the collection are treated as read-only.
 113        /// This means that when the call completes (timeout or not) the <see cref="CloudTask"/> instances should be ref
 114        /// </para>
 115        /// <para>
 116        /// This method runs asynchronously.
 117        /// </para>
 118        /// </remarks>
 119        /// <param name="tasksToMonitor">The collection of tasks to monitor.</param>
 120        /// <param name="desiredState">The target state of the tasks. The method will exit when all tasks have reached t
 121        /// <param name="cancellationToken">A <see cref="CancellationToken"/> for controlling the lifetime of the asynch
 122        /// <param name="controlParams">Controls various settings of the monitor, such as delay between each poll.</para
 123        /// <param name="additionalBehaviors">A collection of <see cref="BatchClientBehavior"/> instances that are appli
 124        /// <returns>A <see cref="System.Threading.Tasks.Task"/> that represents the asynchronous operation.</returns>
 125        /// <exception cref="OperationCanceledException">Thrown if the <paramref name="cancellationToken"/> was cancelle
 126        public async Task WhenAll(
 127            IEnumerable<CloudTask> tasksToMonitor,
 128            Common.TaskState desiredState,
 129            CancellationToken cancellationToken,
 130            ODATAMonitorControl controlParams = null,
 131            IEnumerable<BatchClientBehavior> additionalBehaviors = null)
 132        {
 2133            await this.WhenAllImplAsync(
 2134                tasksToMonitor,
 2135                desiredState,
 2136                cancellationToken,
 2137                controlParams,
 2138                additionalBehaviors).ConfigureAwait(continueOnCapturedContext: false);
 0139        }
 140
 141        /// <summary>
 142        /// Monitors a <see cref="CloudTask"/> collection until each of its members has reached a desired state at least
 143        /// </summary>
 144        /// <remarks>
 145        /// <para>
 146        /// The state of each <see cref="CloudTask"/> instance is assumed to be authoritative at the time of the call.
 147        /// Instances that are already at the <paramref name="desiredState"/> are ignored.
 148        /// The <see cref="CloudTask"/> instances in the collection are treated as read-only.
 149        /// This means that when the call completes (timeout or not) the <see cref="CloudTask"/> instances should be ref
 150        /// </para>
 151        /// <para>
 152        /// This is a blocking operation. For a non-blocking equivalent, see
 153        /// <see cref="WhenAll(System.Collections.Generic.IEnumerable{Microsoft.Azure.Batch.CloudTask},Microsoft.Azure.B
 154        /// </para>
 155        /// </remarks>
 156        /// <param name="tasksToMonitor">The collection of tasks to monitor.</param>
 157        /// <param name="desiredState">The target state of the tasks. The method will exit when all tasks have reached t
 158        /// <param name="timeout">The maximum amount of time this call will wait before timing out.</param>
 159        /// <param name="controlParams">Controls various settings of the monitor, such as delay between each poll.</para
 160        /// <param name="additionalBehaviors">A collection of <see cref="BatchClientBehavior"/> instances that are appli
 161        /// <exception cref="TimeoutException">Thrown if the <paramref name="timeout"/> has elapsed.</exception>
 162        public void WaitAll(
 163            IEnumerable<CloudTask> tasksToMonitor,
 164            Common.TaskState desiredState,
 165            TimeSpan timeout,
 166            ODATAMonitorControl controlParams = null,
 167            IEnumerable<BatchClientBehavior> additionalBehaviors = null)
 168        {
 0169            Task asyncTask = this.WhenAll(tasksToMonitor, desiredState, timeout, controlParams, additionalBehaviors);
 0170            asyncTask.WaitAndUnaggregateException(this.CustomBehaviors, additionalBehaviors);
 0171        }
 172
 173        private async Task WhenAllImplAsync(
 174            IEnumerable<CloudTask> tasksToMonitor,
 175            Common.TaskState desiredState,
 176            CancellationToken cancellationToken,
 177            ODATAMonitorControl controlParams,
 178            IEnumerable<BatchClientBehavior> additionalBehaviors)
 179        {
 3180            if (null == tasksToMonitor)
 181            {
 0182                throw new ArgumentNullException("tasksToMonitor");
 183            }
 184
 185            // we only need the id and state for this monitor.  the filter clause will be updated by the monitor
 3186            ODATADetailLevel odataSuperOptimalPredicates = new ODATADetailLevel() { SelectClause = "id,state" };
 187
 188            // for validation and list calls we need the parent name values
 3189            string jobId = null;
 190
 191            // set up behaviors
 3192            BehaviorManager bhMgr = new BehaviorManager(this.CustomBehaviors, additionalBehaviors);
 193
 194            // set up control params if needed
 3195            if (null == controlParams)
 196            {
 2197                controlParams = new ODATAMonitorControl(); // use defaults
 198            }
 199
 3200            tasksToMonitor = await UtilitiesInternal.EnumerateIfNeededAsync(tasksToMonitor, cancellationToken).Configure
 201
 202            // validation: job schedule id and jobId
 18203            foreach (CloudTask curTask in tasksToMonitor)
 204            {
 205                // can only monitor bound objects
 6206                if (curTask.BindingState != BindingState.Bound)
 207                {
 0208                    Exception ex = UtilitiesInternal.OperationForbiddenOnUnboundObjects;
 209
 0210                    throw ex;
 211                }
 212
 213                // set or validate job Id
 6214                if (null == jobId)
 215                {
 3216                    jobId = curTask.ParentJobId;
 217                }
 218                else
 219                {
 220                    // all instances must have same parent
 3221                    if (!jobId.Equals(curTask.ParentJobId, StringComparison.OrdinalIgnoreCase))
 222                    {
 0223                        Exception ex = UtilitiesInternal.MonitorRequiresConsistentHierarchyChain;
 224
 0225                        throw ex;
 226                    }
 227                }
 228            }
 229
 230            // start call
 3231            Task asyncTask = ODATAMonitor.WhenAllAsync(
 3232                tasksToMonitor,
 3233                x =>
 3234                {
 3235                    // return true if is desired state
 15236                    bool hasReachedDesiredState = x.State == desiredState;
 15237                    return hasReachedDesiredState;
 3238                },
 12239                x => { return x.Id; },  // return the Id of the task
 6240                () => _parentUtilities.ParentBatchClient.JobOperations.ListTasksImpl(jobId, bhMgr, odataSuperOptimalPred
 3241                cancellationToken,
 3242                odataSuperOptimalPredicates,
 3243                controlParams);
 244
 3245            await asyncTask.ConfigureAwait(continueOnCapturedContext: false);
 0246        }
 247
 248#endregion TaskStateMonitor
 249
 250    }
 251}