public async Task <string> SubmitJob(Common.Entities.Job newJob, string batchId = "") { var webApiCallUrl = string.Format(string.Concat(_baseUrl, _submitJobUrl), batchId); var jobPostResp = await _httpClient.PostAsync <Job> ( webApiCallUrl, newJob, new JsonMediaTypeFormatter() ); jobPostResp.EnsureSuccessStatusCode(); var jobId = await jobPostResp.Content.ReadAsAsync <string>(); return(jobId); }
public Common.JobProcessResult DoWork(Common.Entities.Job job, string jobPackagePath, string jobWorkingPath, Action <string> progressCallback) { // // Initialize the job // InitalizeBasics(jobPackagePath, jobWorkingPath); // // Process the actual job // ProcessJob(job, _localTemporaryPath); // // Return the result // return(new JobProcessResult() { Output = "succeeded procesing image " + job.Parameters, Status = Common.Entities.JobStatus.Finished }); }
/// <summary> /// Calls the Geres job Worker Process executable and passes the job entity to it /// </summary> public Common.JobProcessResult DoWork(Common.Entities.Job job, string jobPackagePath, string jobWorkingPath, Action <string> progressCallback) { var errorMessages = string.Empty; var logMessages = string.Empty; // // At the starting point, the job has not been cancelled // _hasBeenCancelled = false; // // Parameter validations // if (_executionContext == null) { throw new InvalidOperationException("Execution context for JobWorkerProcessImplementation is not set correctly!"); } // // Copy the worker process files to the job-directory // var workerProcPath = string.Empty; var roleRootPath = Environment.GetEnvironmentVariable("RoleRoot"); try { // Note: in the local emulator, RoleRoot did not have approot in it while in the cloud it did. if (roleRootPath[roleRootPath.Length - 1] != '\\') { roleRootPath += @"\"; } workerProcPath = Path.Combine(roleRootPath, "approot", "wp"); foreach (var fileToCopy in Directory.GetFiles(workerProcPath)) { File.Copy(fileToCopy, Path.Combine(jobPackagePath, Path.GetFileName(fileToCopy)), true); } } catch (Exception ex) { throw new Exception(string.Format("Unable to copy worker process files to job target directory. Parameters: " + "RoleRoot={0}, JobRootPath={1}, Exception Message={2}", roleRootPath, jobPackagePath, ex.Message), ex); } // // First of all write the job file to the filesystem (use XML since it does not require any further dependencies) // var jobFileName = Path.Combine(jobPackagePath, JobWorkerProcessConstants.JOB_XML_FILE); try { using (var jobStream = new FileStream(jobFileName, FileMode.Create)) { _jobXmlSerializer.Serialize(jobStream, job); } } catch (Exception ex) { throw new Exception(string.Format("Unable to serialize job file {0} for passing to job worker process due to exception: {1}!", job.JobId, ex.Message), ex); } // // Now call the executable with the username // try { // Compile the start info and make sure stdout and stderr are redirected // Note: we assume that we read from stdout, only, in our "private protocol" to reduce complexity of // potenital deadlocks as described here: http://msdn.microsoft.com/en-us/library/system.diagnostics.process.standardoutput(v=vs.110).aspx _geresWorkerProcessPath = Path.Combine(jobPackagePath, JobWorkerProcessConstants.JOB_WORKERPROC_EXENAME); var workerProcessStartInfo = new ProcessStartInfo() { FileName = _geresWorkerProcessPath, UseShellExecute = false, RedirectStandardOutput = true, RedirectStandardError = true, WorkingDirectory = jobWorkingPath, LoadUserProfile = false, CreateNoWindow = true }; // Set the user name and the password if the tenant manager is configured in a way to execute the process under different credentials if (_executionContext.ExecutionAsUserName != null && _executionContext.ExecutionAsUserPassword != null) { workerProcessStartInfo.UserName = _executionContext.ExecutionAsUserName; workerProcessStartInfo.Password = _executionContext.ExecutionAsUserPassword; } // Had to clear environment variables since they were pointing to the "calling users" home directory if (workerProcessStartInfo.EnvironmentVariables.ContainsKey("homepath")) { workerProcessStartInfo.EnvironmentVariables.Remove("homepath"); workerProcessStartInfo.EnvironmentVariables.Add("homepath", jobWorkingPath); } // Add environmentvariables for the job execution context (path information) for the worker process workerProcessStartInfo.EnvironmentVariables.Add(JobWorkerProcessConstants.JOB_ENVIRONMENT_EXEC_PATH, jobPackagePath); workerProcessStartInfo.EnvironmentVariables.Add(JobWorkerProcessConstants.JOB_ENVIRONMENT_WORK_PATH, jobWorkingPath); // // Now start the worker process executable // _currentWorkerProcess = Process.Start(workerProcessStartInfo); // // Create the asynchronous tasks to wait for the process, stderr, stdout // var processWaiter = Task.Run(() => _currentWorkerProcess.WaitForExit()); _stdOutTask = Task.Run(() => { var msg = string.Empty; do { msg = _currentWorkerProcess.StandardOutput.ReadLine(); ProcessConsoleMessage(progressCallback, msg, ref logMessages); } while (!_currentWorkerProcess.HasExited); do { msg = _currentWorkerProcess.StandardOutput.ReadLine(); ProcessConsoleMessage(progressCallback, msg, ref logMessages); } while (!string.IsNullOrEmpty(msg)); }); _stdErrTask = Task.Run(() => { errorMessages = _currentWorkerProcess.StandardError.ReadToEnd(); }); // // Wait until stdout and stderr have completly read and the process did exit // Task.WaitAll(processWaiter, _stdOutTask, _stdErrTask); // // Compose the job output results // var outputString = logMessages; if (!string.IsNullOrEmpty(errorMessages)) { outputString = string.Concat(outputString, Environment.NewLine, "--ERRORS--", Environment.NewLine, errorMessages); } // // Try get the job result from the exit code // Geres.Common.Entities.JobStatus statusFromExitCode = Common.Entities.JobStatus.Finished; try { statusFromExitCode = (Geres.Common.Entities.JobStatus)_currentWorkerProcess.ExitCode; } catch { statusFromExitCode = Common.Entities.JobStatus.Aborted; } // // If the job has been cancelled, the status should be cancelled // if (_hasBeenCancelled) { statusFromExitCode = Common.Entities.JobStatus.Cancelled; } // // Finally return the result // return(new Common.JobProcessResult() { Output = outputString, Status = statusFromExitCode }); } catch (Exception ex) { throw new Exception(string.Format("Failed calling the GERES job worker process due to the following reason: {0}!", ex.Message), ex); } }
public IJobImplementation Lookup(Common.Entities.Job job) { return(new JobWorkerProcessImplementation()); }
private void ProcessJob(Common.Entities.Job jobDetails, string localTempPath) { // // Temporary files used for processing by the legacy app // var sourceFileName = Path.Combine(localTempPath, "source_" + jobDetails.JobId); var targetFileName = Path.Combine(localTempPath, "result_" + jobDetails.JobId); try { // // Parse the parameters passed in for the job // var parametersFromJob = jobDetails.Parameters.Split('|'); var storageAccountConnString = parametersFromJob[0]; var sourceBlobContainerName = parametersFromJob[1]; var sourceImageName = parametersFromJob[2]; var targetBlobContainerName = parametersFromJob[3]; // // Create the storage account proxies used for downloading and uploading the image // var storageAccount = CloudStorageAccount.Parse(storageAccountConnString); var blobClient = storageAccount.CreateCloudBlobClient(); // // Next download the source image to the local directory // var blobSourceContainer = blobClient.GetContainerReference(sourceBlobContainerName); var sourceImage = blobSourceContainer.GetBlobReferenceFromServer(sourceImageName); sourceImage.DownloadToFile(sourceFileName, FileMode.Create); // // Then execute the legacy application for creating the thumbnail // _runningApp = Process.Start ( _legacyAppExecutable, string.Format("\"{0}\" \"{1}\" Custom 100 100", sourceFileName, targetFileName) ); // You should set a timeout to wait for the external process and kill if timeout exceeded _runningApp.WaitForExit(); // // Evaluate the result of execution and throw exception on failure // if (_runningApp.ExitCode != 0) { var errorMessage = string.Format("Legacy app did exit with code {0}, processing failed!", _runningApp.ExitCode); Console.WriteLine(errorMessage, "Warning"); throw new Exception(errorMessage); } // // Processing succeeded, Now upload the result file to blob storage and update the jobs table // using (FileStream resultFile = new FileStream(targetFileName, FileMode.Open)) { var blobContainer = blobClient.GetContainerReference(targetBlobContainerName); blobContainer.CreateIfNotExists(); // Save it to the targetBlobContainerName with the same name as the original one var blob = blobContainer.GetBlockBlobReference(sourceImageName); // Upload the resulting file to the blob storage blob.UploadFromStream(resultFile); } } finally { // // No app is running anymore // try { _runningApp.Dispose(); } catch { } _runningApp = null; // // Deletes all temporary files that have been created as part of processing // It would also be good to run that time-controlled in regular intervals in case of this fails // TryCleanUpTempFiles(sourceFileName, targetFileName); } }