/// <summary>
        /// Saves a HealthCheckScheduleItem to the dictionary.
        /// </summary>
        /// <param name="tx">ITransaction instance.</param>
        /// <param name="item">HealthCheckScheuleItem instance.</param>
        /// <returns>True if successful, otherwise false.</returns>
        /// <remarks>Separate method to address possible key collisions.</remarks>
        internal async Task <bool> SaveAsync(ITransaction tx, WatchdogScheduledItem item)
        {
            int retryCount = 5;

            // Get the schedule dictionary.
            IReliableDictionary <long, WatchdogScheduledItem> schedDict = await this.GetHealthCheckScheduleDictionaryAsync().ConfigureAwait(false);

            // Get a copy of the desired execution time.
            long key = item.ExecutionTicks;

            while (retryCount-- >= 0)
            {
                // Attempt to add the item. There may be a collision because the key already exists.
                // If it doesn't succeed try again with a new key.
                if (await schedDict.TryAddAsync(tx, key, item, this._timeout, this._token).ConfigureAwait(false))
                {
                    return(true);
                }

                // Increment the key value.
                key++;
            }

            // Exhausted the number of allowed retries.
            return(false);
        }
        public void WatchdogScheduledItem_SerializationTest()
        {
            // Serialize to the output buffer as binary.
            OutputBuffer output = new OutputBuffer();
            CompactBinaryWriter <OutputBuffer> writer = new CompactBinaryWriter <OutputBuffer>(output);

            Serialize.To(writer, hcs);

            // De-serialize from the binary output.
            InputBuffer input = new InputBuffer(output.Data);
            CompactBinaryReader <InputBuffer> reader = new CompactBinaryReader <InputBuffer>(input);
            WatchdogScheduledItem             hcs1   = Deserialize <WatchdogScheduledItem> .From(reader);

            Assert.IsTrue(hcs.Equals(hcs1));

            // Using the generic BondCustomSerializer.
            using (MemoryStream ms = new MemoryStream())
            {
                using (BinaryWriter bw = new BinaryWriter(ms))
                {
                    BondCustomSerializer <WatchdogScheduledItem> bcs = new BondCustomSerializer <WatchdogScheduledItem>();
                    bcs.Write(hcs, bw);

                    ms.Position = 0L;

                    using (BinaryReader br = new BinaryReader(ms))
                    {
                        hcs1 = bcs.Read(br);
                        Assert.IsTrue(hcs.Equals(hcs1));
                    }
                }
            }
        }
        public void WatchdogScheduledItem_ConstructorTest()
        {
            WatchdogScheduledItem hcsi = new WatchdogScheduledItem();

            Assert.IsNull(hcsi.Key);
            Assert.AreEqual(default(DateTimeOffset).UtcTicks, hcsi.ExecutionTicks);
        }
        public void WatchdogScheduledItem_EqualsTest()
        {
            WatchdogScheduledItem hc1 = new WatchdogScheduledItem(now, key);

            Assert.IsTrue(hcs.Equals(hc1));

            hc1 = new WatchdogScheduledItem(DateTimeOffset.UtcNow, key);
            Assert.IsFalse(hcs.Equals(hc1));

            hc1 = new WatchdogScheduledItem(now, "fabric:/app/svc/0000000");
            Assert.IsFalse(hcs.Equals(hc1));
        }
        /// <summary>
        /// Performs a HealthCheck for a scheduled item.
        /// </summary>
        /// <param name="item">WatchdogScheduledItem instance.</param>
        internal async Task PerformItemHealthCheckAsync(WatchdogScheduledItem item)
        {
            // Get the health check dictionaries.
            IReliableDictionary <string, HealthCheck> dict = await this.GetHealthCheckDictionaryAsync();

            IReliableDictionary <long, WatchdogScheduledItem> scheduleDict = await this.GetHealthCheckScheduleDictionaryAsync();

            // Create a transaction.
            using (ITransaction tx = this._service.StateManager.CreateTransaction())
            {
                // Attempt to get the HealthCheck instance for the key. If not return.
                ConditionalValue <HealthCheck> cv = await dict.TryGetValueAsync(tx, item.Key, LockMode.Update);

                if (cv.HasValue)
                {
                    HealthCheck hc = cv.Value;

                    try
                    {
                        // Find the partition information that matches the partition identifier.
                        // If the partition isn't found, remove the health check item.
                        Partition partition = await this.FindMatchingPartitionAsync(hc.Partition);

                        if (null == partition)
                        {
                            await dict.TryRemoveAsync(tx, hc.Key, this._timeout, this._token);
                        }
                        else
                        {
                            // Execute the check and evaluate the results returned in the new HealthCheck instance.
                            hc = await this.ExecuteHealthCheckAsync(hc, partition);

                            // Update the value of the HealthCheck to store the results of the test.
                            await dict.TryUpdateAsync(tx, item.Key, hc, cv.Value);

                            // Remove the current scheduled item.
                            await scheduleDict.TryRemoveAsync(tx, item.ExecutionTicks);

                            // Add the new scheduled item.
                            WatchdogScheduledItem newItem = new WatchdogScheduledItem(hc.LastAttempt.Add(hc.Frequency), hc.Key);
                            await(scheduleDict.TryAddAsync(tx, newItem.ExecutionTicks, newItem));
                        }

                        // Commit the transaction.
                        await tx.CommitAsync();
                    }
                    catch (TimeoutException ex)
                    {
                        ServiceEventSource.Current.ServiceMessage(this._service.Context, ex.Message);
                    }
                    catch (FabricNotPrimaryException ex)
                    {
                        ServiceEventSource.Current.ServiceMessage(this._service.Context, ex.Message);
                        return;
                    }
                    catch (Exception ex)
                    {
                        ServiceEventSource.Current.ServiceMessage(this._service.Context, ex.Message);
                        throw;
                    }
                }
            }
        }