// Why attributes above are set. // "DisableConcurrentExecutionAttribute" should have short timeout, because this attribute implemented by following manner: newly started job falls into "processing" state immediately. // Then it tries to receive job lock during timeout. If the lock received, the job starts payload. // When the job is awaiting desired timeout for lock release, it stucks in "processing" anyway. (Therefore, you should not to set long timeouts (like 24*60*60), this will cause a lot of stucked jobs and performance degradation.) // Then, if timeout is over and the lock NOT acquired, the job falls into "scheduled" state (this is default fail-retry scenario). // We can change this default behavior using "AutomaticRetryAttribute". This allows to manage retries and reject jobs in case of retries exhaust. // In our case, the job, awaiting for previous the same job more than 10 seconds, will fall into "deleted" state with no retries. public async Task ProcessAll(IJobCancellationToken cancellationToken) { var thumbnailTasks = await _taskSearchService.SearchAsync(new ThumbnailTaskSearchCriteria() { Take = 0, Skip = 0 }); var tasks = await _taskSearchService.SearchAsync(new ThumbnailTaskSearchCriteria() { Take = thumbnailTasks.TotalCount, Skip = 0 }); Action <ThumbnailTaskProgress> progressCallback = x => { }; await PerformGeneration(tasks.Results, false, progressCallback, cancellationToken); }
public async Task DoExportAsync(Stream outStream, Action <ExportImportProgressInfo> progressCallback, ICancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); var progressInfo = new ExportImportProgressInfo { Description = "loading data..." }; progressCallback(progressInfo); using (var sw = new StreamWriter(outStream, Encoding.UTF8)) { using (var writer = new JsonTextWriter(sw)) { await writer.WriteStartObjectAsync(); progressInfo.Description = "Options are started to export"; progressCallback(progressInfo); await writer.WritePropertyNameAsync("Options"); await writer.SerializeJsonArrayWithPagingAsync(_jsonSerializer, _batchSize, async (skip, take) => { var searchCriteria = AbstractTypeFactory <ThumbnailOptionSearchCriteria> .TryCreateInstance(); searchCriteria.Take = take; searchCriteria.Skip = skip; var searchResult = await _optionSearchService.SearchAsync(searchCriteria); return((GenericSearchResult <ThumbnailOption>)searchResult); }, (processedCount, totalCount) => { progressInfo.Description = $"{processedCount} of {totalCount} Options have been exported"; progressCallback(progressInfo); }, cancellationToken); progressInfo.Description = "Tasks are started to export"; progressCallback(progressInfo); await writer.WritePropertyNameAsync("Tasks"); await writer.SerializeJsonArrayWithPagingAsync(_jsonSerializer, _batchSize, async (skip, take) => { var searchCriteria = AbstractTypeFactory <ThumbnailTaskSearchCriteria> .TryCreateInstance(); searchCriteria.Take = take; searchCriteria.Skip = skip; var searchResult = await _taskSearchService.SearchAsync(searchCriteria); return((GenericSearchResult <ThumbnailTask>)searchResult); }, (processedCount, totalCount) => { progressInfo.Description = $"{processedCount} of {totalCount} Tasks have been exported"; progressCallback(progressInfo); }, cancellationToken); await writer.WriteEndObjectAsync(); await writer.FlushAsync(); } } }
public async Task ProcessAll(IJobCancellationToken cancellationToken) { var thumbnailTasks = await _taskSearchService.SearchAsync(new ThumbnailTaskSearchCriteria() { Take = 0, Skip = 0 }); var tasks = await _taskSearchService.SearchAsync(new ThumbnailTaskSearchCriteria() { Take = thumbnailTasks.TotalCount, Skip = 0 }); Action <ThumbnailTaskProgress> progressCallback = x => { }; var cancellationTokenWrapper = new JobCancellationTokenWrapper(cancellationToken); await _thumbnailProcessor.ProcessTasksAsync(tasks.Results, false, progressCallback, cancellationTokenWrapper); //update tasks in case of successful generation foreach (var task in tasks.Results) { task.LastRun = DateTime.UtcNow; } await _taskService.SaveChangesAsync(tasks.Results); }
private async Task ExportTasksAsync(JsonTextWriter writer, JsonSerializer serializer, ExportImportProgressInfo progressInfo, Action <ExportImportProgressInfo> progressCallback, ICancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); progressInfo.Description = "Exporting tasks..."; progressCallback(progressInfo); var thumbnailTask = await _taskSearchService.SearchAsync(new ThumbnailTaskSearchCriteria() { Take = 0, Skip = 0 }); var totalCount = thumbnailTask.TotalCount; writer.WritePropertyName("TakskTotalCount"); writer.WriteValue(totalCount); writer.WritePropertyName("Tasks"); writer.WriteStartArray(); for (int i = 0; i < totalCount; i += _batchSize) { var tasks = await _taskSearchService.SearchAsync(new ThumbnailTaskSearchCriteria { Take = _batchSize, Skip = i }); foreach (var task in tasks.Results) { serializer.Serialize(writer, task); } writer.Flush(); progressInfo.Description = $"{Math.Min(totalCount, i + _batchSize)} of {totalCount} tasks exported"; progressCallback(progressInfo); } writer.WriteEndArray(); }
public async Task <IActionResult> Search([FromBody] ThumbnailTaskSearchCriteria criteria) { var result = await _thumbnailTaskSearchService.SearchAsync(criteria); return(Ok(result)); }