in SimpleDUTRemote/JobSystem/Job.cs [50:101]
public Job(int id, Process process, JobCallbackInfo callback = null)
{
logger.Info("Spawning new job id {0}; will call {1}", id, process.StartInfo.FileName);
jobId = id;
this.process = process;
// if a progress port was specified in callback info, prepare for streaming
if (callback != null && callback.ProgressPort > 0)
{
var streamEp = new IPEndPoint(callback.Address, callback.ProgressPort);
CreateProgressStream(streamEp);
streamingCollection = new BlockingCollection<string>();
process.OutputDataReceived += (s, a) => streamingCollection.Add(a.Data);
process.ErrorDataReceived += (s, a) => streamingCollection.Add(a.Data);
streamingLoopTask = Task.Factory.StartNew(StreamingLoopHandler);
}
else
{
output = new HelperFunctions.ThreadSafeStringBuilder();
process.OutputDataReceived += (s, a) => output.AppendLine(a.Data);
process.ErrorDataReceived += (s, a) => output.AppendLine(a.Data);
}
// always log output
process.OutputDataReceived += (s,a) => logger.Debug($"Job {this.jobId} std output: {a.Data}");
process.ErrorDataReceived += (s,a) => logger.Debug($"Job {this.jobId} std error: {a.Data}");
// add a logging message when a job finishes and ensure that streaming task stops if needed
process.EnableRaisingEvents = true;
process.Exited += (o, e) => logger.Info($"Job {id} finished executing.");
process.Exited += (o, e) => streamingCollection?.Add(null);
if (callback != null)
{
logger.Info("Registering job {0:d} for callbacks", id);
// if callbacks are specified, we need to register for process events, and setup a handler
callbackInfo = callback;
// fire the callback handler in another thread (otherwise the callback might take a while and block other events waiting on exit)
process.Exited += (o, e) => Task.Factory.StartNew(FireCompletionCallback);
}
process.Start();
process.BeginErrorReadLine();
process.BeginOutputReadLine();
}