/// <summary> /// Public constructor. /// </summary> /// <param name="desc">the batch descriptor that initiates the processing.</param> /// <param name="resultduration">time duration of this result.</param> public DataProcessingResult(DataProcessingBatchDesc desc, System.TimeSpan resultduration) { Desc = desc; X = null; Processed = false; ExpirationTime = System.DateTime.Now + resultduration; }
/// <summary> /// Public constructor. /// </summary> /// <param name="desc">Descriptor of the batch.</param> /// <param name="x">Resulting exception.</param> /// <param name="resultlivetime">Time to live of the result.</param> public DataProcessingResult(DataProcessingBatchDesc desc, System.Exception x, System.TimeSpan resultlivetime) { Desc = desc; X = x; Processed = false; ExpirationTime = System.DateTime.Now + resultlivetime; }
/// <summary> /// Clones the DataProcessingBatchDesc object. /// </summary> /// <returns>a new object identical to this DataProcessingBatchDesc.</returns> public object Clone() { DataProcessingBatchDesc dps = new DataProcessingBatchDesc(); dps.Id = Id; if (Username != null) { dps.Username = (string)Username.Clone(); } if (Password != null) { dps.Password = (string)Password.Clone(); } if (Token != null) { dps.Token = (string)Token.Clone(); } dps.AliasUsername = (string)AliasUsername.Clone(); dps.AliasPassword = (string)AliasPassword.Clone(); dps.MachinePowerClass = MachinePowerClass; dps.CommandLineArguments = CommandLineArguments; dps.Filename = Filename; dps.Enqueued = Enqueued; dps.Started = Started; dps.Finished = Finished; dps.TotalProcessorTime = TotalProcessorTime; dps.PeakVirtualMemorySize = PeakVirtualMemorySize; dps.PeakWorkingSet = PeakWorkingSet; dps.Description = (string)Description.Clone(); dps.MaxOutputText = MaxOutputText; dps.OutputTextSaveFile = OutputTextSaveFile; return((object)dps); }
/// <summary> /// Enqueues a batch. /// </summary> /// <param name="desc">the descriptor of the batch.</param> /// <returns>true if the batch has been accepted, false otherwise.</returns> public bool Enqueue(DataProcessingBatchDesc desc) { m_ReturnException = null; m_pDesc = desc; m_Thread = new System.Threading.Thread(new System.Threading.ThreadStart( delegate() { try { m_ReturnObj = m_Srv.Enqueue(m_pDesc); } catch (Exception x) { m_ReturnException = x; } } )); m_Thread.Start(); if (m_Thread.Join(m_Timeout) == false) { try { m_Thread.Abort(); } catch (Exception) {} m_Srv = null; throw new Exception("Communication timeout!"); } if (m_ReturnException != null) { throw m_ReturnException; } return((bool)m_ReturnObj); }
/// <summary> /// Builds a new execution thread. /// </summary> /// <param name="sname">the server this thread monitors.</param> public ExeThread(string sname, System.Collections.ArrayList jq, System.Collections.ArrayList el, System.Threading.ManualResetEvent dr, System.Collections.ArrayList rs) { ServerName = sname; Desc = null; JobQueue = jq; ExeList = el; ResultList = rs; DataReady = dr; XThread = new System.Threading.Thread(new System.Threading.ThreadStart(Execute)); XThread.Start(); }
/// <summary> /// Enqueues a batch. /// </summary> /// <param name="desc">the descriptor of the batch. If the batch is rejected because another batch in the queue already has the same id, the Id member is set to 0.</param> /// <returns>true if the batch has been accepted, false otherwise.</returns> public bool Enqueue(DataProcessingBatchDesc desc) { if (m_IsWillingToProcess[0] == false) { return(false); } SySal.OperaDb.OperaDbConnection conn = null; try { conn = new SySal.OperaDb.OperaDbConnection(OperaDataProcessingServer.DBServer, OperaDataProcessingServer.DBUserName, OperaDataProcessingServer.DBPassword); conn.Open(); SySal.OperaDb.ComputingInfrastructure.UserPermission [] rights = new SySal.OperaDb.ComputingInfrastructure.UserPermission[1]; rights[0].DB_Site_Id = OperaDataProcessingServer.IdSite; rights[0].Designator = SySal.OperaDb.ComputingInfrastructure.UserPermissionDesignator.ProcessData; rights[0].Value = SySal.OperaDb.ComputingInfrastructure.UserPermissionTriState.Grant; if (desc.Token != null) { if (!SySal.OperaDb.ComputingInfrastructure.User.CheckTokenAccess(desc.Token, rights, conn, null)) { throw new Exception("The user does not own the permission to process data in this site"); } } else { SySal.OperaDb.ComputingInfrastructure.User.CheckAccess(SySal.OperaDb.ComputingInfrastructure.User.CheckLogin(desc.Username, desc.Password, conn, null), rights, true, conn, null); } conn.Close(); conn = null; } catch (System.Exception) { if (conn != null) { conn.Close(); } return(false); } lock (m_Queue) { foreach (SySal.DAQSystem.DataProcessingBatchDesc d in m_Queue) { if (d.Id == desc.Id) { desc.Id = 0; return(false); } } desc.Finished = desc.Started = desc.Enqueued = System.DateTime.Now; m_Queue.Add(desc); m_QueueNotEmpty.Set(); } return(true); }
/// <summary> /// Execution thread method. /// </summary> protected void ExecThread() { while (m_QueueNotEmpty.WaitOne()) { while (m_Queue.Count > 0) { SySal.OperaDb.OperaDbCredentials cred = new SySal.OperaDb.OperaDbCredentials(); DataProcessingBatchDesc desc = null; System.Exception retX = null; string retXstr = ""; m_ExecProc = new System.Diagnostics.Process(); lock (m_ExecProc) { m_ExecProcKilled = false; lock (m_Queue) { desc = (DataProcessingBatchDesc)m_Queue[0]; } m_ExecProc.StartInfo.Arguments = desc.CommandLineArguments; m_ExecProc.StartInfo.FileName = desc.Filename; m_ExecProc.StartInfo.UseShellExecute = false; m_ExecProc.StartInfo.RedirectStandardError = true; desc.Started = desc.Finished = System.DateTime.Now; try { cred.DBUserName = (desc.AliasUsername == null) ? "" : desc.AliasUsername; cred.DBPassword = (desc.AliasPassword == null) ? "" : desc.AliasPassword; cred.DBServer = OperaDataProcessingServer.DBServer; cred.OPERAUserName = (desc.Username == null) ? "" : desc.Username; cred.OPERAPassword = (desc.Password == null) ? "" : desc.Password; cred.RecordToEnvironment(m_ExecProc.StartInfo.EnvironmentVariables); desc.Started = System.DateTime.Now; m_ExecProc.Start(); } catch (Exception x) { retX = new DataProcessingException("Internal error occurred during process start.", x); } try { m_ExecProc.PriorityClass = OperaDataProcessingServer.LowPriority ? System.Diagnostics.ProcessPriorityClass.BelowNormal : System.Diagnostics.ProcessPriorityClass.Normal; //m_ExecProc.MaxWorkingSet = new System.IntPtr(OperaDataProcessingServer.PeakWorkingSetMB * 1048576); } catch (Exception) { } } if (retX == null) { //do { try { m_ExecProc.Refresh(); retXstr += m_ExecProc.StandardError.ReadToEnd(); desc.TotalProcessorTime = m_ExecProc.TotalProcessorTime; desc.PeakVirtualMemorySize = m_ExecProc.PeakVirtualMemorySize; desc.PeakWorkingSet = m_ExecProc.PeakWorkingSet; } catch (Exception) {} } //while (m_ExecProc.WaitForExit(1000) == false); desc.Finished = System.DateTime.Now; lock (m_ExecProc) { /* * try * { * retXstr += m_ExecProc.StandardError.ReadToEnd(); * } * catch (Exception) {}*/ if (retXstr == null || retXstr.Length == 0) { retX = null; } else { retX = new DataProcessingException(retXstr); } if (m_ExecProcKilled) { retX = new Exception("Process has been killed."); } } } else { try { retXstr += m_ExecProc.StandardError.ReadToEnd(); } catch (Exception) {} } m_ExecProc = null; SySal.OperaDb.OperaDbConnection conn = null; lock (m_ResultList) lock (m_Queue) { DataProcessingResult dpr = new DataProcessingResult(desc, m_ResultLiveTime); dpr.Processed = true; dpr.X = retX; m_ResultList.Add(dpr); m_Queue.RemoveAt(0); } } } }
/// <summary> /// Draws a batch out ouf the queue or aborts it if it is already being executed. /// A non-null token or a username/password pair must be supplied that matches the one with which the batch was started. /// If the token is supplied, the username/password pair is ignored. /// </summary> /// <param name="id">identifier of the batch to be removed.</param> /// <param name="token">the process token to be used.</param> /// <param name="user">username of the user that started the batch. Ignored if <c>token</c> is non-null.</param> /// <param name="password">password of the user that started the batch. Ignored if <c>token</c> is non-null.</param> public void Remove(ulong id, string token, string user, string password) { lock (m_Queue) { int i; for (i = 0; i < m_Queue.Count && ((DataProcessingBatchDesc)m_Queue[i]).Id != id; i++) { ; } if (i == m_Queue.Count) { throw new Exception("Batch not present in processing queue."); } DataProcessingBatchDesc dpb = (DataProcessingBatchDesc)m_Queue[i]; bool OkToRemove = false; if (token != null) { if (dpb.Token != null) { if (dpb.Token == token) { OkToRemove = true; } else { throw new Exception("A process operation cannot remove a batch of another process operation."); } } else { throw new Exception("A process operation cannot remove a batch that has been started with a specific user request."); } } else { long id_user = 0; SySal.OperaDb.OperaDbConnection conn = null; try { conn = new SySal.OperaDb.OperaDbConnection(OperaDataProcessingServer.DBServer, OperaDataProcessingServer.DBUserName, OperaDataProcessingServer.DBPassword); conn.Open(); id_user = SySal.OperaDb.ComputingInfrastructure.User.CheckLogin(user, password, conn, null); if (dpb.Token != null) { try { SySal.OperaDb.ComputingInfrastructure.User.CheckTokenOwnership(dpb.Token, id_user, null, null, conn, null); OkToRemove = true; } catch (Exception) { throw new Exception("A user cannot remove a batch started by an operation of another user."); } } else { if (String.Compare(dpb.Username, user, true) != 0) { throw new Exception("A user cannot stop a batch scheduled by another user!"); } else { OkToRemove = true; } } } catch (Exception) { if (conn != null) { conn.Close(); } } } if (OkToRemove == false) { throw new Exception("Cannot remove the batch."); } if (i == 0) { try { m_ExecProc.Kill(); m_ExecProcKilled = true; } catch (Exception) {} } else { lock (m_ResultList) { m_Queue.RemoveAt(i); DataProcessingResult dpr = null; for (i = 0; i < m_ResultList.Count; i++) { dpr = (DataProcessingResult)m_ResultList[i]; if (dpr.Desc.Id == id) { return; } } dpr = new DataProcessingResult(dpb, m_ResultLiveTime); dpr.X = new Exception("The batch was removed from the queue."); dpr.Processed = true; m_ResultList.Add(dpr); } } } }
/// <summary> /// Execution thread method. /// </summary> protected void ExecThread() { while (m_QueueNotEmpty.WaitOne()) { while (m_Queue.Count > 0) { SySal.OperaDb.OperaDbCredentials cred = new SySal.OperaDb.OperaDbCredentials(); DataProcessingBatchDesc desc = null; System.Exception retX = null; string textout = ""; string retXstr = ""; m_ExecProc = new System.Diagnostics.Process(); lock (m_ExecProc) { m_ExecProcKilled = false; lock (m_Queue) { desc = (DataProcessingBatchDesc)m_Queue[0]; } m_ExecProc.StartInfo.Arguments = desc.CommandLineArguments; m_ExecProc.StartInfo.FileName = desc.Filename; m_ExecProc.StartInfo.UseShellExecute = false; m_ExecProc.StartInfo.RedirectStandardError = true; m_ExecProc.StartInfo.RedirectStandardOutput = true; desc.Started = desc.Finished = System.DateTime.Now; try { cred.DBUserName = (desc.AliasUsername == null) ? "" : desc.AliasUsername; cred.DBPassword = (desc.AliasPassword == null) ? "" : desc.AliasPassword; cred.DBServer = OperaDataProcessingServer.DBServer; cred.OPERAUserName = (desc.Username == null) ? "" : desc.Username; cred.OPERAPassword = (desc.Password == null) ? "" : desc.Password; cred.RecordToEnvironment(m_ExecProc.StartInfo.EnvironmentVariables); desc.Started = System.DateTime.Now; m_ExecProc.Start(); } catch (Exception x) { retX = new DataProcessingException("Internal error occurred during process start.", x); } try { m_ExecProc.PriorityClass = OperaDataProcessingServer.LowPriority ? System.Diagnostics.ProcessPriorityClass.BelowNormal : System.Diagnostics.ProcessPriorityClass.Normal; //m_ExecProc.MaxWorkingSet = new System.IntPtr(OperaDataProcessingServer.PeakWorkingSetMB * 1048576); } catch (Exception) {} } int c = -1; if (retX == null) { do { try { m_ExecProc.Refresh(); System.DateTime nextw = System.DateTime.Now.AddSeconds(OutputUpdateSeconds); while ((c = m_ExecProc.StandardOutput.Read()) >= 0) { textout += (char)c; if (textout.Length > OperaDataProcessingServer.MaxOutputText) { textout = textout.Remove(0, textout.Length - OperaDataProcessingServer.MaxOutputText); } if (System.DateTime.Now >= nextw) { try { if (desc.OutputTextSaveFile != null && desc.OutputTextSaveFile.Length > 0) { System.IO.File.WriteAllText(desc.OutputTextSaveFile, textout); } } catch (Exception) { } } finally { nextw = System.DateTime.Now.AddSeconds(OutputUpdateSeconds); } } while ((c = m_ExecProc.StandardError.Read()) >= 0) { retXstr += (char)c; } desc.TotalProcessorTime = m_ExecProc.TotalProcessorTime; desc.PeakVirtualMemorySize = m_ExecProc.PeakVirtualMemorySize; desc.PeakWorkingSet = m_ExecProc.PeakWorkingSet; if (desc.OutputTextSaveFile != null && desc.OutputTextSaveFile.Length > 0) { System.IO.File.WriteAllText(desc.OutputTextSaveFile, textout); } }
/// <summary> /// Draws a batch out ouf the queue or aborts it if it is already being executed. /// A non-null token or a username/password pair must be supplied that matches the one with which the batch was started. /// If the token is supplied, the username/password pair is ignored. /// </summary> /// <param name="id">identifier of the batch to be removed.</param> /// <param name="token">the process token to be used.</param> /// <param name="user">username of the user that started the batch. Ignored if <c>token</c> is non-null.</param> /// <param name="password">password of the user that started the batch. Ignored if <c>token</c> is non-null.</param> public void Remove(ulong id, string token, string user, string password) { lock (m_Queue) { int i; for (i = 0; i < m_Queue.Count; i++) { SySal.DAQSystem.DataProcessingBatchDesc desc = (SySal.DAQSystem.DataProcessingBatchDesc)m_Queue[i]; bool OkToRemove = false; if (desc.Id == id) { if (token != null) { if (desc.Token != null) { if (desc.Token == token) { OkToRemove = true; } else { throw new Exception("A process operation cannot remove a batch of another process operation."); } } else { throw new Exception("A process operation cannot remove a batch that has been started with a specific user request."); } } else { long id_user = 0; SySal.OperaDb.OperaDbConnection conn = null; try { conn = new SySal.OperaDb.OperaDbConnection(MainForm.DBServer, MainForm.DBUserName, MainForm.DBPassword); conn.Open(); id_user = SySal.OperaDb.ComputingInfrastructure.User.CheckLogin(user, password, conn, null); if (desc.Token != null) { try { SySal.OperaDb.ComputingInfrastructure.User.CheckTokenOwnership(desc.Token, id_user, null, null, conn, null); OkToRemove = true; } catch (Exception) { throw new Exception("A user cannot remove a batch started by an operation of another user."); } } else { if (String.Compare(desc.Username, user, true) != 0) { throw new Exception("A user cannot stop a batch scheduled by another user!"); } else { OkToRemove = true; } } } catch (Exception) { if (conn != null) { conn.Close(); } } } if (OkToRemove == false) { throw new Exception("Cannot remove the batch."); } else { DataProcessingResult dpr = new DataProcessingResult(desc, new Exception("The batch was removed from the queue."), m_ResultLiveTime); dpr.Processed = true; m_ResultList.Add(dpr); m_Queue.RemoveAt(i); for (i = 0; i < m_ExeList.Count; i++) { if (((ExeBatch)m_ExeList[i]).Desc.Id == id) { ExeBatch exe = (ExeBatch)m_ExeList[i]; try { exe.DPSW.Remove(exe.MappedDesc.Id, exe.MappedDesc.Token, exe.MappedDesc.Username, exe.MappedDesc.Password); } catch (Exception) {} m_ExeList.RemoveAt(i); } } return; } } } } }
/// <summary> /// Schedules batches onto DataProcessingServers. /// </summary> protected void FeedDataProcessingServers() { if (m_ExeList.Count < m_DPSHandlers.Length) { lock (m_Queue) { if (m_Queue.Count > m_ExeList.Count) { DataProcSrvHandler [] l_AvDPSHandlers = (DataProcSrvHandler [])m_DPSHandlers.Clone(); int i, j; for (j = 0; j < m_ExeList.Count; j++) { for (i = 0; i < l_AvDPSHandlers.Length; i++) { if (l_AvDPSHandlers[i] != null && l_AvDPSHandlers[i].Srv == ((ExeBatch)m_ExeList[j]).DPSW) { l_AvDPSHandlers[i] = null; break; } } } for (i = 0; i < m_Queue.Count; i++) { SySal.DAQSystem.DataProcessingBatchDesc desc = (SySal.DAQSystem.DataProcessingBatchDesc)m_Queue[i]; for (j = 0; j < m_ExeList.Count; j++) { if (((ExeBatch)m_ExeList[j]).Desc == desc) { break; } } if (j == m_ExeList.Count) { for (j = 0; j < l_AvDPSHandlers.Length; j++) { try { if (l_AvDPSHandlers[j] != null && l_AvDPSHandlers[j].IsAvailable && l_AvDPSHandlers[j].MachinePowerClass >= desc.MachinePowerClass) { ExeBatch exe = new ExeBatch(); exe.Desc = desc; exe.MappedDesc = (SySal.DAQSystem.DataProcessingBatchDesc)desc.Clone(); exe.MappedDesc.Id = l_AvDPSHandlers[j].Srv.SuggestId; exe.MappedDesc.Description = exe.Desc.Id.ToString("X16") + " _DPS_REMAP_ " + exe.Desc.Description; if (MainForm.ImpersonateBatchUser == false) { exe.MappedDesc.Username = MainForm.OPERAUserName; exe.MappedDesc.Password = MainForm.OPERAPassword; exe.MappedDesc.Token = null; } exe.DPSW = l_AvDPSHandlers[j].Srv; if (exe.DPSW.Enqueue(exe.MappedDesc) == false) { long ticks = System.DateTime.Now.Ticks; if (ticks < 0) { ticks = -ticks; } exe.MappedDesc.Id = (ulong)ticks; exe.MappedDesc.Description = exe.MappedDesc.Id.ToString("X16") + " _OWN_REMAP_ " + exe.Desc.Description; if (l_AvDPSHandlers[j].Srv.Enqueue(exe.MappedDesc) == false) { m_ResultList.Add(new DataProcessingResult(exe.Desc, new Exception("Unknown error!"), MainForm.ResultLiveTime)); } else { m_ExeList.Add(exe); l_AvDPSHandlers[j] = null; break; } } else { m_ExeList.Add(exe); l_AvDPSHandlers[j] = null; break; } } } catch (Exception) { lock (m_DPSHandlers) { l_AvDPSHandlers[j].Srv = null; l_AvDPSHandlers[j].IsAvailable = false; l_AvDPSHandlers[j].MachinePowerClass = 0; } } } } } } } } }
/// <summary> /// The execution method, ran by the execution thread. /// </summary> public void Execute() { SySal.DAQSystem.SyncDataProcessingServerWrapper DPSW = null; int test = 0; string milestone = "A"; try { while (true) { try { if (DPSW == null) { DPSW = new SySal.DAQSystem.SyncDataProcessingServerWrapper((SySal.DAQSystem.IDataProcessingServer)System.Runtime.Remoting.RemotingServices.Connect(typeof(SySal.DAQSystem.IDataProcessingServer), "tcp://" + ServerName + ":" + ((int)SySal.DAQSystem.OperaPort.DataProcessingServer).ToString() + "/DataProcessingServer.rem"), new TimeSpan(0, 1, 0)); if (DPSW.TestComm(++test) != 2 * test - 1) { throw new Exception(); } MachinePowerClass = DPSW.MachinePowerClass; } } catch (Exception) { DPSW = null; continue; } milestone = "B"; try { Desc = null; int i; lock (JobQueue) { for (i = 0; i < JobQueue.Count; i++) { if (((SySal.DAQSystem.DataProcessingBatchDesc)JobQueue[i]).MachinePowerClass <= MachinePowerClass) { KillEvent.Reset(); Desc = (SySal.DAQSystem.DataProcessingBatchDesc)JobQueue[i]; JobQueue.RemoveAt(i); ExeList.Add(Desc); break; } } if (JobQueue.Count == 0) { DataReady.Reset(); } } milestone = "C"; if (Desc == null) { DataReady.WaitOne(); continue; } else { try { SySal.DAQSystem.DataProcessingBatchDesc mbd = (SySal.DAQSystem.DataProcessingBatchDesc)Desc.Clone(); milestone = "D"; mbd.Id = DPSW.SuggestId; milestone = "E"; mbd.Description = Desc.Id.ToString("X16") + " _DPS_REMAP_ " + Desc.Description; if (MainForm.ImpersonateBatchUser == false) { mbd.Username = MainForm.OPERAUserName; mbd.Password = MainForm.OPERAPassword; mbd.Token = null; } milestone = "E1"; if (DPSW.Enqueue(mbd) == false) { lock (JobQueue) { ExeList.Remove(Desc); JobQueue.Add(Desc); Desc = null; continue; } } milestone = "F"; bool killed = false; while (DPSW.DoneWith(mbd.Id) == false) { if (KillEvent.WaitOne(MainForm.DataProcSrvMonitorInterval * 1000)) { milestone = "F1"; lock (JobQueue) { milestone = "F2"; ResultList.Add(new DataProcessingResult(Desc, new Exception("The batch was removed from the queue."), MainForm.ResultLiveTime)); ExeList.Remove(Desc); Desc = null; milestone = "F3"; try { DPSW.Remove(mbd.Id, mbd.Token, mbd.Username, mbd.Password); } catch (Exception) { } milestone = "F4"; killed = true; break; } } } if (killed == false) { milestone = "G"; mbd = DPSW.Result(mbd.Id); milestone = "H"; Desc.PeakVirtualMemorySize = mbd.PeakVirtualMemorySize; Desc.PeakWorkingSet = mbd.PeakWorkingSet; Desc.TotalProcessorTime = mbd.TotalProcessorTime; Desc.Finished = mbd.Finished; lock (JobQueue) { ResultList.Add(new DataProcessingResult(Desc, null, MainForm.ResultLiveTime)); ExeList.Remove(Desc); Desc = null; } } milestone = "I"; } catch (SySal.DAQSystem.DataProcessingException retx) { lock (JobQueue) { ResultList.Add(new DataProcessingResult(Desc, retx, MainForm.ResultLiveTime)); ExeList.Remove(Desc); Desc = null; } } } catch (Exception x) { DPSW = null; MachinePowerClass = 0; try { EventLog.WriteEntry("Error handling batch " + Desc.Id.ToString("X16") + " - DPS: " + ServerName + "\r\nMilestone: " + milestone + "\r\n" + x.ToString(), System.Diagnostics.EventLogEntryType.Warning); } catch (Exception) { } lock (JobQueue) { ExeList.Remove(Desc); JobQueue.Add(Desc); Desc = null; } } } catch (Exception) { Desc = null; DPSW = null; MachinePowerClass = 0; } }