public async Task StartJob() { Job currentJob; if (PendingJobs.NotEmpty() && !Cancelled) { lock (PendingJobs) currentJob = PendingJobs.Dequeue(); lock (ScheduledJobs) ScheduledJobs.Add(currentJob); await jobSemaphore.WaitAsync(); if (ScheduledJobs.NotEmpty() && !Cancelled) { lock (ScheduledJobs) ScheduledJobs.Remove(currentJob); lock (ExecutingJobs) ExecutingJobs.Add(currentJob); await currentJob.Execute(ImageMaker); if (!Cancelled) { lock (ExecutingJobs) ExecutingJobs.Remove(currentJob); } jobSemaphore.Release(); } } }
/// <summary> /// Attempts to process executing <see cref="GeolocationBatchUpdateJob"/>s' /// <see cref="IPGeolocationUpdateRequest"/>s based on the available <see cref="JobItemBatchSize"/> /// </summary> private void TryProcessExecutingJobItems() { if (!ExecutingJobs.Any()) { return; } foreach (var bufferItem in Buffer) { // Retrieve buffered items by item batch size specification var itemsToProcess = bufferItem.Value.Take(JobItemBatchSize).ToList(); // Retrieve matching job var job = ExecutingJobs.FirstOrDefault(x => x.Id == bufferItem.Key); if (job == null) { continue; } // Invoke delegate to process the series of job items job.Processor.Invoke(itemsToProcess); // Remove processed job items from the buffer for the current job itemsToProcess.ForEach(x => Buffer.FirstOrDefault(i => i.Key == bufferItem.Key) .Value.Remove(x)); job.RemainingItemCount -= itemsToProcess.Count; if (!bufferItem.Value.Any()) { MoveExecutingToCompleted(job); } } }
/// <summary> /// Moves the provided <see cref="GeolocationBatchUpdateJob"/> from executing to completed /// </summary> /// <param name="job">The <see cref="GeolocationBatchUpdateJob"/> to move</param> private void MoveExecutingToCompleted(GeolocationBatchUpdateJob job) { ExecutingJobs.Remove(job); CompletedJobs.Add(job); Buffer.Remove(job.Id); }
/// <summary> /// Moves the provided <see cref="GeolocationBatchUpdateJob"/> from pending to executing /// </summary> /// <param name="job">The <see cref="GeolocationBatchUpdateJob"/> to move</param> private void MovePendingToExecuting(GeolocationBatchUpdateJob job) { PendingJobs.Remove(job); ExecutingJobs.Add(job); Buffer.Add(job.Id, job.Request as List <IPGeolocationUpdateRequest>); }