private static SnTaskResult ExecuteTask(SnTask t) { Console.WriteLine("Start work on task#" + t.Id); var result = new SnTaskResult { AgentName = AgentName, Task = t }; try { if (t.Type == "DoNotRunAnyExecutor") { using (var executor = new TestExecutor()) result.ResultCode = executor.Execute(t); } else { using (var executor = new OutProcExecutor()) result.ResultCode = executor.Execute(t); } } catch (Exception e) { result.Exception = e; } Console.WriteLine("Execution finished."); return(result); }
private static void WriteStartExecutionEvent(SnTask task, string machineName, string agentName) { var message = "Agent " + task.LockedBy + " started a task execution."; WriteEvent(null, TaskEventType.Started, task.Id, null, task.Title, null, task.AppId, machineName, agentName, task.Tag, null, null, null, null); }
private string GetWorkerExePath(SnTask task) { string exePath; if (Agent.TaskExecutors.TryGetValue(task.Type, out exePath)) { return(exePath); } return(null); }
public static string GetFinalizeUrl(this SnTask task, Application app) { var combinedUrl = CombineUrls(app, task.FinalizeUrl, task.Id); // there is no local url: try the global if (string.IsNullOrEmpty(combinedUrl) && app != null) { combinedUrl = CombineUrls(app, app.TaskFinalizeUrl); } return(combinedUrl); }
//===================================================================== Static API public static void BroadcastMessage(SnTask task) { try { var hubContext = GlobalHost.ConnectionManager.GetHubContext <AgentHub>(); hubContext.Clients.All.NewTask(task); } catch (Exception ex) { SnLog.WriteException(ex, "AgentHub BroadcastMessage failed.", EventId.TaskManagement.General); } }
public int Execute(SnTask task) { Task = task; Agent.ExecutionStart(this); try { return(ExecuteInner(task)); } finally { Agent.ExecutionEnd(); } }
/*------------------------------------------------------------------------- */ async static void Work() { lock (_workingsync) { if (_working || _updateStarted) { return; } _working = true; } StartLockTimer(); Console.WriteLine("_______________________________WORKING"); try { var t = await GetTask(); while (t != null) { _currentTask = t; var result = ExecuteTask(t); _currentTask = null; // this will call the finalizers on the server side and delete the task from the database SendResultAndDeleteTask(result); // if an update process started in the meantime, do not get a new task if (_updateStarted) { return; } // after finishing the previous one, try to get the next task t = await GetTask(); } } catch (Exception e) { SnLog.WriteException(e, "Agent error.", EventId.TaskManagement.General); _reconnecting = true; } finally { StopLockTimer(); _working = false; Console.WriteLine("_______________________________WAITING"); } }
public int Execute(SnTask task) { Task = task; var t = 10000 + new Random().Next(5000); Console.Write("t: " + t + " "); _timer.Start(); System.Threading.Thread.Sleep(t); _timer.Stop(); Console.WriteLine("."); return(0); }
private static SnTaskResult ExecuteTask(SnTask t) { Console.WriteLine("Start work on task#" + t.Id); var result = new SnTaskResult { MachineName = Environment.MachineName, AgentName = AgentName, Task = t }; try { if (t.Type == "DoNotRunAnyExecutor") { using var executor = new TestExecutor(); result.ResultCode = executor.Execute(t); } else { using var executor = new OutProcExecutor(AgentConfig); result.ResultCode = executor.Execute(t); } } catch (Exception e) { result.Error = SnTaskError.Create(e); } Console.WriteLine("Execution finished."); result.ResultData = _resultData; if (result.Error == null && _resultError != null) { result.Error = SnTaskError.Parse(_resultError); } _resultData = null; _resultError = null; return(result); }
/*------------------------------------------------------------------------- */ async static void Work() { lock (_workingsync) { if (_working) { return; } _working = true; } StartLockTimer(); Console.WriteLine("_______________________________WORKING"); try { SnTask t; t = await GetTask(); while (t != null) { _currentTask = t; var result = ExecuteTask(t); _currentTask = null; SendResult(result); // after finishing the previous one, try to get the next task t = await FinishAndGetTask(t.Id); } } catch (Exception e) { Logger.WriteError(EventId.ExecutionError, e); _reconnecting = true; } finally { StopLockTimer(); _working = false; Console.WriteLine("_______________________________WAITING"); } }
/*------------------------------------------------------------------------- */ private static async Task WorkAsync() { lock (WorkingSync) { if (_working) { return; } _working = true; } StartLockTimer(); Console.WriteLine("_______________________________WORKING"); try { var t = await GetTask(); while (t != null) { _currentTask = t; var result = ExecuteTask(t); _currentTask = null; // this will call the finalizers on the server side and delete the task from the database await SendResultAndDeleteTask(result); // after finishing the previous one, try to get the next task t = await GetTask(); } } catch (Exception e) { SnLog.WriteException(e, "Agent error.", EventId.TaskManagement.General); } finally { StopLockTimer(); _working = false; Console.WriteLine("_______________________________WAITING"); } }
/*----------------------------------------------------- called by hub proxy */ private static void NewTask(SnTask t) { if (_working) { return; } if (t != null && !TaskExecutors.ContainsKey(t.Type)) { return; } SnTrace.TaskManagement.Write( t == null ? "Agent {0} handles a 'handle-dead-tasks' message." : "Agent {0} handles a 'new-tasks' message.", AgentName); #pragma warning disable 4014 WorkAsync(); #pragma warning restore 4014 }
public async Task <SnTask> GetNextAndLock(string machineName, string agentName, string[] capabilities, CancellationToken cancellationToken) { var sql = string.Format(GETANDLOCKSQL, string.Join("', '", capabilities)); await using var cn = new SqlConnection(_connectionString); #pragma warning disable CA2100 // Review SQL queries for security vulnerabilities await using var cm = new SqlCommand(sql, cn) { CommandType = CommandType.Text }; #pragma warning restore CA2100 // Review SQL queries for security vulnerabilities cm.Parameters.Add("@LockedBy", SqlDbType.NVarChar, 450).Value = agentName; cm.Parameters.AddWithValue("@ExecutionTimeoutInSeconds", _config.TaskExecutionTimeoutInSeconds); await cn.OpenAsync(cancellationToken).ConfigureAwait(false); var reader = await cm.ExecuteReaderAsync(cancellationToken).ConfigureAwait(false); while (await reader.ReadAsync(cancellationToken).ConfigureAwait(false)) { var task = new SnTask { Id = reader.GetInt32(reader.GetOrdinal("Id")), Type = reader.GetString(reader.GetOrdinal("Type")), Title = reader.GetString(reader.GetOrdinal("Title")), Order = reader.GetDouble(reader.GetOrdinal("Order")), Tag = GetSafeString(reader, reader.GetOrdinal("Tag")), RegisteredAt = reader.GetDateTime(reader.GetOrdinal("RegisteredAt")), AppId = GetSafeString(reader, reader.GetOrdinal("AppId")), FinalizeUrl = GetSafeString(reader, reader.GetOrdinal("FinalizeUrl")), LastLockUpdate = GetSafeDateTime(reader, reader.GetOrdinal("LastLockUpdate")), LockedBy = GetSafeString(reader, reader.GetOrdinal("LockedBy")), Hash = reader.GetInt64(reader.GetOrdinal("Hash")), TaskData = GetSafeString(reader, reader.GetOrdinal("TaskData")), }; await WriteStartExecutionEventAsync(task, machineName, agentName, cancellationToken).ConfigureAwait(false); return(task); } return(null); }
/*----------------------------------------------------- called by hub proxy */ private static void NewTask(SnTask t) { if (_working) { return; } if (t != null && !TaskExecutors.ContainsKey(t.Type)) { return; } if (t == null) { SnTrace.TaskManagement.Write("Agent {0} handles a 'handle-dead-tasks' message.", AgentName); } else { SnTrace.TaskManagement.Write("Agent {0} handles a 'new-tasks' message.", AgentName); } Work(); }
public static SnTask GetNextAndLock(string machineName, string agentName, string[] capabilities) { var sql = String.Format(GETANDLOCKSQL, String.Join("', '", capabilities)); using (var cn = new SqlConnection(Configuration.ConnectionString)) using (var cm = new SqlCommand(sql, cn) { CommandType = System.Data.CommandType.Text }) { cm.Parameters.Add("@LockedBy", SqlDbType.NVarChar, 450).Value = agentName; cm.Parameters.AddWithValue("@ExecutionTimeoutInSeconds", Configuration.TaskExecutionTimeoutInSeconds); cn.Open(); var reader = cm.ExecuteReader(); while (reader.Read()) { var task = new SnTask { Id = reader.GetInt32(reader.GetOrdinal("Id")), Type = reader.GetString(reader.GetOrdinal("Type")), Title = reader.GetString(reader.GetOrdinal("Title")), Order = reader.GetDouble(reader.GetOrdinal("Order")), Tag = GetSafeString(reader, reader.GetOrdinal("Tag")), RegisteredAt = reader.GetDateTime(reader.GetOrdinal("RegisteredAt")), AppId = GetSafeString(reader, reader.GetOrdinal("AppId")), FinalizeUrl = GetSafeString(reader, reader.GetOrdinal("FinalizeUrl")), LastLockUpdate = GetSafeDateTime(reader, reader.GetOrdinal("LastLockUpdate")), LockedBy = GetSafeString(reader, reader.GetOrdinal("LockedBy")), Hash = reader.GetInt64(reader.GetOrdinal("Hash")), TaskData = GetSafeString(reader, reader.GetOrdinal("TaskData")), }; WriteStartExecutionEvent(task, machineName, agentName); return(task); } return(null); } }
private int ExecuteInner(SnTask task) { var workerExe = GetWorkerExePath(task); if (string.IsNullOrEmpty(workerExe) || !File.Exists(workerExe)) { throw new TaskManagementException("Task executor command was not found", task.AppId, task.Id, task.Type); } var app = _config.Applications.FirstOrDefault(a => string.Equals(a.AppId, task.AppId, StringComparison.OrdinalIgnoreCase)); var userParameter = "USERNAME:\"" + (task.AppId ?? string.Empty) + "\""; var passwordParameter = "PASSWORD:\"" + (app?.Secret ?? string.Empty) + "\""; var dataParameter = "DATA:\"" + EscapeArgument(task.TaskData) + "\""; var parameters = new List <string> { userParameter, passwordParameter, dataParameter }; var processArgs = string.Join(" ", parameters); var startInfo = new ProcessStartInfo(workerExe, processArgs) { UseShellExecute = false, WorkingDirectory = Path.GetDirectoryName(workerExe), CreateNoWindow = true, ErrorDialog = false, WindowStyle = ProcessWindowStyle.Hidden, RedirectStandardInput = true, RedirectStandardOutput = true, RedirectStandardError = true, }; _process = new Process { EnableRaisingEvents = true, StartInfo = startInfo }; _process.OutputDataReceived += Process_OutputDataReceived; SnLog.WriteInformation(string.Format( "Task#{1} execution STARTED on agent {0}:\r\n id: {1},\r\n type: {2},\r\n hash: {3},\r\n order: {4},\r\n registered: {5},\r\n key: {6},\r\n data: {7}" , Agent.AgentName, task.Id, task.Type, task.Hash, task.Order, task.RegisteredAt, task.TaskKey, task.TaskData), EventId.TaskManagement.Lifecycle); _process.Start(); _process.BeginOutputReadLine(); _process.WaitForExit(); _process.OutputDataReceived -= Process_OutputDataReceived; var result = _process.ExitCode; if (result != 0) { SnLog.WriteWarning($"Task#{task.Id} execution TERMINATED with error. Result:{result}, task type: {task.Type}, agent: {Agent.AgentName}", EventId.TaskManagement.General); } else { SnLog.WriteInformation($"Task#{task.Id} execution FINISHED: type: {task.Type}, agent: {Agent.AgentName}", EventId.TaskManagement.Lifecycle); } _process.Dispose(); _process = null; return(result); }
private Task WriteStartExecutionEventAsync(SnTask task, string machineName, string agentName, CancellationToken cancellationToken) { return(WriteEventAsync(null, TaskEventType.Started, task.Id, null, task.Title, null, task.AppId, machineName, agentName, task.Tag, null, null, null, null, cancellationToken)); }
private Task WriteFinishSubtaskEventAsync(SnSubtask subtask, SnTask task, string machine, string agent, CancellationToken cancellationToken) { return(WriteEventAsync(null, TaskEventType.SubtaskFinished, task.Id, subtask.Id, subtask.Title, subtask.Details, task.AppId, machine, agent, task.Tag , null, null, null, null, cancellationToken)); }
private string GetWorkerExePath(SnTask task) { return(Agent.TaskExecutors.TryGetValue(task.Type, out var exePath) ? exePath : null); }
private static void WriteFinishSubtaskEvent(SnSubtask subtask, SnTask task, string machine, string agent) { WriteEvent(null, TaskEventType.SubtaskFinished, task.Id, subtask.Id, subtask.Title, subtask.Details, task.AppId, machine, agent, task.Tag , null, null, null, null); }
public static async Task BroadcastNewTask(this IHubContext <AgentHub> hubContext, SnTask task) { try { await hubContext.Clients.All.SendAsync("newTask", task).ConfigureAwait(false); } catch (Exception ex) { SnLog.WriteException(ex, "AgentHub BroadcastNewTask failed.", EventId.TaskManagement.General); } }
public static void FinishSubtask(string machineName, string agentName, SnSubtask subtask, SnTask task) { WriteFinishSubtaskEvent(subtask, task, machineName, agentName); }
public async Task FinishSubtask(string machineName, string agentName, SnSubtask subtask, SnTask task) { SnTrace.TaskManagement.Write("AgentHub FinishSubtask. Task id:{0}, agent:{1}, title:{2}", task.Id, agentName, subtask.Title); try { await _dataHandler.FinishSubtask(machineName, agentName, subtask, task, Context.ConnectionAborted).ConfigureAwait(false); await _monitorHub.OnTaskEvent(SnTaskEvent.CreateSubtaskFinishedEvent(task.Id, subtask.Title, subtask.Details, task.AppId, task.Tag, machineName, agentName, subtask.Id)).ConfigureAwait(false); } catch (Exception ex) { SnLog.WriteException(ex, "AgentHub FinishSubtask failed.", EventId.TaskManagement.General); } }
public void FinishSubtask(string machineName, string agentName, SnSubtask subtask, SnTask task) { SnTrace.TaskManagement.Write("AgentHub FinishSubtask. Task id:{0}, agent:{1}, title:{2}", task.Id, agentName, subtask.Title); try { TaskDataHandler.FinishSubtask(machineName, agentName, subtask, task); TaskMonitorHub.OnTaskEvent(SnTaskEvent.CreateSubtaskFinishedEvent(task.Id, subtask.Title, subtask.Details, task.AppId, task.Tag, machineName, agentName, subtask.Id)); } catch (Exception ex) { SnLog.WriteException(ex, "AgentHub FinishSubtask failed.", EventId.TaskManagement.General); } }
private int ExecuteInner(SnTask task) { var workerExe = GetWorkerExePath(task); if (string.IsNullOrEmpty(workerExe) || !File.Exists(workerExe)) { throw new Exception("Task executor command was not found: " + task.Type); } var urlParameter = "REPO:\"" + Configuration.RepositoryUrl + "\""; var userParameter = "USERNAME:\"" + Configuration.Username + "\""; var passwordParameter = "PASSWORD:\"" + Configuration.Password + "\""; var dataParameter = "DATA:\"" + EscapeArgument(task.TaskData) + "\""; var prms = new List <string> { urlParameter, userParameter, passwordParameter, dataParameter }; var processArgs = string.Join(" ", prms); var startInfo = new ProcessStartInfo(workerExe, processArgs) { UseShellExecute = false, WorkingDirectory = Path.GetDirectoryName(workerExe), CreateNoWindow = true, ErrorDialog = false, WindowStyle = ProcessWindowStyle.Hidden, RedirectStandardInput = true, RedirectStandardOutput = true, RedirectStandardError = true, }; //_process = Process.Start(startInfo); _process = new Process(); _process.EnableRaisingEvents = true; _process.StartInfo = startInfo; _process.OutputDataReceived += process_OutputDataReceived; Logger.WriteInformation(EventId.ExecutionStarted, "Task#{1} execution STARTED on agent {0}:\r\n id: {1},\r\n type: {2},\r\n hash: {3},\r\n order: {4},\r\n registered: {5},\r\n key: {6},\r\n data: {7}" , Agent.AgentName, task.Id, task.Type, task.Hash, task.Order, task.RegisteredAt, task.TaskKey, task.TaskData); _process.Start(); _process.BeginOutputReadLine(); _process.WaitForExit(); _process.OutputDataReceived -= process_OutputDataReceived; var result = _process.ExitCode; if (result != 0) { Logger.WriteWarning(EventId.TaskErrorResult, "Task#{0} execution TERMINATED with error. Result:{1}, task type: {2}, agent: {3}", task.Id, result, task.Type, Agent.AgentName); } else { Logger.WriteInformation(EventId.ExecutionFinished, "Task#{0} execution FINISHED: type: {1}, agent: {2}", task.Id, task.Type, Agent.AgentName); } _process.Dispose(); _process = null; return(result); }
public Task FinishSubtask(string machineName, string agentName, SnSubtask subtask, SnTask task, CancellationToken cancellationToken) { return(WriteFinishSubtaskEventAsync(subtask, task, machineName, agentName, cancellationToken)); }