static int Run(string[] args, ILogger logger) { TaskCompletionSource <int> exited = null; Task heartBeat = null; var newArgs = new List <string>(); for (int i = 0; i < args.Length; ++i) { var arg = args[i]; if (arg == "--debugBreak") { logger.Log("Waiting for debugger"); while (!Debugger.IsAttached) { Thread.Sleep(1000); } Debugger.Break(); } else { newArgs.Add(arg); } } args = newArgs.ToArray(); var server = new PersistentProcessManager(); int exitCode = 1; if (args.Length < 1) { Usage(logger); } else { string configFile, heartBeatUri = null, jobName = null; if (args.Length > 1) { if (args.Length > 2) { jobName = Utils.CmdLineDecode(args[2]); } exited = new TaskCompletionSource <int>(); configFile = args[1]; heartBeatUri = Utils.CmdLineDecode(args[0]); } else { configFile = args[0]; } if (heartBeatUri != null) { string appId = Yarn.Utils.ApplicationIdFromEnvironment(); try { jobDirectoryUri = new Uri(heartBeatUri.Replace("_JOBID_", appId)); } catch (Exception) { logger.Log("Bad job directory URI " + heartBeatUri); } } if (server.Initialize(configFile, jobDirectoryUri, logger)) { if (heartBeatUri != null) { heartBeat = HeartBeat(logger, server, exited.Task, jobName); } server.Start(); exitCode = server.WaitForShutdown(); server.Stop(); } } if (heartBeat != null) { exited.SetResult(exitCode); heartBeat.Wait(); } return(exitCode); }
static async Task HeartBeat(ILogger logger, PersistentProcessManager server, Task <int> exited, string jobName) { try { DateTime startTime = DateTime.UtcNow; if (jobDirectoryUri.Scheme != "azureblob") { logger.Log("Can't send heartbeat to non-Azure dfs " + jobDirectoryUri.AbsoluteUri); return; } string account, key, container, directoryName; Azure.Utils.FromAzureUri(jobDirectoryUri, out account, out key, out container, out directoryName); // get the full name of the blob from the job directory string heartbeatBlobName = directoryName + "heartbeat"; string killBlobName = directoryName + "kill"; using (Azure.AzureDfsClient client = new Azure.AzureDfsClient(account, key, container)) { CloudPageBlob killBlob = client.Container.GetPageBlobReference(killBlobName); CloudPageBlob heartbeatBlob = client.Container.GetPageBlobReference(heartbeatBlobName); await heartbeatBlob.CreateAsync(512); heartbeatBlob.Metadata["status"] = "running"; heartbeatBlob.Metadata["starttime"] = startTime.ToString(); if (jobName != null) { jobName = jobName.Replace('\r', ' ').Replace('\n', ' '); try { heartbeatBlob.Metadata["jobname"] = jobName; } catch (Exception e) { logger.Log("Got exception trying to set jobname metadata to '" + jobName + "': " + e.ToString()); heartbeatBlob.Metadata["jobname"] = "[got exception setting job name]"; } } while (true) { logger.Log("Uploading heartbeat properties"); heartbeatBlob.Metadata["heartbeat"] = DateTime.UtcNow.ToString(); await heartbeatBlob.SetMetadataAsync(); logger.Log("Heartbeat sleeping"); Task <int> t = await Task.WhenAny(exited, Task.Delay(1000).ContinueWith((d) => { return(259); })); int exitCode = t.Result; string status = null; if (t == exited) { status = (exitCode == 0) ? "success" : "failure"; } else if (killBlob.Exists()) { exitCode = 1; status = "killed"; server.TriggerFullShutdown(1, "job was cancelled"); } if (status != null) { logger.Log("Uploading final heartbeat properties " + exitCode + " " + status); heartbeatBlob.Metadata["status"] = status; await heartbeatBlob.SetMetadataAsync(); logger.Log("Heartbeat exiting"); return; } } } } catch (Exception e) { logger.Log("Heartbeat got exception " + e.ToString()); } }