internal static MonitorJobStatusDto GetStatus(this MonitorJob job, JobStorage storage)
        {
            long currentTicks = DateTime.UtcNow.Ticks;

            if (job.MonitorTime.Ticks > currentTicks)
            {
                return(new MonitorJobStatusDto(MonitorJobStatus.Unstarted));
            }

            var key = job.GetMonitorStateKey();

            using (var connection = storage.GetConnection())
            {
                var source = connection.GetMonitorState(key);

                if (source == null)
                {
                    return(new MonitorJobStatusDto(MonitorJobStatus.Unstarted));
                }

                var startTick = job.MonitorTime.Ticks.ToString();
                var endTick   = job.NextTime.Ticks.ToString();
                var lastKey   = source.Keys.OrderBy(k => k)
                                .LastOrDefault(k => string.Compare(k, startTick) >= 0 && string.Compare(k, endTick) == -1);

                if (string.IsNullOrEmpty(lastKey) && job.NextTime.Ticks < currentTicks)
                {
                    return(new MonitorJobStatusDto(MonitorJobStatus.Unexecuted));
                }
                else if (!string.IsNullOrEmpty(lastKey))
                {
                    var result = source[lastKey].Split(';');

                    return(new MonitorJobStatusDto
                    {
                        Status = (MonitorJobStatus)Enum.Parse(typeof(MonitorJobStatus), result[0]),
                        ExecutedTime = new DateTime(long.Parse(result[1])),
                        ExecutedJobId = result[2]
                    });
                }
            }

            return(new MonitorJobStatusDto(MonitorJobStatus.Unstarted));
        }
 internal static string GetMonitorStateKey(this MonitorJob monitorJob)
 {
     return($"monitor-job:{monitorJob.MonitorTime.ToLocalTime().Date.Ticks}:{monitorJob.ActionName}");
 }