private void FuncThreadCancelSession(object context) { LaunchSessionThreadInfo info; info = (LaunchSessionThreadInfo)context; int sessionID; sessionID = info.SessionID; XORCISMEntities model = new XORCISMEntities(); SESSION session; session = model.SESSION.SingleOrDefault(o => o.SessionID == sessionID); //int accountID; //accountID = (int)model.USERACCOUNT.FirstOrDefault(o => o.UserID == session.UserID).AccountID; // ============================= // Cancel the jobs on the agents // ============================= Utils.Helper_Trace("MANAGER ENGINE", string.Format("SESSION {0} : THREADCANCELSESSION : Cancelling jobs on agents", sessionID)); foreach (JOB J in info.ListJob) { Utils.Helper_Trace("MANAGER ENGINE", string.Format("SESSION {0} : THREADCANCELSESSION : Handling job {1}", sessionID, J.JobID)); // ==================================== // Contact the agent and cancel the job // ==================================== Utils.Helper_Trace("MANAGER ENGINE", string.Format("SESSION {0} : THREADCANCELSESSION : Trying to contact the agent", sessionID)); try { ServiceReferenceAgent.Service1Client service; service = new ServiceReferenceAgent.Service1Client(); // TODO : // service.Endpoint.Address = bestAgent.IPAddress; service.CancelJob(J.JobID); } catch (Exception ex) { Utils.Helper_Trace("MANAGER ENGINE", string.Format("SESSION {0} : THREADCANCELSESSION : Error contacting the agent. Exception = {1} {2}", sessionID, ex.Message, ex.InnerException)); //HARDCODED XCommon.Utils.Helper_SendEmail("*****@*****.**", "MANAGER ENGINE ERROR", "THREADCANCELSESSION : Error contacting the agent. Exception =" + ex.Message + " " + ex.InnerException); return; } Utils.Helper_Trace("MANAGER ENGINE", string.Format("SESSION {0} : THREADCANCELSESSION : The agent has been successfully contacted", sessionID)); } // ============================= // Update table SESSION (Status) // ============================= Utils.Helper_Trace("MANAGER ENGINE", string.Format("SESSION {0} : THREADCANCELSESSION : Updating status in table SESSION to CANCELED", sessionID)); var mySession = from Sess in model.SESSION where Sess.SessionID == sessionID select Sess; SESSION MySession = mySession.ToList().First(); MySession.Status = XCommon.STATUS.CANCELED.ToString(); MySession.DateEnd = DateTimeOffset.Now; model.SaveChanges(); try { m_ListRunningSessionThread.Remove(sessionID); } catch (Exception ex) { Utils.Helper_Trace("MANAGER ENGINE", string.Format("SESSION {0} : THREADCANCELSESSION : Error m_ListRunningSessionThread.Remove. Exception = {1}", sessionID, ex.Message)); return; } Utils.Helper_Trace("MANAGER ENGINE", string.Format("SESSION {0} : THREADCANCELSESSION : Finished", sessionID)); }
private void FuncThread() { XORCISMEntities context; context = new XORCISMEntities(); // Explicitly open the connection. //context.Connection.Open(); // ================= // Main polling loop // ================= try { while (true) //Infinite loop { // ============================================================================= // PHASE 0 : Look in table SESSION and let's see if there is something to cancel // ============================================================================= #region Phase0 //Utils.Helper_Trace("MANAGER ENGINE", "Looking for new session to cancel (those with status = 'ToCancel')"); string status; status = XCommon.STATUS.TOCANCEL.ToString(); XORCISMModel.SESSION cancelSession; cancelSession = context.SESSION.FirstOrDefault(s => s.Status == status); if (cancelSession != null) { // =============================== // Abort the Launch Session thread // =============================== if (m_ListRunningSessionThread.ContainsKey(cancelSession.SessionID) == true) { LaunchSessionThreadInfo info; info = m_ListRunningSessionThread[cancelSession.SessionID]; Thread musCanceledThread; musCanceledThread = info.Thread; musCanceledThread.Abort(cancelSession.SessionID.ToString()); // ============================== // Launch a Cancel Session thread // ============================== Utils.Helper_Trace("MANAGER ENGINE", string.Format("Launching cancel session thread (sessionID={0})", cancelSession.SessionID)); cancelSession.Status = XCommon.STATUS.CANCELLING.ToString(); context.SaveChanges(); ParameterizedThreadStart ts; ts = new ParameterizedThreadStart(FuncThreadCancelSession); Thread thread; thread = new Thread(ts); thread.Start(info); } else { //Canceling after Manager crash/reboot //Session is not in m_ListRunningSessionThread Utils.Helper_Trace("MANAGER ENGINE", string.Format("Session {0} must be canceled", cancelSession.SessionID)); //int accountID; //accountID = (int)model.USERACCOUNT.FirstOrDefault(o => o.UserID == session.UserID).AccountID; // ============================= // Cancel the jobs on the agents // ============================= Utils.Helper_Trace("MANAGER ENGINE", string.Format("SESSION {0} : CANCELSESSION : Cancelling jobs on agents", cancelSession.SessionID)); var jobs = from jc in context.JOB where jc.SessionID == cancelSession.SessionID select jc; foreach (JOB J in jobs.ToList()) { Utils.Helper_Trace("MANAGER ENGINE", string.Format("SESSION {0} : CANCELSESSION : Handling job {1}", cancelSession.SessionID, J.JobID)); // ==================================== // Contact the agent and cancel the job // ==================================== Utils.Helper_Trace("MANAGER ENGINE", string.Format("SESSION {0} : CANCELSESSION : Trying to contact the agent", cancelSession.SessionID)); try { ServiceReferenceAgent.Service1Client service; service = new ServiceReferenceAgent.Service1Client(); // TODO : // service.Endpoint.Address = bestAgent.IPAddress; service.CancelJob(J.JobID); Utils.Helper_Trace("MANAGER ENGINE", string.Format("SESSION {0} : CANCELSESSION : The agent has been successfully contacted", cancelSession.SessionID)); } catch (Exception ex) { Utils.Helper_Trace("MANAGER ENGINE", string.Format("SESSION {0} : CANCELSESSION : Error contacting the agent. Exception = {1} {2}", cancelSession.SessionID, ex.Message, ex.InnerException)); XCommon.Utils.Helper_SendEmail("*****@*****.**", "MANAGER ENGINE ERROR", "CANCELSESSION : Error contacting the agent. Exception =" + ex.Message + " " + ex.InnerException); //return; } } // ============================= // Update table SESSION (Status) // ============================= Utils.Helper_Trace("MANAGER ENGINE", string.Format("SESSION {0} : CANCELSESSION : Updating status in table SESSION to CANCELED", cancelSession.SessionID)); try { cancelSession.Status = XCommon.STATUS.CANCELED.ToString(); cancelSession.DateEnd = DateTimeOffset.Now; context.SaveChanges(); } catch (Exception ex) { Utils.Helper_Trace("MANAGER ENGINE", string.Format("SESSION {0} : CANCELSESSION : Error CANCELED. Exception = {1}", cancelSession.SessionID, ex.Message)); //return; } Utils.Helper_Trace("MANAGER ENGINE", string.Format("SESSION {0} : CANCELSESSION : Finished", cancelSession.SessionID)); } } #endregion Phase0 // ============================================================================= // PHASE 1 : Look in table SESSION and let's see if there is something to launch // ============================================================================= Utils.Helper_Trace("MANAGER ENGINE", "Looking for new session to start (status IDLE)"); //DO NOT COMMENT THIS LINE string Statut = XCommon.STATUS.IDLE.ToString(); var session = context.SESSION.FirstOrDefault(s => s.Status == Statut); if (session != null) { int sessionID; sessionID = session.SessionID; //Check if the Account and User are still valid USERACCOUNT user = null; user = context.USERACCOUNT.SingleOrDefault(o => o.UserID == session.UserID); if (user.ACCOUNT.ValidUntilDate != null && user.ACCOUNT.ValidUntilDate < DateTimeOffset.Now) { Utils.Helper_Trace("MANAGER ENGINE", string.Format("Account not valid for session {0}", sessionID)); Utils.Helper_Trace("MANAGER ENGINE", string.Format("Changing session (sessionID={0}) to CANCELED", sessionID)); session.Status = XCommon.STATUS.CANCELED.ToString(); context.SaveChanges(); } else { if (m_ListRunningSessionThread.ContainsKey(sessionID) == true) { Utils.Helper_Trace("MANAGER ENGINE", string.Format("Session {0} is supposed to be launched but a thread is already running for this session !", sessionID)); } else { // ======================= // Launch a session thread // ======================= Utils.Helper_Trace("MANAGER ENGINE", string.Format("Launching session (sessionID={0})", sessionID)); session.Status = XCommon.STATUS.RUNNING.ToString(); context.SaveChanges(); ParameterizedThreadStart managerThreadStart; managerThreadStart = new ParameterizedThreadStart(FuncThreadLaunchSession); Thread thread; thread = new Thread(managerThreadStart); LaunchSessionThreadInfo info; info = new LaunchSessionThreadInfo(sessionID, thread); thread.Start(info); // ======================== // Put it in the dictionary // ======================== m_ListRunningSessionThread.Add(sessionID, info); } } } // =================================================================================== // PHASE 2 : Look in table SESSIONCRON and let's see if we have to create new sessions // =================================================================================== Statut = XCommon.STATUS.IDLE.ToString(); var q = context.SESSIONCRON.Where(o => o.Status == Statut); foreach (SESSIONCRON sessionCron in q.ToList()) { if (sessionCron.DateEnd == null || sessionCron.DateEnd > DateTime.Now) { //Check if the Account and User are still valid USERACCOUNT user = null; user = context.USERACCOUNT.SingleOrDefault(o => o.UserID == sessionCron.UserID); if (user.ACCOUNT.ValidUntilDate != null && user.ACCOUNT.ValidUntilDate < DateTimeOffset.Now) { //Utils.Helper_Trace("MANAGER ENGINE", string.Format("Account not valid for entry {0} in table SESSIONCRON", sessionCron.SessionCronID)); } else { CrontabSchedule schedule; schedule = CrontabSchedule.Parse(sessionCron.CronExpression); DateTimeOffset start = DateTimeOffset.Now; DateTimeOffset end = start + TimeSpan.FromDays(2 * 360); var occurrence = schedule.GetNextOccurrences(start, end).GetEnumerator(); occurrence.MoveNext(); // Utils.Helper_Trace("MANAGER ENGINE", "SessionCron "+sessionCron.SessionCronID+" Next occurrence=" + occurrence.Current.DayOfWeek.ToString() + " " + occurrence.Current.Day.ToString() + "/" + occurrence.Current.Month.ToString() + "/" + occurrence.Current.Year.ToString() + " " + occurrence.Current.Hour.ToString() + "H" + occurrence.Current.Minute.ToString() + ":" + occurrence.Current.Second.ToString()); TimeSpan ts; ts = occurrence.Current - start; if (ts.TotalSeconds <= 5.0) { Utils.Helper_Trace("MANAGER ENGINE", string.Format("Cron expression for entry {0} in table SESSIONCRON has triggered an execution", sessionCron.SessionCronID)); // ================================ // Extract and parse the parameters // ================================ Dictionary <string, object> dicoParameters; try { MemoryStream ms; ms = new MemoryStream(sessionCron.Parameters); BinaryFormatter bf; bf = new BinaryFormatter(); dicoParameters = (Dictionary <string, object>)bf.Deserialize(ms); } catch (Exception e) { Utils.Helper_Trace("MANAGER SERVICE", string.Format("Exception while deserializing parameters : {0}", e.Message)); return; } int[] tabAssetID = null; if (dicoParameters["ASSETS"] != null) { tabAssetID = (int[])dicoParameters["ASSETS"]; } // ================================ // Add a new entry in table SESSION // ================================ Utils.Helper_Trace("MANAGER ENGINE", string.Format("Adding an entry in table SESSION")); SESSION tmpSession = new SESSION(); //xxx try { tmpSession.UserID = sessionCron.UserID; tmpSession.Status = XCommon.STATUS.IDLE.ToString(); tmpSession.ServiceCategoryID = sessionCron.ServiceCategoryID; tmpSession.DateStart = DateTimeOffset.Now; tmpSession.DateEnd = null; tmpSession.Parameters = sessionCron.Parameters; tmpSession.SessionCronID = sessionCron.SessionCronID; context.SESSION.Add(tmpSession); context.SaveChanges(); //xxx } catch (Exception ex) { //xxx Utils.Helper_Trace("MANAGER ENGINE", string.Format("Error adding entry in table SESSION : Exception = {0} - {1}", ex.Message, ex.InnerException.Message)); throw ex; } Utils.Helper_Trace("MANAGER ENGINE", string.Format("SessionID = {0}", tmpSession.SessionID)); // ============================================ // Add several entries in table ASSETSESSION // ============================================ if (tabAssetID != null) { Utils.Helper_Trace("MANAGER ENGINE", string.Format("Adding {0} entries in table ASSETSESSION", tabAssetID.Count())); try { foreach (int assetID in tabAssetID) { ASSETSESSION tmpAinS = new ASSETSESSION(); tmpAinS.SESSION = tmpSession; tmpAinS.AssetID = assetID; context.ASSETSESSION.Add(tmpAinS); } context.SaveChanges(); } catch (Exception ex) { Utils.Helper_Trace("MANAGER ENGINE", string.Format("Error adding entries in table ASSETSESSION : Exception = {0}", ex.Message)); throw ex; } } } } } } // ===== // Sleep // ===== Thread.Sleep(5000); //Hardcoded } } catch (ThreadAbortException exThreadAbort) { //int SessionId; //SessionId=Convert.ToInt32((string)exThreadAbort.ExceptionState); //XORCISMModel.SESSION musBeCanceledSession; //musBeCanceledSession=context.SESSION.SingleOrDefault(s => s.SessionID == SessionId); //if (musBeCanceledSession != null) //{ // musBeCanceledSession.Status = XCommon.STATUS.TOCANCEL.ToString(); // context.SaveChanges(); //} Utils.Helper_Trace("MANAGER ENGINE", string.Format("ThreadError in main polling loop : Exception = {0}", exThreadAbort.Message)); //HARDCODED XCommon.Utils.Helper_SendEmail("*****@*****.**", "ThreadError in XManager", "MyException = " + exThreadAbort.Message + " " + exThreadAbort.InnerException); return; } catch (Exception ex) { Utils.Helper_Trace("MANAGER ENGINE", string.Format("Error in main polling loop : Exception = {0} {1}", ex.Message, ex.InnerException)); //HARDCODED XCommon.Utils.Helper_SendEmail("*****@*****.**", "Error in XManager", "MyException = " + ex.Message + " " + ex.InnerException); return; } }