private static async Task DoJob(ChannelReader <JobInfo> reader) { using (JobsRepo repo = new JobsRepo()) { while (await reader.WaitToReadAsync()) { while (reader.TryRead(out JobInfo job)) { Task.Run(async() => { var now = DateTime.Now; if (job.RunAt > now) { await Task.Delay(job.RunAt.Subtract(now)); } if (repo.AcquireJobLock(job.Id)) { repo.ProcessLockedJob(job.Id); Console.WriteLine("O"); } else { Console.WriteLine("X"); } }).Wait(); } if (reader.Completion.IsCompleted) { break; } } } }
public JobWorker(int concurrentSize) { using (JobsRepo repo = new JobsRepo()) { while (true) { JobInfo job = Queue.pop(); long delay = (job.RunAt.Ticks / TimeSpan.TicksPerMillisecond) - (DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond); //Console.WriteLine("[" + job.Id + "] job.RunAt=> " + job.RunAt + ", DateTime.Now=>" + DateTime.Now + ", delay =>" + delay); if (delay > 0) { Task.Delay(TimeSpan.FromMilliseconds(delay)).Wait(); } if (repo.GetJob(job.Id).State == 0) { if (repo.AcquireJobLock(job.Id)) { repo.ProcessLockedJob(job.Id); Console.Write("[" + job.Id + "]" + "O"); } else { Console.Write("[" + job.Id + "]" + "X"); } } } } }
public static void Main() { var jobs = new JobsRepo(); string input; while ((input = Console.ReadLine()) != "End") { var args = input.Split(); switch (args[0]) { case "Job": jobs.CreateJob(args[1], int.Parse(args[2]), args[3]); break; case "StandardEmployee": jobs.CreateEmployee(new StandardEmployee(args[1])); break; case "PartTimeEmployee": jobs.CreateEmployee(new PartTimeEmployee(args[1])); break; case "Pass": jobs.PassWeek(); break; case "Status": jobs.Status(); break; } } }
protected override async Task ExecuteAsync(CancellationToken stoppingToken) { using (var repo = new JobsRepo()) { while (!stoppingToken.IsCancellationRequested) { _logger.LogInformation("RetrieveWorker running at: {time}", DateTimeOffset.Now); // get jobs into queue list // set duration with a delta time to compensate the delay time of various items var duration = (JobSettings.MinPrepareTime + JobSettings.MaxDelayTime).Add(new TimeSpan(0, 0, 0, -5, 0)); var jobs = repo.GetReadyJobs(duration).ToList(); _logger.LogWarning($"Retrieve job count: {jobs.Count}"); // remove duplicate items jobs.RemoveAll(x => Program.JobList.Select(i => i.Id).Contains(x.Id)); var obj = new object(); lock (obj) { Program.JobList.AddRange(jobs); } await Task.Delay(duration, stoppingToken).ConfigureAwait(false); } } }
public void CheckSprints() { SprintsRepo.Sprints.Where(s => s.EndData < DateTime.Today).ToList() .ForEach(s => { SprintsRepo.CloseSprint(s); JobsRepo.CloseSprint(s); }); }
protected async override Task ExecuteAsync(CancellationToken stoppingToken) { ThreadPool.SetMinThreads(MAX_CONCURRENT_SIZE, MAX_CONCURRENT_SIZE); Random random = new Random(); TimeSpan sleepSpan; double runAtRange = JobSettings.MinPrepareTime.TotalSeconds; for (int i = 0; i < MAX_CONCURRENT_SIZE; i++) { Task.Run(() => { JobWorker jobWorker = new JobWorker(MAX_CONCURRENT_SIZE); }); } await Task.Delay(1); using (JobsRepo repo = new JobsRepo()) { while (stoppingToken.IsCancellationRequested == false) { JobInfo tmpJobInfo = null; foreach (JobInfo job in repo.GetReadyJobs(TimeSpan.FromSeconds(runAtRange))) { Queue.push(job); //Console.WriteLine(job.Id + "\t" + job.RunAt); tmpJobInfo = job; } //計算SLEEP多久 if (tmpJobInfo == null) { sleepSpan = TimeSpan.FromMilliseconds((10 * 1000) + random.Next(5 * 1000)); //Console.WriteLine("[random]" + sleepSpan.Seconds + "\t" + sleepSpan.TotalSeconds); } else { sleepSpan = TimeSpan.FromSeconds((tmpJobInfo.RunAt.AddSeconds(random.Next(15)) - DateTime.Now).Seconds + 1); //Console.WriteLine("[next]" + sleepSpan.Seconds + "\t" + sleepSpan.TotalSeconds); } await Task.Delay(sleepSpan, stoppingToken); Console.Write("_"); } } }
private void DoWorkerThread() { using (var repo = new JobsRepo()) { while (true) { while (_workItems.Count > 0) { JobInfo job = null; lock (_workItems) { if (_workItems.Count > 0) { job = _workItems.Dequeue(); } } if (job == null) { continue; } if (repo.GetJob(job.Id).State == 0) { if (repo.AcquireJobLock(job.Id)) { repo.ProcessLockedJob(job.Id); Console.WriteLine($"[Consumer][Done] #{job.Id}"); } else { Console.WriteLine($"[Consumer][Failed] #{job.Id}"); } } if (_cancelFlag) { break; } } if (_stopFlag || _cancelFlag) { break; } if (_enqueueNotify.WaitOne(_maxWorkerThreadTimeout, true)) { continue; } break; } } _workerThreads.Remove(Thread.CurrentThread); }
protected async override Task ExecuteAsync(CancellationToken stoppingToken) { await Task.Delay(1); List <Thread> threads = new List <Thread>(); for (int i = 0; i < 5; i++) { Thread T = new Thread(Worker); threads.Add(T); T.Start(); } using (JobsRepo repo = new JobsRepo()) { while (stoppingToken.IsCancellationRequested == false) { DateTime LastQueryTime = DateTime.Now; foreach (JobInfo job in repo.GetReadyJobs(JobSettings.MinPrepareTime)) { if (stoppingToken.IsCancellationRequested == true) { break; } if (repo.GetJob(job.Id).State == 0 && repo.AcquireJobLock(job.Id)) { if (job.RunAt > DateTime.Now) { await Task.Delay(job.RunAt - DateTime.Now); } queue.Add(job); } } if (stoppingToken.IsCancellationRequested == false && LastQueryTime.Add(JobSettings.MinPrepareTime) > DateTime.Now ) { await Task.Delay(LastQueryTime.Add(JobSettings.MinPrepareTime) - DateTime.Now); } } } queue.CompleteAdding(); threads.ForEach(T => { T.Join(); }); Console.WriteLine($"- shutdown event detected, stop worker service..."); }
private void Worker() { using (JobsRepo repo = new JobsRepo()) { foreach (JobInfo job in this.queue.GetConsumingEnumerable()) { repo.ProcessLockedJob(job.Id); } } }
private void ProcessJob() { using (JobsRepo repo = new JobsRepo()) { foreach (var jobInfo in blockingCollection.GetConsumingEnumerable()) { repo.ProcessLockedJob(jobInfo.Id); } } }
protected override async Task ExecuteAsync(CancellationToken stoppingToken) { var channels = new List <Channel <JobInfo> >(); for (int i = 0; i < maxChannelNumber; i++) { var ch = Channel.CreateBounded <JobInfo>(new BoundedChannelOptions(1) { SingleWriter = true, SingleReader = true, AllowSynchronousContinuations = true }); channels.Add(ch); } foreach (var ch in channels) { DoJob(ch); } using (JobsRepo repo = new JobsRepo()) { while (stoppingToken.IsCancellationRequested == false) { var newJobs = repo.GetReadyJobs(TimeSpan.FromSeconds(10)).ToList(); foreach (var job in newJobs) { var done = false; while (!done) { foreach (var channel in channels) { var writer = channel.Writer; if (writer.WaitToWriteAsync(stoppingToken).Result) { writer.TryWrite(job); done = true; break; } } } } try { await Task.Delay(JobSettings.MinPrepareTime, stoppingToken); Console.Write("_"); } catch (TaskCanceledException) { break; } } } }
public ActionResult AddExistingUser(Workers frm) { var uRepo = new UsersRepo(); var usr = uRepo.GetById(frm.UserId); ViewBag.SeasonId = frm.SeasonId; if (usr == null || usr.FullName != frm.FullName) { ModelState.AddModelError("FullName", Messages.UserNotExists); return(PartialView("_WorkerList", GetWorkerVMByRelevantEntity(frm.RelevantEntityId, frm.RelevantEntityLogicalName, frm.SeasonId, frm.LeagueId))); } var uJob = new UsersJob { JobId = frm.JobId, UserId = usr.UserId, SeasonId = frm.SeasonId, LeagueId = (frm.LeagueId == 0 ? (int?)null : frm.LeagueId) }; switch (frm.RelevantEntityLogicalName) { case LogicaName.Union: uJob.UnionId = frm.RelevantEntityId; break; case LogicaName.League: uJob.LeagueId = frm.RelevantEntityId; break; case LogicaName.Team: uJob.TeamId = frm.RelevantEntityId; break; case LogicaName.Club: uJob.ClubId = frm.RelevantEntityId; break; } var jobsRepo = new JobsRepo(); if (jobsRepo.IsUserInJob(frm.RelevantEntityLogicalName, frm.RelevantEntityId, uJob.JobId, usr.UserId)) { ModelState.AddModelError("FullName", Messages.UserAlreadyHasThisRole); return(PartialView("_WorkerList", GetWorkerVMByRelevantEntity(frm.RelevantEntityId, frm.RelevantEntityLogicalName, frm.SeasonId, frm.LeagueId))); } jobsRepo.AddUsersJob(uJob); jobsRepo.Save(); TempData["SavedId"] = uJob.UserId; return(PartialView("_WorkerList", GetWorkerVMByRelevantEntity(frm.RelevantEntityId, frm.RelevantEntityLogicalName, frm.SeasonId, frm.LeagueId))); }
protected override async Task ExecuteAsync(CancellationToken stoppingToken) { await Task.Delay(1, stoppingToken); using (var repo = new JobsRepo(_connectionString)) { while (stoppingToken.IsCancellationRequested == false) { JobInfo lastJobInThisRound = null; TimeSpan intervalSeconds = _defaultFetchJobsIntervalSeconds; Console.WriteLine("[Producer][FetchJobs]"); var jobs = repo.GetReadyJobs(_fetchJobsRunAtRange); foreach (var job in jobs) { if (stoppingToken.IsCancellationRequested) { goto shutdown; } Console.WriteLine($"[Producer][PutJobToQueue] #{job.Id} run at {job.RunAt}"); _stp.QueueUserWorkerItem(job); lastJobInThisRound = job; } try { if (lastJobInThisRound != null) { intervalSeconds = TimeSpan.FromSeconds((lastJobInThisRound.RunAt - DateTime.Now).Seconds + 1); Console.WriteLine($"[Producer][WaitForNextJob] {intervalSeconds.TotalSeconds} seconds"); } else { Console.WriteLine($"[Producer][Wait] {intervalSeconds.TotalSeconds} seconds"); } await Task.Delay(intervalSeconds, stoppingToken); } catch (TaskCanceledException) { _stp.Dispose(); break; } } } shutdown: Console.WriteLine("[System] In Levi's BackgroundService'"); Console.WriteLine("[System] Shutdown event detected, stop worker service..."); }
public JobWorker(int concurrentSize) { using (JobsRepo repo = new JobsRepo("Data Source=(LocalDB)\\MSSQLLocalDB;AttachDbFilename=D:\\workspace\\dotnet\\SchedulingPractice\\SubWorker.AndrewDemo\\JobsDB.mdf;Integrated Security=True")) { while (true) { JobInfo job = Queue.pop(); repo.ProcessLockedJob(job.Id); } } }
private void ProcessThread() { using (JobsRepo repo = new JobsRepo()) { foreach (var job in this._queue.GetConsumingEnumerable()) { repo.ProcessLockedJob(job.Id); Console.WriteLine($"[T: {Thread.CurrentThread.ManagedThreadId}] process job({job.Id}) with delay {(DateTime.Now - job.RunAt).TotalMilliseconds} msec..."); } Console.WriteLine($"[T: {Thread.CurrentThread.ManagedThreadId}] process worker thread was terminated..."); } }
protected override async Task ExecuteAsync(CancellationToken stoppingToken) { await Task.Delay(1); List <Thread> threads = new List <Thread>(); for (int i = 0; i < threadCount; i++) { Thread T = new Thread(ProcessJob); threads.Add(T); T.Start(); } using (JobsRepo repo = new JobsRepo()) { while (stoppingToken.IsCancellationRequested == false) { foreach (var job in repo.GetReadyJobs()) { if (stoppingToken.IsCancellationRequested == true) { goto shutdown; } if (repo.GetJob(job.Id).State == (int)JobStateEnum.CREATE && repo.AcquireJobLock(job.Id)) { if (job.RunAt > DateTime.Now) { await Task.Delay(job.RunAt - DateTime.Now); } blockingCollection.Add(job); } } try { await Task.Delay(JobSettings.MinPrepareTime, stoppingToken); } catch (TaskCanceledException) { break; } } } shutdown: this.blockingCollection.CompleteAdding(); foreach (var thread in threads) { thread.Join(); } Console.WriteLine($"End"); }
private void RunThread() { using (JobsRepo repo = new JobsRepo()) { foreach (var job in readyJobs) { if (job.State == 0 && repo.AcquireJobLock(job.Id)) { if (repo.ProcessLockedJob(job.Id)) { Console.WriteLine($"[job ID: {job.Id}] update state...."); } } } } }
protected async override Task ExecuteAsync(CancellationToken stoppingToken) { await Task.Delay(1); using (JobsRepo repo = new JobsRepo()) { while (stoppingToken.IsCancellationRequested == false) { bool empty = true; foreach (var job in repo.GetReadyJobs()) { if (stoppingToken.IsCancellationRequested == true) { goto shutdown; } if (repo.AcquireJobLock(job.Id)) { repo.ProcessLockedJob(job.Id); Console.Write("O"); } else { Console.Write("X"); } empty = false; } if (empty == false) { continue; } try { await Task.Delay(10000, stoppingToken); Console.Write("_"); } catch (TaskCanceledException) { break; } } } shutdown: Console.WriteLine($"- shutdown event detected, stop worker service..."); }
protected async override Task ExecuteAsync(CancellationToken stoppingToken) { await Task.Delay(1); using (JobsRepo repo = new JobsRepo("Data Source=(LocalDB)\\MSSQLLocalDB;AttachDbFilename=D:\\workspace\\dotnet\\SchedulingPractice\\SubWorker.AndrewDemo\\JobsDB.mdf;Integrated Security=True")) { while (stoppingToken.IsCancellationRequested == false) { bool empty = true; foreach (var job in repo.GetReadyJobs()) { if (stoppingToken.IsCancellationRequested == true) { goto shutdown; } if (repo.AcquireJobLock(job.Id)) { repo.ProcessLockedJob(job.Id); Console.Write("O"); } else { Console.Write("X"); } empty = false; } if (empty == false) { continue; } try { await Task.Delay(JobSettings.MinPrepareTime, stoppingToken); Console.Write("_"); } catch (TaskCanceledException) { break; } } } shutdown: Console.WriteLine($"- shutdown event detected, stop worker service..."); }
protected override async Task ExecuteAsync(CancellationToken stoppingToken) { using (var repo = new JobsRepo()) { while (!stoppingToken.IsCancellationRequested) { _logger.LogInformation("ExecuteWorker running at: {time}", DateTimeOffset.Now); // get all jobs need to be process from JobList var readyJobs = Program.JobList.Where(x => (DateTime.Now - x.RunAt) > new TimeSpan(0, 0, 0, 0, JobSettings.LoopDuration)).ToList(); if (readyJobs.Count > 0) { _logger.LogWarning($"Current execute job count: {readyJobs.Count}"); } // process all jobs by using Task.Run foreach (JobInfo job in readyJobs) { //Task.Run(() => //{ var isLock = repo.AcquireJobLock(job.Id); if (isLock) { repo.ProcessLockedJob(job.Id); } //}); } var obj = new object(); lock (obj) { Program.JobList.RemoveAll(x => readyJobs.Select(i => i.Id).Contains(x.Id)); } await Task.Delay(JobSettings.LoopDuration, stoppingToken).ConfigureAwait(false); } } }
protected async override Task ExecuteAsync(CancellationToken stoppingToken) { this._stop = stoppingToken; TimeSpan duration = JobSettings.MinPrepareTime + JobSettings.MaxDelayTime; using (JobsRepo repo = new JobsRepo()) { while (true) { readyJobs = repo.GetReadyJobs(duration).Where(x => x.LockAt == null).ToList(); Program.JobList.AddRange(readyJobs); try { Console.WriteLine("---------- GetJobsList ----------"); await Task.Delay(duration, stoppingToken); } catch (TaskCanceledException) { break; } } } }
private void ExuteBody() { while (_stop == false) { JobInfo job = null; while (this._jobList.TryTake(out job)) { if (job.RunAt > DateTime.Now) { var sleepTime = job.RunAt.Subtract(DateTime.Now); int index = Task.WaitAny( Task.Delay(sleepTime), Task.Run(() => _stopAre.WaitOne())); if (index == 1) { break; } } using (JobsRepo repo = new JobsRepo(this._connectString)) { if (repo.AcquireJobLock(job.Id)) { repo.ProcessLockedJob(job.Id); Console.Write("O"); } else { Console.Write("X"); } } } Task.WaitAny( Task.Run(() => _stopAre.WaitOne()), Task.Run(() => _doJobAre.WaitOne())); } }
protected async override Task ExecuteAsync(CancellationToken stoppingToken) { await Task.Delay(1); this._stop = stoppingToken; using (JobsRepo repo = new JobsRepo()) { while (true) { readyJobs = repo.GetReadyJobs(JobSettings.MinPrepareTime).ToList(); foreach (var job in readyJobs) { if (job.State == 0 && repo.AcquireJobLock(job.Id)) { if (repo.ProcessLockedJob(job.Id)) { Console.WriteLine($"[job ID: {job.Id}] update state...."); } } } //Thread[] threads = new Thread[threadsCnts]; //for (int i = 0; i < threadsCnts; i++) //{ // threads[i] = new Thread(RunThread); // threads[i].Start(); //} try { await Task.Delay(JobSettings.MinPrepareTime, stoppingToken); Console.Write("_"); } catch (TaskCanceledException) { break; } } } }
protected async override Task ExecuteAsync(CancellationToken stoppingToken) { await Task.Delay(1); this._stop = stoppingToken; TimeSpan duration = JobSettings.ExecuteDuration; using (JobsRepo repo = new JobsRepo()) { while (true) { readyJobs = Program.JobList; while (readyJobs.Count > 0) { var jobs = readyJobs.Where(x => x.RunAt <= DateTime.Now).ToList(); foreach (var job in jobs) { if (job.State == 0 && repo.AcquireJobLock(job.Id)) { if (repo.ProcessLockedJob(job.Id)) { Console.WriteLine($"[job ID: {job.Id}] update state...."); readyJobs.Remove(job); } } } Program.JobList.RemoveAll(x => jobs.Select(y => y.Id).Contains(x.Id)); } //try //{ // Console.WriteLine("---------- Delay ----------"); // await Task.Delay(duration, stoppingToken); //} //catch (TaskCanceledException) { break; } } } }
protected async override Task ExecuteAsync(CancellationToken stoppingToken) { ThreadPool.SetMaxThreads(5, 5); ThreadPool.QueueUserWorkItem(Worker, 0); ThreadPool.QueueUserWorkItem(Worker, 1); ThreadPool.QueueUserWorkItem(Worker, 2); ThreadPool.QueueUserWorkItem(Worker, 3); ThreadPool.QueueUserWorkItem(Worker, 4); using (JobsRepo repo = new JobsRepo()) { while (stoppingToken.IsCancellationRequested == false) { var newJob = repo.GetReadyJobs(TimeSpan.FromSeconds(15)).ToList(); jobList = getCleanDictionary(); for (int i = 0; i < newJob.Count; i++) { jobList[i % 5].Enqueue(newJob[i]); } try { await Task.Delay(5000, stoppingToken); Console.Write("_"); } catch (TaskCanceledException) { break; } } } shutdown: Console.WriteLine($"- shutdown event detected, stop worker service..."); }
private static void Worker(object obj) { var index = (int)obj; JobInfo job; while (true) { if (jobList == null || jobList[index] == null || jobList[index].TryDequeue(out job) == false) { Thread.Sleep(20); continue; } if (job != null && job.RunAt <= DateTime.Now) { try { using (var repo = new JobsRepo()) { job = repo.GetJob(job.Id); if (job.State == 0 && repo.AcquireJobLock(job.Id)) { repo.ProcessLockedJob(job.Id); Console.Write("O"); } else { Console.Write("X"); } } } catch { Console.Write("E"); } } } }
private void FetchJob() { while (_stop == false) { using (JobsRepo repo = new JobsRepo(_connectString)) { var jobs = repo.GetReadyJobs(TimeSpan.FromSeconds(_intervalSecond)); foreach (var job in jobs.OrderBy(X => X.RunAt)) { this._jobList.Add(job); Console.WriteLine(job.Id); } _doJobAre.Set(); _doJobAre.Reset(); } Task.WaitAny(Task.Delay(TimeSpan.FromSeconds(_intervalSecond)), Task.Run(() => _stopAre.WaitOne())); } }
static void Main(string[] args) { if (args.Length != 5) { Console.WriteLine("Usage: PubWorker.exe [since] [duration] [runner] [mode] [csv-path]"); } int since_sec = int.Parse(args[0]); int duration_sec = int.Parse(args[1]); string runner = args[2]; string mode = args[3]; string path = args[4]; // 設定: 預定測試開始時間 DateTime since = DateTime.Now.AddSeconds(since_sec); // 設定: 預定測試持續時間 TimeSpan duration = TimeSpan.FromMinutes(1); // 計算: 預定測試預計結束時間 DateTime until = since + duration; // 統計: 累計總任務數 int total = 0; using (var repo = new JobsRepo()) { Console.WriteLine($"Init test database..."); Console.WriteLine($"- now: {DateTime.Now}"); Console.WriteLine($"- since: {since}"); Console.WriteLine($"- until: {until}"); Console.WriteLine(); Console.WriteLine($"Step 0: reset database..."); repo.ResetDatabase(); // step 1: add one job per 3 sec { Console.WriteLine(); Console.WriteLine($"Step 1: add job per 3 sec"); int count = 0; DateTime current = since; TimeSpan period = TimeSpan.FromSeconds(3); while (current < until) { count++; current = current + period; Console.Write("."); repo.CreateJob(current); } total += count; Console.WriteLine(); Console.WriteLine($"- complete({count})."); } // step 2: add 20 job per 13 sec { Console.WriteLine(); Console.WriteLine($"Step 2: add 20 jobs per 13 sec"); int count = 0; DateTime current = since; TimeSpan period = TimeSpan.FromSeconds(13); int loop = 20; while (current < until) { current = current + period; for (int i = 0; i < loop; i++) { count++; Console.Write("."); repo.CreateJob(current); } } total += count; Console.WriteLine(); Console.WriteLine($"- complete({count})."); } // step 3: random add job per 1 ~ 3 sec { Console.WriteLine(); Console.WriteLine($"Step 3: random add job per 1 ~ 3 sec"); int count = 0; Random rnd = new Random(); DateTime current = since; while (current < until) { current = current + TimeSpan.FromMilliseconds(1000 + rnd.Next(2000)); count++; Console.Write("."); repo.CreateJob(current); } total += count; Console.WriteLine(); Console.WriteLine($"- complete({count})."); } // step 4, realtime: add a job scheduled after 10 sec, and random waiting 1 ~ 3 sec. { Console.WriteLine(); Console.WriteLine($"Step 4: realtime: add a job scheduled after 10 sec, and random waiting 1 ~ 3 sec."); int count = 0; Random rnd = new Random(); while (DateTime.Now.AddSeconds(10) < until) { Task.Delay(1000 + rnd.Next(2000)).Wait(); count++; Console.Write("."); repo.CreateJob(DateTime.Now + JobSettings.MinPrepareTime + TimeSpan.FromMilliseconds(100)); } total += count; Console.WriteLine(); Console.WriteLine($"- complete({count})."); } Console.WriteLine(); Console.WriteLine($"Database initialization complete."); Console.WriteLine($"- total jobs: {total}"); Console.WriteLine($"- now: {DateTime.Now}"); Console.WriteLine($"- since: {since}"); Console.WriteLine($"- until: {until}"); // step 5, wait 30 sec, show statistic Task.Delay(JobSettings.MaxDelayTime + JobSettings.MinPrepareTime).Wait(); var metrics = repo.GetStatstics(); Console.WriteLine(); Console.WriteLine($"Jobs Scheduling Metrics:"); Console.WriteLine(); Console.WriteLine("--(action count)----------------------------------------------"); Console.WriteLine($"- CREATE: {metrics.count_action_create}"); Console.WriteLine($"- ACQUIRE_SUCCESS: {metrics.count_action_acquire_success}"); Console.WriteLine($"- ACQUIRE_FAILURE: {metrics.count_action_acquire_failure}"); Console.WriteLine($"- COMPLETE: {metrics.count_action_complete}"); Console.WriteLine($"- QUERYJOB: {metrics.count_action_queryjob}"); Console.WriteLine($"- QUERYLIST: {metrics.count_action_querylist}"); Console.WriteLine(); Console.WriteLine("--(state count)----------------------------------------------"); Console.WriteLine($"- COUNT(CREATE): {metrics.count_state_create}"); Console.WriteLine($"- COUNT(LOCK): {metrics.count_state_lock}"); Console.WriteLine($"- COUNT(COMPLETE): {metrics.count_action_complete}"); Console.WriteLine(); Console.WriteLine("--(statistics)----------------------------------------------"); Console.WriteLine($"- DELAY(Average): {metrics.stat_average_delay}"); Console.WriteLine($"- DELAY(Stdev): {metrics.stat_stdev_delay}"); Console.WriteLine(); Console.WriteLine("--(test result)----------------------------------------------"); Console.WriteLine($"- Complete Job: {metrics.count_action_complete == metrics.count_action_create}, {metrics.count_action_complete} / {metrics.count_action_create}"); Console.WriteLine($"- Delay Too Long: {metrics.stat_delay_exceed_count}"); Console.WriteLine($"- Fail Job: {metrics.count_state_lock == 0}, {metrics.count_state_lock}"); Console.WriteLine(); Console.WriteLine("--(benchmark score)----------------------------------------------"); Console.WriteLine($"- Exec Cost Score: {metrics.count_action_querylist * 100.0 + metrics.count_action_acquire_failure * 10.0 + metrics.count_action_queryjob * 1.0:#.##} (querylist x 100 + acquire-failure x 10 + queryjob x 1)"); Console.WriteLine($"- Efficient Score: {metrics.stat_average_delay + metrics.stat_stdev_delay:#.##} (average + stdev)"); // RUNNER, MODE, // CREATE, ACQUIRE_SUCCESS, ACQUIRE_FAILURE, COMPLETE, QUERYJOB, QUERYLIST, // CREATE_COUNT, LOCK_COUNT, COMPLETE_COUNT, // DELAY_AVERAGE, DELAY_STDEV, // DELAY_EXCEED, EARLY_LOCK, EARLY_EXEC, // EXEC_COST_SCORE, EFFICIENT_SCORE, //string path = @"result-stat.csv"; if (File.Exists(path) == false) { File.AppendAllText( path, @"RUNNER, MODE, " + @"CREATE, ACQUIRE_SUCCESS, ACQUIRE_FAILURE, COMPLETE, QUERYJOB, QUERYLIST, " + @"CREATE_COUNT, LOCK_COUNT, COMPLETE_COUNT, " + @"DELAY_AVERAGE, DELAY_STDEV, " + @"DELAY_EXCEED, EARLY_LOCK, EARLY_EXEC, " + "\n"); } File.AppendAllText( path, $"{Environment.GetEnvironmentVariable("RUNNER")}, {Environment.GetEnvironmentVariable("MODE")}," + $"{metrics.count_action_create}, {metrics.count_action_acquire_success}, {metrics.count_action_acquire_failure}, {metrics.count_action_complete}, {metrics.count_action_queryjob}, {metrics.count_action_querylist}, " + $"{metrics.count_state_create}, {metrics.count_state_lock}, {metrics.count_state_complete}, " + $"{metrics.stat_average_delay}, {metrics.stat_stdev_delay}, " + $"{metrics.stat_delay_exceed_count}, {metrics.count_state_early_lock}, {metrics.count_state_early_exec}, " + "\n"); } }
public JobsService(JobsRepo repo) { _repo = repo; }
static void Main(string[] args) { // 設定: 預定測試持續時間 TimeSpan duration = TimeSpan.FromMinutes(1); // 設定: 預定測試開始時間 DateTime since = DateTime.Now.AddSeconds(30); // 計算: 預定測試預計結束時間 DateTime until = since + duration; // 統計: 累計總任務數 int total = 0; using (var repo = new JobsRepo()) { Console.WriteLine($"Init test database..."); Console.WriteLine($"- now: {DateTime.Now}"); Console.WriteLine($"- since: {since}"); Console.WriteLine($"- until: {until}"); Console.WriteLine(); Console.WriteLine($"Step 0: reset database..."); repo.ResetDatabase(); // step 1: add one job per 3 sec { Console.WriteLine(); Console.WriteLine($"Step 1: add job per 3 sec"); int count = 0; DateTime current = since; TimeSpan period = TimeSpan.FromSeconds(3); while (current < until) { count++; current = current + period; Console.Write("."); repo.CreateJob(current); } total += count; Console.WriteLine(); Console.WriteLine($"- complete({count})."); } // step 2: add 20 job per 13 sec { Console.WriteLine(); Console.WriteLine($"Step 2: add 20 jobs per 13 sec"); int count = 0; DateTime current = since; TimeSpan period = TimeSpan.FromSeconds(13); int loop = 20; while (current < until) { current = current + period; for (int i = 0; i < loop; i++) { count++; Console.Write("."); repo.CreateJob(current); } } total += count; Console.WriteLine(); Console.WriteLine($"- complete({count})."); } // step 3: random add job per 1 ~ 3 sec { Console.WriteLine(); Console.WriteLine($"Step 3: random add job per 1 ~ 3 sec"); int count = 0; Random rnd = new Random(); DateTime current = since; while (current < until) { current = current + TimeSpan.FromMilliseconds(1000 + rnd.Next(2000)); count++; Console.Write("."); repo.CreateJob(current); } total += count; Console.WriteLine(); Console.WriteLine($"- complete({count})."); } // step 4, realtime: add a job scheduled after 10 sec, and random waiting 1 ~ 3 sec. { Console.WriteLine(); Console.WriteLine($"Step 4: realtime: add a job scheduled after 10 sec, and random waiting 1 ~ 3 sec."); int count = 0; Random rnd = new Random(); while (DateTime.Now.AddSeconds(10) < until) { Task.Delay(1000 + rnd.Next(2000)).Wait(); count++; Console.Write("."); repo.CreateJob(DateTime.Now + JobSettings.MinPrepareTime + TimeSpan.FromMilliseconds(100)); } total += count; Console.WriteLine(); Console.WriteLine($"- complete({count})."); } Console.WriteLine(); Console.WriteLine($"Database initialization complete."); Console.WriteLine($"- total jobs: {total}"); Console.WriteLine($"- now: {DateTime.Now}"); Console.WriteLine($"- since: {since}"); Console.WriteLine($"- until: {until}"); // step 5, wait 30 sec, show statistic Task.Delay(JobSettings.MaxDelayTime + JobSettings.MinPrepareTime).Wait(); var metrics = repo.GetStatstics(); Console.WriteLine(); Console.WriteLine($"Jobs Scheduling Metrics:"); Console.WriteLine(); Console.WriteLine("--(action count)----------------------------------------------"); Console.WriteLine($"- CREATE: {metrics.count_action_create}"); Console.WriteLine($"- ACQUIRE_SUCCESS: {metrics.count_action_acquire_success}"); Console.WriteLine($"- ACQUIRE_FAILURE: {metrics.count_action_acquire_failure}"); Console.WriteLine($"- COMPLETE: {metrics.count_action_complete}"); Console.WriteLine($"- QUERYJOB: {metrics.count_action_queryjob}"); Console.WriteLine($"- QUERYLIST: {metrics.count_action_querylist}"); Console.WriteLine(); Console.WriteLine("--(state count)----------------------------------------------"); Console.WriteLine($"- COUNT(CREATE): {metrics.count_state_create}"); Console.WriteLine($"- COUNT(LOCK): {metrics.count_state_lock}"); Console.WriteLine($"- COUNT(COMPLETE): {metrics.count_action_complete}"); Console.WriteLine(); Console.WriteLine("--(statistics)----------------------------------------------"); Console.WriteLine($"- DELAY(Average): {metrics.stat_average_delay}"); Console.WriteLine($"- DELAY(Stdev): {metrics.stat_stdev_delay}"); Console.WriteLine(); Console.WriteLine("--(test result)----------------------------------------------"); Console.WriteLine($"- Complete Job: {metrics.count_action_complete == metrics.count_action_create}, {metrics.count_action_complete} / {metrics.count_action_create}"); Console.WriteLine($"- Delay Too Long: {metrics.stat_delay_exceed_count}"); Console.WriteLine($"- Fail Job: {metrics.count_state_lock == 0}, {metrics.count_state_lock}"); Console.WriteLine(); Console.WriteLine("--(benchmark score)----------------------------------------------"); Console.WriteLine($"- Exec Cost Score: {metrics.count_action_querylist * 100.0 + metrics.count_action_acquire_failure * 10.0 + metrics.count_action_queryjob * 1.0:#.##} (querylist x 100 + acquire-failure x 10 + queryjob x 1)"); Console.WriteLine($"- Efficient Score: {metrics.stat_average_delay + metrics.stat_stdev_delay:#.##} (average + stdev)"); } }