/// <summary>
        /// Determine whether a new task needs to be executed
        /// </summary>
        /// <param name="type">Type</param>
        /// <returns>True if need to execute, false if not</returns>
        public virtual async Task <bool> Check(Type type)
        {
            if (null == type)
            {
                throw new ArgumentNullException("type");
            }

            var entry = new ScheduledTaskEntry()
            {
                PartitionKey = ScheduledTaskEntry.GenerateLogsPartitionKey(type.GetType().ToString()),
                ServiceName  = type.GetType().ToString(),
            };

            var performTask = true;

            var records = await this.storage.QueryByPartition <ScheduledTaskEntry>(entry.PartitionKey);

            if (records != null && records.Any())
            {
                var latest = records.OrderByDescending(x => x.StartTime).First();

                performTask = (latest.CompletionTime.HasValue) ?
                              DateTime.UtcNow.Subtract(latest.CompletionTime.Value) >= period || !latest.Successful :
                              DateTime.UtcNow.Subtract(latest.StartTime) >= retryInterval;
            }

            return(performTask);
        }
        public void ServiceName()
        {
            var expected = ScheduledTaskEntry.GenerateLogsPartitionKey(this.GetType().ToString());
            var entity   = new ScheduledTaskEntry
            {
                ServiceName = expected,
            };

            Assert.AreEqual(expected, entity.ServiceName);
        }
        public void Identifier()
        {
            var entity = new ScheduledTaskEntry
            {
                PartitionKey = ScheduledTaskEntry.GenerateLogsPartitionKey(this.GetType().ToString()),
                ServiceName  = this.GetType().ToString(),
            };

            Assert.IsNull(entity.Identifier);
            var data = Guid.NewGuid();

            entity.Identifier = data;
            Assert.AreEqual(data, entity.Identifier);
            entity.Identifier = null;
            Assert.IsNull(entity.Identifier);
        }
        /// <summary>
        /// Complete
        /// </summary>
        /// <param name="type">Task Type</param>
        /// <param name="identifier">Identifier</param>
        /// <param name="start">Start</param>
        /// <param name="end">End</param>
        /// <param name="success">Success</param>
        /// <returns>Task</returns>
        public virtual async Task Complete(Type type, Guid identifier, DateTime start, DateTime end, bool success)
        {
            if (null == type)
            {
                throw new ArgumentNullException("type");
            }

            await this.storage.InsertOrReplace(new ScheduledTaskEntry
            {
                PartitionKey   = ScheduledTaskEntry.GenerateLogsPartitionKey(type.GetType().ToString()),
                ServiceName    = type.GetType().ToString(),
                Identifier     = Guid.Empty == identifier ? Guid.NewGuid() : identifier,
                StartTime      = start,
                CompletionTime = end,
                Successful     = success,
            });
        }
        /// <summary>
        /// Start
        /// </summary>
        /// <param name="type">Task Type</param>
        /// <param name="identifier">Identifier</param>
        /// <param name="start">Start</param>
        /// <returns>Task</returns>
        public virtual async Task Start(Type type, Guid identifier, DateTime start)
        {
            if (null == type)
            {
                throw new ArgumentNullException("type");
            }
            if (Guid.Empty == identifier)
            {
                throw new ArgumentException("identifier");
            }

            await this.storage.InsertOrReplace(new ScheduledTaskEntry
            {
                PartitionKey = ScheduledTaskEntry.GenerateLogsPartitionKey(type.GetType().ToString()),
                ServiceName  = type.GetType().ToString(),
                Identifier   = identifier,
                StartTime    = start,
            });
        }
        public void GenerateLogsPartitionKey()
        {
            var serviceName = Guid.NewGuid().ToString();

            Assert.AreEqual(string.Format("{0}-{1:yyyy}-{1:MM}", serviceName, DateTime.UtcNow), ScheduledTaskEntry.GenerateLogsPartitionKey(serviceName));
        }