public void ConstructorTestDefaultPriority() { String applicationId = Guid.NewGuid().ToString(); Int32 threadId = 1234; ThreadIdentifier ti = new ThreadIdentifier(applicationId, threadId); Assert.AreEqual(applicationId, ti.ApplicationId); Assert.AreEqual(threadId, ti.ThreadId); Assert.AreEqual(ThreadIdentifier.DefaultPriority, ti.Priority); }
public void ConstructorTestSimepleConstructor() { String applicationId = Guid.NewGuid().ToString(); Int32 threadId = 1234; Int32 priority = 100; ThreadIdentifier ti = new ThreadIdentifier(applicationId, threadId, priority); Assert.AreEqual(applicationId, ti.ApplicationId); Assert.AreEqual(threadId, ti.ThreadId); Assert.AreEqual(priority, ti.Priority); }
//----------------------------------------------------------------------------------------------- /// <summary> /// Abort the given thread. /// </summary> /// <param name="ti">ThreadIdentifier object representing the GridThread to be aborted</param> public void Manager_AbortThread(ThreadIdentifier ti) { try { if (_ThreadExecutorThread!=null && _ThreadExecutorThread.IsAlive) { logger.Debug(string.Format("Starting to abort executor Thread: {0}:{1}", ti.ApplicationId, ti.ThreadId)); _ThreadExecutorThread.Abort(); logger.Debug("Waiting for thread to join:"+ti.ThreadId); _ThreadExecutorThread.Join(); logger.Debug(string.Format("Aborted Executor Thread: {0}:{1}", ti.ApplicationId, ti.ThreadId)); } else { logger.Debug(string.Format("AbortThread: Thread {0}:{1} not alive. Not doing anything.",ti.ApplicationId , ti.ThreadId)); } } catch (Exception e) { logger.Warn(string.Format("Error aborting thread: {0}:{1}. Continuing...", ti.ApplicationId, ti.ThreadId),e); } }
/// <summary> /// Queries the database to return the next dedicated schedule. /// </summary> /// <returns>DedicatedSchedule</returns> public DedicatedSchedule ScheduleDedicated() { ExecutorStorageView executorStorage = GetNextAvailableExecutor(); if (executorStorage == null) { return null; } ThreadStorageView threadStorage = GetNextAvailableThread(); if (threadStorage == null) { return null; } DedicatedSchedule dsched = null; string executorId = executorStorage.ExecutorId; string appid = threadStorage.ApplicationId; int threadId = threadStorage.ThreadId; int priority = threadStorage.Priority; // if (priority == -1) // { // priority = 5; //DEFAULT PRIORITY - TODO: have to put this in some Constants.cs file or something... // } ThreadIdentifier ti= new ThreadIdentifier(appid, threadId,priority); logger.Debug(String.Format("Schedule dedicated. app_id={0},threadID={1}, executor-id={2}", appid, threadId, executorId) ); dsched = new DedicatedSchedule(ti, executorId); return dsched; }
private void RelinquishIncompleteThreads() { if (_ActiveWorkers != null) { ThreadIdentifier[] keys = null; lock (_ActiveWorkers) { keys = new ThreadIdentifier[_ActiveWorkers.Keys.Count]; //since we remove it from the list in this method! //copy active worker 'keys' into another collection //to avoid concurrent modification exception _ActiveWorkers.Keys.CopyTo(keys, 0); } if (keys != null) { foreach (ThreadIdentifier ti in keys) { if (ti != null) { try { logger.Debug("Relinquishing incomplete thread:" + ti.UniqueId); Manager_AbortThread(ti); Manager.Executor_RelinquishThread(Credentials, ti); } catch (Exception ex) { logger.Warn("Error relinquishing thread : " + ti.UniqueId + ", " + ex.Message); } } } } } }
/// <summary> /// Abort the given thread. /// </summary> /// <param name="ti">ThreadIdentifier object representing the GridThread to be aborted</param> public void Manager_AbortThread(ThreadIdentifier ti) { if (_ActiveWorkers != null) { lock (_ActiveWorkers) { if (_ActiveWorkers.ContainsKey(ti)) { _ActiveWorkers[ti].Stop(); _ActiveWorkers.Remove(ti); } } } }
private void btnStop_Click(object sender, System.EventArgs e) { try { //try to stop the application. ThreadIdentifier ti = new ThreadIdentifier(_thread.ApplicationId, _thread.ThreadId); console.Manager.Owner_AbortThread(console.Credentials, ti); MessageBox.Show("Thread Aborted.","Applcation Properties",MessageBoxButtons.OK, MessageBoxIcon.Information); } catch (Exception ex) { if (ex is AuthorizationException) { MessageBox.Show("Access denied. You do not have adequate permissions for this operation.","Authorization Error",MessageBoxButtons.OK, MessageBoxIcon.Error); } else { logger.Error("Could not stop application. Error: "+ex.Message, ex); MessageBox.Show("Could not stop application. Error: "+ex.Message,"Console Error",MessageBoxButtons.OK,MessageBoxIcon.Error); } } }
//----------------------------------------------------------------------------------------------- /// <summary> /// Gets the exception that occured when the given thread was executing. /// </summary> /// <param name="sc">security credentials to verify if the owner has permission to perform this operation /// (i.e get failed thread exception, which is associated with the ManageOwnApp / ManageAllApps permission)</param> /// <param name="ti">ThreadIdentifier of the failed thread</param> /// <returns></returns> public Exception Owner_GetFailedThreadException(SecurityCredentials sc, ThreadIdentifier ti) { AuthenticateUser(sc); ApplicationAuthorizationCheck(sc, ti.ApplicationId); logger.Debug("Getting exception for thread:"+ti.ThreadId); return _Applications[ti.ApplicationId][ti.ThreadId].FailedThreadException; }
/// <summary> /// Gets the failed thread exception, given the thread identifier. /// </summary> /// <param name="manager">The manager.</param> /// <param name="sc">The security credentials.</param> /// <param name="ti">The thread identifier.</param> /// <returns></returns> public static string GetFailedThreadException(IManager manager, SecurityCredentials sc, ThreadIdentifier ti) { return manager.Owner_GetFailedThreadException(sc, ti).ToString(); }
/// <summary> /// Schedules a thread for the dedicated executors. /// </summary> /// <returns>thread identifier</returns> public DedicatedSchedule ScheduleDedicated() { lock (_Mapping) { _Mapping.Update(); IList cThreads = SortThreadsByPriority(GetThreads()); foreach (ThreadStorageView oThreadStorage in cThreads) { string strApplicationId = oThreadStorage.ApplicationId; string strExecutorId = GetNextExecutor(strApplicationId); if (strExecutorId != null) { int nThreadId = oThreadStorage.ThreadId; int nPriority = oThreadStorage.Priority; logger.Debug(String.Format("ScheduleDedicated; ApplicationId = {0}, ThreadId = {1}, ExecutorId = {2}", strApplicationId, nThreadId, strExecutorId)); ThreadIdentifier oThreadIdentifier = new ThreadIdentifier(strApplicationId, nThreadId, nPriority); return new DedicatedSchedule(oThreadIdentifier, strExecutorId); } } } return null; }
/// <summary> /// Initializes a set of threads and stores them into the database. /// </summary> /// <param name="sc">security credentials to verify if the owner has permission to perform this operation /// (i.e SetThread, which is associated with the ManageOwnApp permission)</param> /// <param name="ti">array of thread identifiers</param> /// <param name="threads">array of byte arrays representing the serialized threads</param> public void Owner_SetThreads(SecurityCredentials sc, ThreadIdentifier[] threadIds, byte[][] threads) { AuthenticateUser(sc); if (threadIds.Length > 0) { ApplicationAuthorizationCheck(sc, threadIds[0].ApplicationId); for (int i = 0; i < threadIds.Length; i++) { ThreadIdentifier thId = threadIds[i]; MThread t = _Applications[thId.ApplicationId][thId.ThreadId]; t.Value = threads[i]; //[thread number][serialized thread] t.Init(true); t.Priority = thId.Priority; logger.Debug("Initialised thread : " + thId.ThreadId); InternalShared.Instance.DedicatedSchedulerActive.Set(); } } }
/// <summary> /// Gets the exception that occured when the given thread was executing. /// </summary> /// <param name="sc">security credentials to verify if the owner has permission to perform this operation /// (i.e get failed thread exception, which is associated with the ManageOwnApp / ManageAllApps permission)</param> /// <param name="ti">ThreadIdentifier of the failed thread</param> /// <returns></returns> public Exception Owner_GetFailedThreadException(SecurityCredentials sc, ThreadIdentifier ti) { AuthenticateUser(sc); ApplicationAuthorizationCheck(sc, ti.ApplicationId); logger.Debug("Getting exception for thread:" + ti.ThreadId); Exception newEx = _Applications[ti.ApplicationId][ti.ThreadId].FailedThreadException; //wrap the exception if ( newEx != null && !(newEx is RemoteException)) newEx = new RemoteException(newEx.Message, newEx); if (newEx != null) return new RemoteException(newEx.Message, newEx); else return null; //return _Applications[ti.ApplicationId][ti.ThreadId].FailedThreadException; }
private void ExecuteThreadInAppDomain() { byte[] rawThread = null; try { logger.Info("Started ExecuteThreadInAppDomain..."); logger.Info(string.Format("executing grid thread # {0}.{1}", _CurTi.ApplicationId, _CurTi.ThreadId)); string appDir = GetApplicationDirectory(_CurTi.ApplicationId); logger.Debug("AppDir on executor=" + appDir); if (!_GridAppDomains.Contains(_CurTi.ApplicationId)) { lock(_GridAppDomains) { // make sure that by the time the lock was acquired the app domain is still not created if (!_GridAppDomains.Contains(_CurTi.ApplicationId)) { // create application domain for newly encountered grid application logger.Debug("app dir on executor: " + appDir); //before initializing clear dir.. foreach (string F in Directory.GetFiles(appDir)) { try //becoz exception should not be created for an issue as small as this { File.Delete(F); } catch (Exception ex) { } } FileDependencyCollection manifest = Manager.Executor_GetApplicationManifest(Credentials, _CurTi.ApplicationId); if (manifest != null) { foreach (FileDependency dep in manifest) { try //so that IO error does not occur if files already exist { logger.Debug("Unpacking file: " + dep.FileName + " to " + appDir); dep.UnPackToFolder(appDir); } catch (Exception ex) { } } } else { logger.Warn("Executor_GetApplicationManifest from the Manager returned null"); } initialize_GridThreadExecutor(); _GridAppDomains.Add( _CurTi.ApplicationId, new GridAppDomain(GridThreadApplicationDomain, GridThreadExecutor) ); logger.Info("Created app domain, policy, got instance of GridAppDomain and added to hashtable...all done once for this application"); } else { logger.Info("I got the lock but this app domain is already created."); } } } //get thread from manager GridAppDomain gad = (GridAppDomain) _GridAppDomains[_CurTi.ApplicationId]; //if we have an exception in the secondary appdomain, it will raise an exception in this method, since the cross-app-domain call //uses remoting internally, and it is just as if a remote method has caused an exception. we have a handler for that below anyway. rawThread = Manager.Executor_GetThread(Credentials, _CurTi); logger.Debug("Got thread from manager. executing it: "+_CurTi.ThreadId); //execute it byte[] finishedThread = gad.Executor.ExecuteThread(rawThread); logger.Info(string.Format("ExecuteThread returned for thread # {0}.{1}", _CurTi.ApplicationId, _CurTi.ThreadId)); //set its status to finished Manager.Executor_SetFinishedThread(Credentials, _CurTi, finishedThread, null); logger.Info(string.Format("Finished executing grid thread # {0}.{1}", _CurTi.ApplicationId, _CurTi.ThreadId)); } catch (ThreadAbortException) { if (_CurTi!=null) logger.Warn(string.Format("aborted grid thread # {0}.{1}", _CurTi.ApplicationId, _CurTi.ThreadId)); else logger.Warn(string.Format("aborted grid thread # {0}.{1}",null, null)); Thread.ResetAbort(); } catch (Exception e) { logger.Warn(string.Format("grid thread # {0}.{1} failed ({2})", _CurTi.ApplicationId, _CurTi.ThreadId, e.GetType()),e); try { //some exceptions such as Win32Exception caused problems when passed directly into this method. //so better create another new exception object and send it over. Exception eNew = new Exception(e.ToString()); Manager.Executor_SetFinishedThread(Credentials, _CurTi, rawThread, eNew); } catch (Exception ex1) { if (_CurTi!=null) { logger.Warn("Error trying to set failed thread for App: "+_CurTi.ApplicationId+", thread="+_CurTi.ThreadId + ". Original Exception = \n" + e.ToString(),ex1); } else { logger.Warn("Error trying to set failed thread: Original exception = " + e.ToString(), ex1); } } } finally { _CurTi = null; _ReadyToExecute.Set(); logger.Info("Exited ExecuteThreadInAppDomain..."); } }
//----------------------------------------------------------------------------------------------- //eduGRID Addition //written by Abhishek kumar dated March 5, 2007 //Reason: Inter process communication is not our concern here //we wish to allow communication bw the Gthread and //and the bot wrapper class that runs on executor node private void ExecuteThread() { byte[] rawThread = null; //this will contain the serialized Gthread logger.Info("Started ExecuteThread..."); try { //note: the above statement means that ibot will be initialized only when it //receives its first thread. this means that the response time for the first query //to this GExector will be high. //TODO: put initialize bot else where .. probably in constructor logger.Info("Bot is initialized."); //Get Thread rawThread = Manager.Executor_GetThread(Credentials, _CurTi); logger.Debug("Got thread from manager. executing it: " + _CurTi.ThreadId); //execute it byte[] thread = new byte[rawThread.Length]; rawThread.CopyTo(thread, 0); GThread gridThread = (GThread)Alchemi.Core.Utility.Utils.DeserializeFromByteArray(thread); logger.Debug("Executor running GThread: " + gridThread.Id); logger.Debug("Working dir=" + AppDomain.CurrentDomain.SetupInformation.PrivateBinPath); gridThread.SetWorkingDirectory(AppDomain.CurrentDomain.SetupInformation.PrivateBinPath); //eduGRID main link gridThread.SetiBOT(iBot); gridThread.Start(); logger.Debug("GThread " + gridThread.Id + " done. Serializing it to send back to the manager..."); byte[] finishedThread = Alchemi.Core.Utility.Utils.SerializeToByteArray(gridThread); //set its status to finished Manager.Executor_SetFinishedThread(Credentials, _CurTi, finishedThread, null); logger.Info(string.Format("Finished executing grid thread # {0}.{1}", _CurTi.ApplicationId, _CurTi.ThreadId)); } catch (ThreadAbortException) { if (_CurTi != null) logger.Warn(string.Format("aborted grid thread # {0}.{1}", _CurTi.ApplicationId, _CurTi.ThreadId)); else logger.Warn(string.Format("aborted grid thread # {0}.{1}", null, null)); Thread.ResetAbort(); } catch (Exception e) { logger.Warn(string.Format("grid thread # {0}.{1} failed ({2})", _CurTi.ApplicationId, _CurTi.ThreadId, e.GetType()), e); try { //some exceptions such as Win32Exception caused problems when passed directly into this method. //so better create another new exception object and send it over. Exception eNew = new Exception(e.ToString()); Manager.Executor_SetFinishedThread(Credentials, _CurTi, rawThread, eNew); } catch (Exception ex1) { if (_CurTi != null) { logger.Warn("Error trying to set failed thread for App: " + _CurTi.ApplicationId + ", thread=" + _CurTi.ThreadId + ". Original Exception = \n" + e.ToString(), ex1); } else { logger.Warn("Error trying to set failed thread: Original exception = " + e.ToString(), ex1); } } } finally { _CurTi = null; _ReadyToExecute.Set(); logger.Info("Exited ExecuteThread..."); } }
//----------------------------------------------------------------------------------------------- /// <summary> /// Executes the given thread /// </summary> /// <param name="ti">ThreadIdentifier representing the GridThread to be executed on this node.</param> public void Manager_ExecuteThread(ThreadIdentifier ti) { _ReadyToExecute.WaitOne(); _ReadyToExecute.Reset(); _CurTi = ti; //eduGRID modification: _ThreadExecutorThread = new Thread(new ThreadStart(ExecuteThreadInAppDomain)); _ThreadExecutorThread.Name = "ExecuteThreadInAppDomain-thread"; //_ThreadExecutorThread = new Thread(new ThreadStart(ExecuteThread)); //_ThreadExecutorThread.Name = "ExecuteThread-thread"; //end of edugrid modification _ThreadExecutorThread.Priority = ThreadPriority.Lowest; _ThreadExecutorThread.Start(); logger.Debug("Started thread for executing GridThread:"+ti.ThreadId); }
//----------------------------------------------------------------------------------------------- /// <summary> /// Executes a thread given to this manager by another manager above itself. /// This method is *NOT* implemented in the current version. /// An implementation is expected to be provided in a future version after v.1.0.0 /// </summary> /// <param name="ti">ThreadIdentifier of the thread to execute</param> public void Manager_ExecuteThread(ThreadIdentifier ti) { // TODO: hierarchical grids ignored until after v1.0.0 /* MThread t = _Applications[ti.ApplicationId][ti.ThreadId]; t.Init(false); t.Priority = ti.Priority + 1; InternalShared.Instance.DedicatedSchedulerActive.Set(); */ }
//----------------------------------------------------------------------------------------------- /// <summary> /// Aborts the thread. This is called by the owner of the thread. /// </summary> /// <param name="sc">security credentials to verify if the owner has permission to perform this operation /// (i.e abort thread, which is associated with the ManageOwnApp / ManageAllApps permission)</param> /// <param name="ti">ThreadIdentifier of the thread to abort</param> public void Owner_AbortThread(SecurityCredentials sc, ThreadIdentifier ti) { AuthenticateUser(sc); ApplicationAuthorizationCheck(sc, ti.ApplicationId); MThread thread = _Applications[ti.ApplicationId][ti.ThreadId]; logger.Debug("Owner called abort thread:"+ti.ThreadId); // if running on an executor, ask it to abort the thread if (thread.State != ThreadState.Dead && thread.State != ThreadState.Finished) { AbortThread(ti, thread.CurrentExecutorId); thread.State = ThreadState.Dead; } }
/// <summary> /// Aborts the job, given its ThreadIdentifier. /// </summary> /// <param name="manager">The manager.</param> /// <param name="sc">The security credentials.</param> /// <param name="ti">The thread identifier.</param> public static void AbortJob(IManager manager, SecurityCredentials sc, ThreadIdentifier ti) { manager.Owner_AbortThread(sc, ti); }
//----------------------------------------------------------------------------------------------- /// <summary> /// Gets the state of the given thread. /// </summary> /// <param name="sc">security credentials to verify if the owner has permission to perform this operation /// (i.e get thread state, which is associated with the ManageOwnApp / ManageAllApps permission)</param> /// <param name="ti">ThreadIdentifier of thread whose state is to be retrieved</param> /// <returns>state of the given thread</returns> public ThreadState Owner_GetThreadState(SecurityCredentials sc, ThreadIdentifier ti) { AuthenticateUser(sc); ApplicationAuthorizationCheck(sc, ti.ApplicationId); logger.Debug("Getting state for thread: "+ti.ThreadId); return _Applications[ti.ApplicationId][ti.ThreadId].State; }
//----------------------------------------------------------------------------------------------- /// <summary> /// Initializes a thread and stores it into the database. /// </summary> /// <param name="sc">security credentials to verify if the owner has permission to perform this operation /// (i.e SetThread, which is associated with the ManageOwnApp permission)</param> /// <param name="ti">ThreadIdentifier</param> /// <param name="thread">byte array representing the serialized thread</param> public void Owner_SetThread(SecurityCredentials sc, ThreadIdentifier ti, byte[] thread) { AuthenticateUser(sc); ApplicationAuthorizationCheck(sc, ti.ApplicationId); MThread t = _Applications[ti.ApplicationId][ti.ThreadId]; t.Value = thread; t.Init(true); t.Priority = ti.Priority; //?? logger.Debug("Initialised thread:"+ti.ThreadId ); InternalShared.Instance.DedicatedSchedulerActive.Set(); }
/// <summary> /// Creates a new instance of an MThread /// </summary> /// <param name="ti">ThreadIdentifier for this thread</param> public MThread(ThreadIdentifier ti) { _AppId = ti.ApplicationId; _Id = ti.ThreadId; }
//----------------------------------------------------------------------------------------------- /// <summary> /// Aborts the thread with the given id, on the given executor. /// </summary> /// <param name="ti">ThreadIdentifier</param> /// <param name="executorId">Executor id</param> internal static void AbortThread(ThreadIdentifier ti, string executorId) { if (executorId == null) { // not being executed on any executor logger.Debug(string.Format("Null executorID passed in to AbortThread: {0}:{1}. Not aborting...",ti.ApplicationId,ti.ThreadId)); return; } MExecutor me = new MExecutor(executorId); if (me.RemoteRef == null) { // not being executed on a dedicated executor .. so can't abort logger.Debug("AbortThread: not doing anything since the executor is not dedicated."); return; } try { logger.Debug("Aborting thread "+ ti.ThreadId +" on executor:"+executorId); me.RemoteRef.Manager_AbortThread(ti); logger.Debug("Aborting thread "+ ti.ThreadId +" on executor:"+executorId + ":: Complete."); } catch (ExecutorCommException ece) { logger.Error("ExecutorCommException...while aborting thread. Disconnecting executor...",ece); me.Disconnect(); } catch (Exception e) { logger.Debug("Exception aborting thread on executor : " + e.Message,e); } }
/// <summary> /// Executes the given thread /// </summary> /// <param name="ti">ThreadIdentifier representing the GridThread to be executed on this node.</param> public void Manager_ExecuteThread(ThreadIdentifier ti) { lock (_ActiveWorkers) { ExecutorWorker worker = null; if (_ActiveWorkers.ContainsKey(ti)) { //stop any existing instances of the user's thread worker = _ActiveWorkers[ti]; worker.Stop(); } worker = new ExecutorWorker(this, ti); _ActiveWorkers[ti] = worker; worker.Start(); } }
//----------------------------------------------------------------------------------------------- /// <summary> /// Gets the thread with the given identifier, as a byte array. /// This is called by a remote executor requesting a thread from the manager. /// </summary> /// <param name="sc">security credentials to verify if the executor has permission to perform this operation /// (i.e GetThread, which is associated with the ExecuteThread permission)</param> /// <param name="ti">ThreadIdentifier</param> /// <returns>A byte array representing the serialized thread</returns> public byte[] Executor_GetThread(SecurityCredentials sc, ThreadIdentifier ti) { AuthenticateUser(sc); EnsurePermission(sc, Permission.ExecuteThread); byte[] retval; MThread t = _Applications[ti.ApplicationId][ti.ThreadId]; // TODO: hierarchical grids ignored until after v1.0.0 //if (_Applications[ti.ApplicationId].IsPrimary) //{ retval = t.Value; //} //else //{ // retval = Manager.Executor_GetThread(null, ti); //} t.State = ThreadState.Started; logger.Debug("set thread status to started. returning the byte array:"+ti.ThreadId); return retval; }
/// <summary> /// Queries the database to return the next dedicated schedule. /// </summary> /// <returns>DedicatedSchedule</returns> public DedicatedSchedule ScheduleDedicated() { ExecutorStorageView executorStorage = GetNextAvailableExecutor(); if (executorStorage == null) { return null; } ThreadStorageView threadStorage = GetNextAvailableThread(); if (threadStorage == null) { return null; } DedicatedSchedule dsched = null; string executorId = executorStorage.ExecutorId; string appid = threadStorage.ApplicationId; int threadId = threadStorage.ThreadId; int priority = threadStorage.Priority; ThreadIdentifier ti = new ThreadIdentifier(appid, threadId, priority); dsched = new DedicatedSchedule(ti, executorId); return dsched; }
//----------------------------------------------------------------------------------------------- /// <summary> /// Resets a thread which is executing. /// </summary> /// <param name="sc">security credentials to verify if the executor has permission to perform this operation /// (i.e RelinquishThread, which is associated with the ExecuteThread permission)</param> /// <param name="ti">ThreadIdentifier of the thread to relinquish</param> public void Executor_RelinquishThread(SecurityCredentials sc, ThreadIdentifier ti) { AuthenticateUser(sc); EnsurePermission(sc, Permission.ExecuteThread); new MThread(ti).Reset(); logger.Debug("Reset thread: "+ti.ThreadId); }
/// <summary> /// Constructor with a threadIdentifier and executorId /// </summary> /// <param name="ti">ThreadIdentifier</param> /// <param name="executorId">Executor Id</param> public DedicatedSchedule(ThreadIdentifier ti, string executorId) { _ti = ti; _ExecutorId = executorId; }
//----------------------------------------------------------------------------------------------- /// <summary> /// Sets the given thread to a finished state. /// This is called by a remote executor after completing execution of this thread. /// The thread may be successfully finished or failed. /// </summary> /// <param name="sc">security credentials to verify if the executor has permission to perform this operation /// (i.e SetFinishedThread, which is associated with the ExecuteThread permission)</param> /// <param name="ti">ThreadIdentifier</param> /// <param name="thread">the byte array representing the serialized thread</param> /// <param name="e">Any exception that may have occured during the execution of the thread</param> public void Executor_SetFinishedThread(SecurityCredentials sc, ThreadIdentifier ti, byte[] thread, Exception e) { AuthenticateUser(sc); EnsurePermission(sc, Permission.ExecuteThread); MApplication app = _Applications[ti.ApplicationId]; MThread t = _Applications[ti.ApplicationId][ti.ThreadId]; if (app == null) { //invalid application id passed. normally this should not happen. throw new InvalidApplicationException("Invalid application id: "+ti.ApplicationId, null); } if (t == null) { //invalid thread id. this should normally not happen. throw new InvalidThreadException("Invalid thread id: "+ti.ApplicationId+":"+ti.ThreadId, null); } if (app.IsPrimary) { if (thread!=null) { try { t.Value = thread; } catch(Exception ex) { logger.Debug("Error saving thread to disk:"+ex.Message); //thread could not be saved to disk on the Manager //so set it as failed! //if e is not null, then let us get the exception which caused it to fail anyway. if (e==null) e = ex; } } if (e != null) { try { logger.Debug("thread failed. ti: " + ti.ThreadId + "," + e.Message); t.FailedThreadException = e; } catch (Exception ex) { logger.Debug("error saving thread-exception for failed thread to disk: threadId="+ti.ThreadId+", thread-fail-reason:" + e.Message, ex); } } else { logger.Debug("thread completed successfully. ti:"+ti.ThreadId ); } } else { // TODO: hierarchical grids ignored until after v1.0.0 //Manager.Executor_SetFinishedThread(null, ti, thread, e); } t.State = ThreadState.Finished; InternalShared.Instance.DedicatedSchedulerActive.Set(); logger.Debug("Set the thread ("+ti.ThreadId +") state to finished. And set the dedicatedSchedulerActive."); }
//----------------------------------------------------------------------------------------------- /// <summary> /// Aborts a thread given to this manager by another manager. /// This method is *NOT* implemented in the current version. /// An implementation is expected to be provided in a future version after v.1.0.0 /// </summary> /// <param name="ti">ThreadIdentifier</param> public void Manager_AbortThread(ThreadIdentifier ti) { // TODO: hierarchical grids ignored until after v1.0.0 logger.Debug("Manager_AbortThread called. NOT IMPLEMENTED IN THIS VERSION"); }
/// <summary> /// Execute a thread on a dedicated Executor. /// /// Right before the execution the thread's status is set the Scheduled /// and the thread's executor is set to the executor's ID. /// Spawn a new thread that remotes the execution to the Executor. /// /// </summary> /// <param name="ds">Containes the Thread ID and the Executor ID.</param> /// <returns>True if the thread was successfully started on the Executor.</returns> public bool ExecuteThread(DedicatedSchedule ds) { bool success = false; //kna added this to allow controlling MAX_CONCURRENT_THREADS per executor. Aug19. 05 //find # of executing threads from the db. int numConcurrentThreads = 0; MThread mt = new MThread(ds.TI); try { numConcurrentThreads = ManagerStorageFactory.ManagerStorage().GetExecutorThreadCount( _Id, ThreadState.Ready, ThreadState.Scheduled, ThreadState.Started); if (numConcurrentThreads >= MAX_CONCURRENT_THREADS) { success = false; } else { /// [email protected] - Feb 28, 2006: /// moved the thread status updating here from ManagerContainer.ScheduleDedicated /// to make sure that the thread state is written in the right order mt.CurrentExecutorId = ds.ExecutorId; mt.State = ThreadState.Scheduled; logger.Debug(String.Format("Scheduling thread {0} to executor: {1}", ds.TI.ThreadId, ds.ExecutorId)); this.currentTI = ds.TI; Thread dispatchThread = new Thread(new ThreadStart(this.ExecuteCurrentThread)); dispatchThread.Name = "ScheduleDispatchThread"; dispatchThread.Start(); success = true; } } catch (Exception ex) { // restore the thread status so another executor can pick it up mt.CurrentExecutorId = null; mt.State = ThreadState.Ready; logger.Debug("Error scheduling thread on executor "+ _Id, ex); } return success; }