public EmbedderTableEntity(EmbedderJob job, string status) { this.PartitionKey = job.Job.AssetID; this.RowKey = $"{job.WatermarkedURL.NormalizedURL().ToPartitionKey()}_{job.UserID}"; this.WaterMarkedMp4 = job.WatermarkedURL.NormalizedURL(); this.UserID = job.UserID; this.AssetID = job.Job.AssetID; this.JobID = job.Job.JobID; this.Status = status; }
public Task LogEmbedderAsync(EmbedderJob job, string status) { if (this.embedderTable == null) { return(Task.CompletedTask); } var entity = new EmbedderTableEntity(job: job, status: status); return(Policy.Handle <Exception>() .WaitAndRetryAsync(retryCount: 5, sleepDurationProvider: attempt => TimeSpan.FromSeconds(1), onRetry: (ex, ts) => { Console.WriteLine($"While logging to table: {ex.Message}"); }) .ExecuteAsync(() => { return embedderTable.InsertOrReplaceAsync <EmbedderTableEntity>(entity); })); }
private static async Task RunEmbedderAsync(EmbedderJob _, Action <Category, string> stdout, Action <Category, string> stderr) { #region Embedder stdout(Category.Embedder, $"Start embed {_.UserID} into {_.WatermarkedFile.FullName}"); var embedderOutput = await Utils.RunProcessAsync( prefix : "EMBEDDER", fileName : "/usr/bin/NGS_SmartEmbedderCLI", additionalEnvironment : new Dictionary <string, string> { { "TMPDIR", Environment.CurrentDirectory } }, arguments : new[] { _.MmrkFile.FullName, _.UserID, _.WatermarkedFile.FullName } ); if (embedderOutput.Success) { stdout(Category.Embedder, $"Finished embed {_.UserID} into {_.WatermarkedFile.FullName}"); // stdout(Category.Embedder, embedderOutput.Output); } else { stderr(Category.Embedder, embedderOutput.Output); var queueOutput = await _.Queue.DispatchMessage(new NotificationEmbedder { AssetID = _.Job.AssetID, JobID = _.Job.JobID, FileName = _.Name, UserID = _.UserID, Status = JobStatus.Error, JobOutput = embedderOutput.Output }); if (!queueOutput.Success) { stderr(Category.QueueNotifications, queueOutput.Output); } return; } #endregion #region Upload stdout(Category.UploadWatermarked, $"Start upload {_.UserID} {_.WatermarkedFile.FullName}"); var uploadResult = await _.WatermarkedFile.UploadToAsync(_.WatermarkedURL); stdout(Category.UploadWatermarked, $"Finished upload {_.UserID} {_.WatermarkedFile.FullName}"); if (uploadResult.Success) { var queueOutput = await _.Queue.DispatchMessage(new NotificationEmbedder { AssetID = _.Job.AssetID, JobID = _.Job.JobID, FileName = _.Name, UserID = _.UserID, Status = JobStatus.Finished, JobOutput = uploadResult.Output }); if (!queueOutput.Success) { stderr(Category.QueueNotifications, queueOutput.Output); } } else { var queueOutput = await _.Queue.DispatchMessage(new NotificationEmbedder { AssetID = _.Job.AssetID, JobID = _.Job.JobID, FileName = _.Name, UserID = _.UserID, Status = JobStatus.Error, JobOutput = uploadResult.Output }); if (!queueOutput.Success) { stderr(Category.QueueNotifications, queueOutput.Output); } } #endregion #region Delete watermarked file after upload Policy .Handle <Exception>() .WaitAndRetry( retryCount: 5, sleepDurationProvider: attempt => TimeSpan.FromSeconds(1)) .Execute(() => { if (_.WatermarkedFile.Exists) { stdout(Category.Main, $"Delete {_.WatermarkedFile.FullName}"); _.WatermarkedFile.Delete(); } }); #endregion }
private static async Task RunEmbedderAsync(EmbedderJob _, Action <string> stdout, Action <string> stderr) { #region Embedder var embedderOutput = await Utils.RunProcessAsync( prefix : "EMBEDDER", fileName : "/usr/bin/NGS_SmartEmbedderCLI", arguments : new[] { _.MmrkFile.FullName, _.UserID, _.WatermarkedFile.FullName } ); if (embedderOutput.Success) { stdout(embedderOutput.Output); } else { stderr(embedderOutput.Output); var queueOutput = await _.Queue.DispatchMessage(new NotificationEmbedder { AssetID = _.Job.AssetID, JobID = _.Job.JobID, FileName = _.Name, UserID = _.UserID, Status = JobStatus.Error, JobOutput = embedderOutput.Output }); if (!queueOutput.Success) { stderr(queueOutput.Output); } return; } #endregion #region Upload var uploadResult = await _.WatermarkedFile.UploadToAsync(_.WatermarkedURL); if (uploadResult.Success) { var queueOutput = await _.Queue.DispatchMessage(new NotificationEmbedder { AssetID = _.Job.AssetID, JobID = _.Job.JobID, FileName = _.Name, UserID = _.UserID, Status = JobStatus.Finished, JobOutput = uploadResult.Output }); if (!queueOutput.Success) { stderr(queueOutput.Output); } } else { var queueOutput = await _.Queue.DispatchMessage(new NotificationEmbedder { AssetID = _.Job.AssetID, JobID = _.Job.JobID, FileName = _.Name, UserID = _.UserID, Status = JobStatus.Error, JobOutput = uploadResult.Output }); if (!queueOutput.Success) { stderr(queueOutput.Output); } } #endregion }
static async Task <int> MainAsync(string[] args) { #region Install licenses if (string.IsNullOrEmpty(Environment.GetEnvironmentVariable("LICENSES"))) { stderr(Category.Main, "Could not determine licenses from environment..."); return(-1); } LicenseData.InjectIntoFilesystem(environmentVariable: "LICENSES"); #endregion var tableConnectionString = Environment.GetEnvironmentVariable("LOGGINGTABLE"); if (string.IsNullOrEmpty(tableConnectionString)) { stdout(Program.Category.Main, $"Could not configure table logging, missing environment variable 'LOGGINGTABLE'"); } var table = await TableWrapper.CreateAsync( connectionString : tableConnectionString, preprocessorTableName : "preprocessor", embedderTableName : "embedder"); #region Read Job EmbedderJobDTO job = null; var jobEnvironmentVariable = Environment.GetEnvironmentVariable("JOB"); if (string.IsNullOrEmpty(jobEnvironmentVariable)) { stderr(Category.Main, "Could not retrieve job from 'JOB' environment variable..."); return(-1); } try { string json = null; if (jobEnvironmentVariable.StartsWith("http")) { var ms = new MemoryStream(); using (var client = new HttpClient()) using (var stream = await client.GetStreamAsync(jobEnvironmentVariable)) { await stream.CopyToAsync(ms); } json = Encoding.UTF8.GetString(ms.GetBuffer()); } else { json = Encoding.UTF8.GetString( Convert.FromBase64String(jobEnvironmentVariable)); } // cat juan.json | jq -c -M . | base64 --wrap=0 > juan.base64 job = JsonConvert.DeserializeObject <EmbedderJobDTO>(json); if (job == null) { stderr(Category.Main, "Could not read job description from 'JOB' environment variable"); return(-1); } } catch (Exception ex) { stderr(Category.Main, $"Could not parse the job description: {ex.Message}"); stderr(Category.Main, $"JOB == {jobEnvironmentVariable}"); return(-1); } #endregion var workFolder = Path.Combine("/mnt", job.JobID .Replace(":", "_") .Replace("/", "_")); stdout(Category.Main, $"Changing work directory to {workFolder}"); Directory.CreateDirectory(workFolder); Environment.CurrentDirectory = workFolder; #region MMRK Generation var preprocessorData = PreprocessorJob.DeterminePreprocessorJobs(job); stdout(Category.Main, "Start Preprocessor"); foreach (var pd in preprocessorData) { // run these compute-intensive jobs sequentially await Program.RunPreprocessorAsync(pd, stdout, stderr, table); } stdout(Category.Main, "Finished Preprocessor"); #endregion #region Watermarking Func <int> getNumberOfParallelEmbedderTasks = () => { int result; if (int.TryParse(Environment.GetEnvironmentVariable("PARALLELEMBEDDERS"), out result)) { return(result); } return(5); }; var parallelEmbedderTasks = getNumberOfParallelEmbedderTasks(); stdout(Category.Main, "Start Embedder"); var embedderData = EmbedderJob.DetermineEmbedderJobs(job); await embedderData.ForEachAsync( parallelTasks : parallelEmbedderTasks, task : _ => Program.RunEmbedderAsync(_, stdout, stderr, table)); stdout(Category.Main, "Finished Embedder"); #endregion #region Delete all MMRK files from pod filesystem foreach (var pd in preprocessorData) { Policy .Handle <Exception>() .WaitAndRetry( retryCount: 5, sleepDurationProvider: attempt => TimeSpan.FromSeconds(1)) .Execute(() => { if (pd.MmrkFile.Exists) { pd.MmrkFile.Delete(); } }); } #endregion Environment.CurrentDirectory = "/"; stdout(Category.Main, $"Removing work directory {workFolder}"); Directory.Delete(workFolder, recursive: true); return(0); }