public ActionResult AssignJob(JobRequestModel model) { var id = System.Web.HttpContext.Current.User.Identity.GetUserId(); JobService.AcceptJobProposal(new CustomJobHistory { JobId = model.JobModel.Id, PurposalText = model.JobModel.PurposalText, ContractorId = model.JobModel.ContractorId }, id); var jobs = JobService.GetJobsProposals(id); model.PageObj.CurrentPage--; var newPage = CalculateJobsWithPaging(ref jobs, model.PageObj); var modelnew = new JobPartialPageModel { JobList = jobs, Page = new PaggingClass { TotalPages = newPage.TotalPages, TotalItems = newPage.TotalItems, CurrentPage = model.PageObj.CurrentPage + 1, ItemsPerPage = model.PageObj.ItemsPerPage, SortBy = model.PageObj.SortBy, SortOrder = model.PageObj.SortOrder, CategoryId = model.PageObj.CategoryId, SearchTerm = model.PageObj.SearchTerm } }; return(PartialView("~/Views/Job/JobProposalsPartials.cshtml", modelnew)); }
public ActionResult SuspendJobByAdmin(JobRequestModel model) { var id = System.Web.HttpContext.Current.User.Identity.GetUserId(); JobService.SuspendResumeJob(model.JobModel, id); var jobs = JobService.GetAllJobs(true); model.PageObj.CurrentPage--; var newPage = CalculateJobsWithPaging(ref jobs, model.PageObj); var modelnew = new JobPartialPageModel { JobList = jobs, Page = new PaggingClass { TotalPages = newPage.TotalPages, TotalItems = newPage.TotalItems, CurrentPage = model.PageObj.CurrentPage + 1, ItemsPerPage = model.PageObj.ItemsPerPage, SortBy = model.PageObj.SortBy, SortOrder = model.PageObj.SortOrder, CategoryId = model.PageObj.CategoryId, SearchTerm = model.PageObj.SearchTerm } }; return(PartialView("~/Views/Job/ListViewJobsPartial.cshtml", modelnew)); }
/// <summary> /// Generates test data /// </summary> /// <param name="sequenceNumber">sequence number</param> /// <param name="uniqueness">unique part of the names</param> /// <returns>Generated JobRequestModel</returns> private static JobRequestModel GenerateJobRequestModel(int sequenceNumber, string uniqueness) { var jobId = $"jobId-{sequenceNumber}-{uniqueness}"; var jobName = $"jobName-{sequenceNumber}-{uniqueness}"; var outputAssetName = $"output-{sequenceNumber}-{uniqueness}"; // Add job input for this test var input = new JobInputHttp( baseUri: "<Enter URL>", files: new List <string> { "<Enter Filename>" }, label: "input1" ); var request = new JobRequestModel { Id = jobId, JobName = jobName, OutputAssetName = outputAssetName, TransformName = transformName, JobInputs = new JobInputs { Inputs = new List <JobInput> { input } } }; return(request); }
/// <inheritdoc/> public async Task <JobProcessingInstructionModel> GetAvailableJobAsync(string workerId, JobRequestModel jobRequest, CancellationToken ct) { if (string.IsNullOrEmpty(workerId)) { throw new ArgumentNullException(nameof(workerId)); } while (true) { var uri = _config?.Config?.JobOrchestratorUrl?.TrimEnd('/'); if (uri == null) { throw new InvalidConfigurationException("Job orchestrator not configured"); } var request = _httpClient.NewRequest($"{uri}/v2/workers/{workerId}"); request.Headers.Authorization = new AuthenticationHeaderValue("Basic", _tokenProvider.IdentityToken.ToAuthorizationValue()); _serializer.SerializeToRequest(request, jobRequest.ToApiModel()); var response = await _httpClient.PostAsync(request, ct) .ConfigureAwait(false); try { response.Validate(); var result = _serializer.DeserializeResponse <JobProcessingInstructionApiModel>( response); return(result.ToServiceModel()); } catch (UnauthorizedAccessException) { await _tokenProvider.ForceUpdate(); } } }
/// <summary> /// Stores a new job request /// </summary> /// <param name="jobRequestModel">Job request to store</param> /// <param name="logger">Logger to log data</param> /// <returns></returns> public async Task <JobRequestModel> CreateAsync(JobRequestModel jobRequestModel, ILogger logger) { var message = JsonConvert.SerializeObject(jobRequestModel, this.settings); // Encode message to Base64 before sending to the queue await this.queue.SendMessageAsync(QueueServiceHelper.EncodeToBase64(message)).ConfigureAwait(false); logger.LogInformation($"JobRequestStorageService::CreateAsync successfully added request to the queue: jobRequestModel={LogHelper.FormatObjectForLog(jobRequestModel)}"); return(jobRequestModel); }
/// <inheritdoc/> public async Task <JobProcessingInstructionModel> GetAvailableJobAsync(string workerId, JobRequestModel request, CancellationToken ct) { var query = new JobInfoQueryModel { Status = JobStatus.Active // Only query active jobs }; string continuationToken = null; do { var jobList = await _jobRepository.QueryAsync(query, continuationToken, null, ct); if (jobList?.Jobs == null) { break; } System.Diagnostics.Debug .Assert(!jobList.Jobs.Any(j => j.LifetimeData.Status != JobStatus.Active)); // Filter demands var demandFilteredJobs = jobList.Jobs .Where(j => _demandMatcher.MatchCapabilitiesAndDemands(j.Demands, request?.Capabilities)) .ToArray(); foreach (var job in demandFilteredJobs) { // Test the listed job first before hitting the database var jobProcessInstruction = CalculateInstructions(job, workerId); if (jobProcessInstruction != null) { try { await _jobRepository.UpdateAsync(job.Id, existingJob => { // Try again on the current value in the database jobProcessInstruction = CalculateInstructions(existingJob, workerId); if (jobProcessInstruction != null) { _jobEventHandler.OnJobAssignmentAsync(_jobService, jobProcessInstruction.Job, workerId).Wait(); } return(Task.FromResult(jobProcessInstruction != null)); }, ct); return(jobProcessInstruction); } catch (ResourceNotFoundException) { continue; // Job deleted while updating, continue to next job } } } continuationToken = jobList.ContinuationToken; }while (continuationToken != null); return(null); }
public JobRequestModel GetAllJobRequests() { JobRequestModel model = new JobRequestModel(); var list = db.JobRequests.Include("User").Include("Service").ToList(); if (list.Count > 0) { model.jobsList = list.Select(x => x.CreateFrom()); } model.serviceList = db.Services.Select(x => new { x.ServiceName }).ToList(); return(model); }
public async Task <ActionResult> UsersByOffer(int id) { List <BigViewModel> list = new List <BigViewModel>(); List <Folder> folders = new List <Folder>(); List <JobRequest> jobs = new List <JobRequest>(); folders = serviceFolder.GetAll().Where(a => a.etape == 3).ToList(); foreach (var item in folders) { jobs = serviceJob.GetAll().Where(a => a.offerId == id && a.jobRequestId == item.jobRequestId).ToList(); } foreach (var item in jobs) { User user = await UserManager.FindByIdAsync(item.userId); UserModel userModel = new UserModel(); userModel.firstname = user.firstname; userModel.lastname = user.lastname; userModel.Email = user.Email; userModel.userId = user.Id; JobRequestModel jobModel = new JobRequestModel(); jobModel.dateApply = item.dateApply; jobModel.speciality = item.speciality; jobModel.userId = item.userId; jobModel.jobRequestId = item.jobRequestId; jobModel.state = item.state; // Resource user1 = serviceResouce.getResource(user.UserName); BigViewModel bg = new BigViewModel(); bg.resourceViewModel = userModel; bg.jobRequestModel = jobModel; list.Add(bg); } return(View(list)); }
public ActionResult jobOffer(int id) { List <JobRequestModel> list = new List <JobRequestModel>(); foreach (var item in serviceJob.GetAll().Where(a => a.offerId == id)) { JobRequestModel fv = new JobRequestModel(); fv.userId = item.userId; fv.state = item.state; fv.speciality = item.speciality; fv.dateApply = item.dateApply; fv.jobRequestId = item.jobRequestId; list.Add(fv); } return(View(list)); }
// GET: JobRequest public ActionResult Index() { List <JobRequestModel> list = new List <JobRequestModel>(); foreach (var item in serviceJob.GetAll()) { JobRequestModel fv = new JobRequestModel(); fv.userId = item.userId; fv.state = item.state; fv.speciality = item.speciality; fv.dateApply = item.dateApply; fv.jobRequestId = item.jobRequestId; list.Add(fv); } ViewBag.Message = message; return(View(list)); }
public ActionResult Indexx(string searchString) { List <JobRequestModel> list = new List <JobRequestModel>(); foreach (var item in serviceJob.GetAll()) { JobRequestModel fv = new JobRequestModel(); fv.userId = item.userId; fv.state = item.state; fv.speciality = item.speciality; fv.dateApply = item.dateApply; fv.jobRequestId = item.jobRequestId; list.Add(fv); } if (!String.IsNullOrEmpty(searchString)) { list = list.Where(a => a.speciality.Contains(searchString)).ToList(); } return(View(list)); }
public async Task <IActionResult> InProgress(JobRequestModel jobRequest) { response = new ResponseModel(); try { long userId = base.UserId; Job job = await _unitOfWork.GetRepository <Job>().Where(x => x.UserId == userId && x.JobId == jobRequest.JobId).SingleOrDefaultAsync(); if (job == null) { response.Message = Constants.Invalid_JobId; return(BadRequest(response)); } job.Status = JobStatus.InProgress.ToString(); job.SyncType = jobRequest.IsManualSync ? "Manual" : "Automatic"; if (!string.IsNullOrWhiteSpace(jobRequest.Reason)) { job.Status = JobStatus.Stopped.ToString(); job.Reason = jobRequest.Reason; } List <JobDetail> jobDetails = new List <JobDetail>(); jobDetails.Add(await GetJobDetail(jobRequest.Reads, job.Id, userId, job.Status)); jobDetails.Add(await GetJobDetail(jobRequest.Bills, job.Id, userId, job.Status)); jobDetails.AddRange(await GetJobDetail(jobRequest.Images, job.Id, userId, job.Status)); _unitOfWork.GetRepository <JobDetail>().Insert(jobDetails); int count = _unitOfWork.Commit(); response.Status = count > 0; } catch (Exception ex) { response.Status = false; response.Message = Constants.Error; return(StatusCode(500, response)); } return(Ok(response)); }
public Jobs SaveNewJob(JobRequestModel data) { var lastJob = context.Jobs.Where(a => a.JobName.Contains(data.Prefix) && DbFunctions.TruncateTime(a.CreatedDate) == DbFunctions.TruncateTime(DateTime.Now))?.OrderByDescending(a => a.CreatedDate).FirstOrDefault(); int lastRunningNo = 1; if (lastJob != null) { lastRunningNo = Convert.ToInt32(lastJob.JobName.Substring(lastJob.JobName.Length - 3)); lastRunningNo++; } var job = new Models.Jobs { CreatedById = data.RequesterUserId, CreatedDate = DateTime.Now, WarehouseType = data.Prefix == "WHD" ? 1 : 2, Id = 0, JobName = data.Prefix + "-" + DateTime.Now.ToString("yyyyMMdd") + "-" + lastRunningNo.ToString().PadLeft(2, '0') }; context.Jobs.Add(job); context.SaveChanges(); return(job); }
public ActionResult ChnageJobApproval(JobRequestModel model) { JobService.ChangeJobApproval(model.JobModel); var job = JobService.GetJobById(model.JobModel.Id); KaamShaam.Services.EmailService.SendEmail(job.JobPostedByObj.Email, "Job Status Updated - KamSham.Pk", job.JobPostedByObj.FullName + " we noticed that admin has updated one of your job. Please review your Jobs in manage job section."); KaamShaam.Services.EmailService.SendSms(job.JobPostedByObj.Mobile, "One of your job status has been changed. Please visit https://kamsham.pk"); var jobs = JobService.GetAllJobs(false); if (jobs != null && jobs.Count > 0) { jobs = jobs.Where(j => string.IsNullOrEmpty(j.Feedback)).ToList(); } model.PageObj.CurrentPage--; var newPage = CalculateJobsWithPaging(ref jobs, model.PageObj); var modelnew = new JobPartialPageModel { JobList = jobs, Page = new PaggingClass { TotalPages = newPage.TotalPages, TotalItems = newPage.TotalItems, CurrentPage = model.PageObj.CurrentPage + 1, ItemsPerPage = model.PageObj.ItemsPerPage, SortBy = model.PageObj.SortBy, SortOrder = model.PageObj.SortOrder, CategoryId = model.PageObj.CategoryId, SearchTerm = model.PageObj.SearchTerm } }; return(PartialView("~/Views/Job/ListViewJobsPartial.cshtml", modelnew)); }
public Jobs Post([FromBody] JobRequestModel data) { return(_repo.SaveNewJob(data)); }
/// <summary> /// Gets the next available job - this will always return the job representation of the legacy publishednodes.json /// along with legacy command line arguments. /// </summary> /// <param name="workerId"></param> /// <param name="request"></param> /// <param name="ct"></param> /// <returns></returns> public Task <JobProcessingInstructionModel> GetAvailableJobAsync(string workerId, JobRequestModel request, CancellationToken ct = default) { _updated = false; return(Task.FromResult(_jobProcessingInstructionModel)); }
public IHttpActionResult AddJobRequest() { JobRequestModel model = new JobRequestModel(); var httpRequest = HttpContext.Current.Request; if (httpRequest.Files.Count > 0) { model.ReferenceImages = new List <string>(); HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.Created); IList <string> AllowedFileExtensions = new List <string> { ".jpg", ".png", ".jpeg", ".JPG", ".PNG", ".JPEG" }; var date = DateTime.Now.ToString("yyyy-dd-M--HH-mm-ss").Replace("-", "_"); var count = httpRequest.Files.Count; if (count > 0) { for (int i = 0; i < httpRequest.Files.Count; i++) { if (httpRequest.Files[i] != null) { var postedImg = httpRequest.Files[i]; var ext = postedImg.FileName.Substring(postedImg.FileName.LastIndexOf('.')); var path = "~/Images/JobRequest/"; var imagePath = Path.GetFileNameWithoutExtension(postedImg.FileName) + "_" + date + ext.ToLower(); var fileName = path + imagePath; if (!AllowedFileExtensions.Contains(ext)) { return(this.Ok(new { status = false, message = Resource.file_extension_invalid })); } if (!Directory.Exists(HttpContext.Current.Server.MapPath(path))) { Directory.CreateDirectory(HttpContext.Current.Server.MapPath(path)); } postedImg.SaveAs(HttpContext.Current.Server.MapPath(fileName)); model.ReferenceImages.Add(imagePath); } } } } model.UserId = Convert.ToInt64(httpRequest.Form.Get("UserId")); if (httpRequest.Form.Get("CheckList") != null) { var checklist = httpRequest.Form.Get("CheckList").ToString(); model.CheckList = Newtonsoft.Json.JsonConvert.DeserializeObject <List <string> >(checklist); } model.PropertyId = Convert.ToInt64(httpRequest.Form.Get("PropertyId")); model.CategoryId = Convert.ToInt64(httpRequest.Form.Get("CategoryId")); if (httpRequest.Form.Get("JobStartDatetime") != null) { model.JobStartDatetime = Convert.ToDateTime(httpRequest.Form.Get("JobStartDatetime")); } if (httpRequest.Form.Get("JobEndDatetime") != null) { model.JobEndDatetime = Convert.ToDateTime(httpRequest.Form.Get("JobEndDatetime")); } if (httpRequest.Form.Get("Price") != null) { model.Price = Convert.ToDecimal(httpRequest.Form.Get("Price")); } if (httpRequest.Form.Get("ClientPrice") != null) { model.ClientPrice = Convert.ToDecimal(httpRequest.Form.Get("ClientPrice")); } if (httpRequest.Form.Get("HasPrice") != null) { model.HasPrice = Convert.ToBoolean(httpRequest.Form.Get("HasPrice")); } model.Description = httpRequest.Form.Get("Description"); model.SubCategoryId = Convert.ToInt64(httpRequest.Form.Get("SubCategoryId")); var subsubCat = httpRequest.Form.Get("SubSubCategories"); List <long> lst = new List <long>(); if (!string.IsNullOrEmpty(subsubCat)) { var subsubCatArr = subsubCat.Split(','); for (int i = 0; i < subsubCatArr.Length; i++) { var id = Convert.ToInt64(subsubCatArr[i]); lst.Add(id); } } model.SubSubCategories = lst; var status = propertyService.AddJobRequest(model); return(this.Ok(new { status = status, message = propertyService.message })); }
/// <summary> /// Gets the next available job - this will always return the job representation of the legacy publishednodes.json /// along with legacy command line arguments. /// </summary> /// <param name="workerId"></param> /// <param name="request"></param> /// <param name="ct"></param> /// <returns></returns> public Task <JobProcessingInstructionModel> GetAvailableJobAsync(string workerId, JobRequestModel request, CancellationToken ct = default) { if (_assignedJobs.TryGetValue(workerId, out var job)) { return(Task.FromResult(job)); } if (_availableJobs.Count > 0 && _availableJobs.TryDequeue(out job)) { _assignedJobs.AddOrUpdate(workerId, job); if (_availableJobs.Count == 0) { _updated = false; } } else { _updated = false; } return(Task.FromResult(job)); }
/// <summary> /// Gets the next available job - this will always return the job representation of the legacy publishednodes.json /// along with legacy command line arguments. /// </summary> /// <param name="workerId"></param> /// <param name="request"></param> /// <param name="ct"></param> /// <returns></returns> public Task <JobProcessingInstructionModel> GetAvailableJobAsync(string workerId, JobRequestModel request, CancellationToken ct = default) { _lock.Wait(ct); try { if (_assignedJobs.TryGetValue(workerId, out var job)) { return(Task.FromResult(job)); } if (_availableJobs.Count > 0 && _availableJobs.TryDequeue(out job)) { _assignedJobs.AddOrUpdate(workerId, job); } return(Task.FromResult(job)); } catch (OperationCanceledException) { _logger.Information("Operation GetAvailableJobAsync was canceled"); throw; } catch (Exception e) { _logger.Error(e, "Error while looking for available jobs, for {Worker}", workerId); throw; } finally { _lock.Release(); } }
public JsonResult AddJobRequest(FormCollection formCollection) { JobRequestModel model = new JobRequestModel(); model.CategoryId = Convert.ToInt32(formCollection["CategoryId"]); model.PropertyId = Convert.ToInt32(formCollection["PropertyId"]); if (formCollection["JobStartDatetime"] != null && formCollection["JobStartTime"] != null) { var getDate = DateTime.ParseExact(formCollection["JobStartDatetime"], "MM/dd/yyyy", System.Globalization.CultureInfo.InvariantCulture); //var getDate = Convert.ToDateTime(formCollection["JobStartDatetime"]); TimeSpan time; if (TimeSpan.TryParse(formCollection["JobStartTime"], out time)) { string startDate = (getDate + time).ToString("yyyy-MM-dd HH:mm:ss"); model.JobStartDatetime = Convert.ToDateTime(startDate); } } if (formCollection["Price"] != "null" || formCollection["ClientPrice"] != "null") { model.HasPrice = true; } else { model.HasPrice = false; } if (formCollection["JobEndDatetime"] != null && formCollection["JobEndTime"] != null) { var getDate = DateTime.ParseExact(formCollection["JobEndDatetime"], "MM/dd/yyyy", System.Globalization.CultureInfo.InvariantCulture); //var getDate = Convert.ToDateTime(formCollection["JobEndDatetime"]); TimeSpan time; if (TimeSpan.TryParse(formCollection["JobEndTime"], out time)) { string endDate = (getDate + time).ToString("yyyy-MM-dd HH:mm:ss"); model.JobEndDatetime = Convert.ToDateTime(endDate); } } if (formCollection["CheckList"] != null) { var checklist = formCollection["CheckList"].ToString(); model.CheckList = Newtonsoft.Json.JsonConvert.DeserializeObject <List <string> >(checklist); } model.Description = formCollection["Description"]; model.UserId = Convert.ToInt64(Session["UserId"]); if (formCollection["SubCategoryId"] != "undefined") { model.SubCategoryId = Convert.ToInt64(formCollection["SubCategoryId"]); } if (formCollection["Price"] != "null") { model.Price = Convert.ToDecimal(formCollection["Price"]); } if (formCollection["ClientPrice"] != "null") { model.ClientPrice = Convert.ToDecimal(formCollection["ClientPrice"]); } var json = formCollection["Attachments"].ToString(); List <string> getAttachments = Newtonsoft.Json.JsonConvert.DeserializeObject <List <string> >(json); model.ReferenceImages = new List <string>(); var date = DateTime.Now.ToString("yyyy_MM_dd_HH_mm_ss").Replace("-", "_"); if (getAttachments.Count > 0) { var count = getAttachments.Count(); if (count > 0) { for (int i = 0; i < getAttachments.Count(); i++) { string imageName = "JobRequest" + Guid.NewGuid() + date + ".jpg"; string[] splitAttachment = getAttachments[i].Split(','); Common.SaveImage(splitAttachment[1], imageName); model.ReferenceImages.Add(imageName); } } } if (formCollection["SubSubCategories"] != null) { var subsubCatArr = formCollection["SubSubCategories"].ToString(); model.SubSubCategories = Newtonsoft.Json.JsonConvert.DeserializeObject <List <long> >(subsubCatArr); } var status = propertyService.AddJobRequest(model); wsBase obj = new wsBase() { status = status, message = propertyService.message }; return(Json(obj, JsonRequestBehavior.AllowGet)); }
/// <summary> /// Gets the next available job - this will always return the job representation of the legacy publishednodes.json /// along with legacy command line arguments. /// </summary> /// <param name="workerId"></param> /// <param name="request"></param> /// <param name="ct"></param> /// <returns></returns> public Task <JobProcessingInstructionModel> GetAvailableJobAsync(string workerId, JobRequestModel request, CancellationToken ct = default) { if (_assignedJobs.TryGetValue(workerId, out var job)) { return(Task.FromResult(job)); } if (_availableJobs.Count > 0 && (job = _availableJobs.Dequeue()) != null) { _assignedJobs[workerId] = job; } else { _updated = false; } return(Task.FromResult(job)); }
/// <summary> /// Submits job to Azure Media Services. /// </summary> /// <param name="jobRequestModel">Job to submit.</param> /// <param name="logger">Logger to log data</param> /// <returns>Submitted job</returns> public async Task <Job> SubmitJobAsync(JobRequestModel jobRequestModel, ILogger logger) { logger.LogInformation($"JobSchedulingService::SubmitJobAsync started: jobRequestModel={LogHelper.FormatObjectForLog(jobRequestModel)}"); // Get next available Azure Media Services instance var selectedInstanceName = await this.mediaServiceInstanceHealthService.GetNextAvailableInstanceAsync(logger).ConfigureAwait(false); logger.LogInformation($"JobSchedulingService::SubmitJobAsync selected healthy instance: MediaServiceAccountName={selectedInstanceName} jobRequestModel={LogHelper.FormatObjectForLog(jobRequestModel)}"); // load configuration for specific instance var clientConfiguration = this.configService.MediaServiceInstanceConfiguration[selectedInstanceName]; // get client var clientInstance = this.mediaServiceInstanceFactory.GetMediaServiceInstance(selectedInstanceName, logger); // In order to submit a new job, output asset has to be created first var asset = await clientInstance.Assets.CreateOrUpdateAsync( clientConfiguration.ResourceGroup, clientConfiguration.AccountName, jobRequestModel.OutputAssetName, new Asset()).ConfigureAwait(false); JobOutput[] jobOutputs = { new JobOutputAsset(jobRequestModel.OutputAssetName) }; // submit new job var job = await clientInstance.Jobs.CreateAsync( clientConfiguration.ResourceGroup, clientConfiguration.AccountName, jobRequestModel.TransformName, jobRequestModel.JobName, new Job { Input = jobRequestModel.JobInputs, Outputs = jobOutputs, }).ConfigureAwait(false); logger.LogInformation($"JobSchedulingService::SubmitJobAsync successfully created job: job={LogHelper.FormatObjectForLog(job)}"); // create job verification request var jobVerificationRequestModel = new JobVerificationRequestModel { Id = Guid.NewGuid().ToString(), JobId = job.Id, OriginalJobRequestModel = jobRequestModel, MediaServiceAccountName = selectedInstanceName, JobOutputAssetName = jobRequestModel.OutputAssetName, JobName = job.Name, RetryCount = 0 // initial submission, only certain number of retries are performed before skipping job verification retry, // see job verification service for more details }; //create job output status record var statusInfo = MediaServicesHelper.GetJobOutputState(job, jobRequestModel.OutputAssetName); var jobOutputStatusModel = new JobOutputStatusModel { Id = Guid.NewGuid().ToString(), EventTime = statusInfo.Item2, JobOutputState = statusInfo.Item1, JobName = job.Name, MediaServiceAccountName = selectedInstanceName, JobOutputAssetName = jobRequestModel.OutputAssetName, TransformName = jobRequestModel.TransformName }; // in order to round robin among all healthy services, health service needs to know which instance has been used last // data is persisted in memory only for current process this.mediaServiceInstanceHealthService.RecordInstanceUsage(selectedInstanceName, logger); var retryCount = 3; var retryTimeOut = 1000; // Job is submitted at this point, failing to do any calls after this point would result in reprocessing this job request and submitting duplicate one. // It is OK to retry and ignore exception at the end. In current implementation based on Azure storage, it is very unlikely to fail in any of the below calls. do { try { // persist initial job output status await this.jobOutputStatusStorageService.CreateOrUpdateAsync(jobOutputStatusModel, logger).ConfigureAwait(false); // persist job verification request. It is used to trigger logic to verify that job was completed and not stuck sometime in future. var jobVerificationResult = await this.jobVerificationRequestStorageService.CreateAsync(jobVerificationRequestModel, this.verificationDelay, logger).ConfigureAwait(false); logger.LogInformation($"JobSchedulingService::SubmitJobAsync successfully submitted jobVerificationModel: result={LogHelper.FormatObjectForLog(jobVerificationResult)}"); // no exception happened, let's break. break; } #pragma warning disable CA1031 // Do not catch general exception types catch (Exception e) #pragma warning restore CA1031 // Do not catch general exception types { logger.LogError($"JobSchedulingService::SubmitJobAsync got exception calling jobVerificationRequestStorageService.CreateAsync: retryCount={retryCount} message={e.Message} job={LogHelper.FormatObjectForLog(job)}"); retryCount--; await Task.Delay(retryTimeOut).ConfigureAwait(false); } }while (retryCount > 0); logger.LogInformation($"JobSchedulingService::SubmitJobAsync completed: job={LogHelper.FormatObjectForLog(job)}"); return(job); }