Пример #1
0
        /// <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;
            MThread mt      = new MThread(ds.TI);

            try
            {
                /// [email protected] - Feb 28, 2006:
                /// moved the thread status updating here from ManagerContainer.StartDispatch
                /// 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("Dispatching thread {0} to executor: {1}", ds.TI.ThreadId, ds.ExecutorId));

                // [email protected] - Jul 17, 2006: changed to parameterized thread start.
                ExecuteCurrentThreadParameters oParameters = new ExecuteCurrentThreadParameters(ds.TI, mt);
                Thread dispatchThread = new Thread(new ParameterizedThreadStart(this.ExecuteCurrentThread));
                dispatchThread.Name = "ScheduleDispatchThread";
                dispatchThread.Start(oParameters);

                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);
        }
Пример #2
0
        /// <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);
        }
Пример #3
0
        private void StartDispatch()
        {
            logger.Info("Dispatcher thread started.");
            try
            {
                // TODO: allow scheduling of multiple threads in one go
                while (!_stop)
                {
                    try
                    {
                        //logger.Debug("WaitOne for 1000 millis on DedicatedSchedulerActive");
                        InternalShared.Instance.DedicatedSchedulerActive.WaitOne(1000, false);

                        //logger.Debug("Getting a dedicated schedule");
                        DedicatedSchedule ds = InternalShared.Instance.Scheduler.ScheduleDedicated();

                        if (ds == null)
                        {
                            //to avoid blocking again if stop has been called.
                            if (!_stop)
                            {
                                InternalShared.Instance.DedicatedSchedulerActive.Reset();
                                //logger.Debug("Dedicated schedule is null. Reset the DedicatedSchedulerActive waithandle");
                            }
                        }
                        else
                        {
                            logger.Debug(String.Format("Scheduler mapped thread {0} to executor: {1}", ds.TI.ThreadId, ds.ExecutorId));
                            MExecutor me = new MExecutor(ds.ExecutorId);
                            try
                            {
                                // dispatch thread
                                me.ExecuteThread(ds);

                                /// [email protected] - Feb 28, 2006:
                                /// updating the thread's status is done inside ExecuteThread after it was decided
                                /// whether this executor can take it or not
                                /// this prevents race conditions if the Executor finishes very quickly
                                /// and we overwrite here the Executor's status back to Scheduled after it was finished
                                //		// update thread state 'after' it is dispatched. (kna changed this: aug19,05). to prevent the scheduler from hanging here.
                                //		mt.CurrentExecutorId = ds.ExecutorId;
                                //		mt.State = ThreadState.Scheduled;
                                //		logger.Debug("Scheduled thread " + ds.TI.ThreadId + " to executor:"+ds.ExecutorId);
                            }
                            catch (Exception e)
                            {
                                logger.Error("Some error occured trying to schedule. Reset-ing the thread to be scheduled. Continuing...", e);
                                MThread mt = new MThread(ds.TI);
                                mt.Reset(); // this should happen as part of the disconnection
                            }
                        }
                    }
                    catch (ThreadAbortException)
                    {
                        logger.Debug("Dispatcher Thread resetting abort (1)...");
                        Thread.ResetAbort();
                    }
                    catch (Exception e)
                    {
                        if (e is DbException)
                        {
                            //some problem contacting database
                            //wait for a bit and try again
                            logger.Debug("Error contacting database:", e);
                            Thread.Sleep(30000);
                            //TODO: need to provide fault tolerance here: what if the database/storage cannot be contacted.?
                            //TODO: in that case, just raise an event, and let the Service/exec deal with it.
                        }
                        else
                        {
                            logger.Error("Dispatch thread error. Continuing...", e);
                        }
                    }
                } //while
            }
            catch (ThreadAbortException)
            {
                logger.Debug("Scheduler Thread resetting abort (2)...");
                Thread.ResetAbort();
            }
            catch (Exception e)
            {
                logger.Error("StartDispatch thread error. Scheduler thread stopped.", e);
            }
            logger.Info("Scheduler thread exited.");
        }
Пример #4
0
        private void StartDispatch()
        {
            logger.Info("Dispatcher thread started.");
            try
            {
                // TODO: allow scheduling of multiple threads in one go
                while (!_stop)
                {
                    try
                    {
                        //logger.Debug("WaitOne for 1000 millis on DedicatedSchedulerActive");
                        InternalShared.Instance.DedicatedSchedulerActive.WaitOne(1000, false);

                        //logger.Debug("Getting a dedicated schedule");
                        DedicatedSchedule ds = InternalShared.Instance.Scheduler.ScheduleDedicated();

                        if (ds == null)
                        {
                            //to avoid blocking again if stop has been called.
                            if (!_stop)
                            {
                                InternalShared.Instance.DedicatedSchedulerActive.Reset();
                                //logger.Debug("Dedicated schedule is null. Reset the DedicatedSchedulerActive waithandle");
                            }
                        }
                        else
                        {
                            logger.Debug(String.Format("Scheduler mapped thread {0} to executor: {1}", ds.TI.ThreadId, ds.ExecutorId));
                            MExecutor me = new MExecutor(ds.ExecutorId);
                            try
                            {
                                // dispatch thread
                                me.ExecuteThread(ds);

                                /// [email protected] - Feb 28, 2006:
                                /// updating the thread's status is done inside ExecuteThread after it was decided
                                /// whether this executor can take it or not
                                /// this prevents race conditions if the Executor finishes very quickly
                                /// and we overwrite here the Executor's status back to Scheduled after it was finished
                                //		// update thread state 'after' it is dispatched. (kna changed this: aug19,05). to prevent the scheduler from hanging here.
                                //		mt.CurrentExecutorId = ds.ExecutorId;
                                //		mt.State = ThreadState.Scheduled;
                                //		logger.Debug("Scheduled thread " + ds.TI.ThreadId + " to executor:"+ds.ExecutorId);
                            }
                            catch (Exception e)
                            {
                                logger.Error("Some error occured trying to schedule. Reset-ing the thread to be scheduled. Continuing...", e);
                                MThread mt = new MThread(ds.TI);
                                mt.Reset(); // this should happen as part of the disconnection
                            }
                        }
                    }
                    catch (ThreadAbortException)
                    {
                        logger.Debug("Dispatcher Thread resetting abort (1)...");
                        Thread.ResetAbort();
                    }
                    catch (Exception e)
                    {
                        if (e is DbException)
                        {
                            //some problem contacting database
                            //wait for a bit and try again
                            logger.Debug("Error contacting database:", e);
                            Thread.Sleep(30000);
                            //TODO: need to provide fault tolerance here: what if the database/storage cannot be contacted.?
                            //TODO: in that case, just raise an event, and let the Service/exec deal with it.
                        }
                        else
                        {
                            logger.Error("Dispatch thread error. Continuing...", e);
                        }
                    }
                } //while
            }
            catch (ThreadAbortException)
            {
                logger.Debug("Scheduler Thread resetting abort (2)...");
                Thread.ResetAbort();
            }
            catch (Exception e)
            {
                logger.Error("StartDispatch thread error. Scheduler thread stopped.", e);
            }
            logger.Info("Scheduler thread exited.");
        }
Пример #5
0
        //-----------------------------------------------------------------------------------------------
        /// <summary>
        /// Gets the identifier of the  next scheduled thread.
        /// </summary>
        /// <param name="sc">security credentials to verify if the executor has permission to perform this operation 
        /// (i.e GetNextScheduledThreadIdentifier, which is associated with the ExecuteThread permission)</param>
        /// <param name="executorId">executor id</param>
        /// <returns>ThreadIdentifier object representing the next scheduled grid thread</returns>
        public ThreadIdentifier Executor_GetNextScheduledThreadIdentifier(SecurityCredentials sc, string executorId)
        {
            AuthenticateUser(sc);
            EnsurePermission(sc, Permission.ExecuteThread);

            bool scheduled = false;
            ThreadIdentifier ti;

            // critical section .. don't want to schedule same thread on multiple executors
            Monitor.Enter(InternalShared.Instance);

            //logger.Debug("Entering monitor...");
            // try and get a local thread
            ti = InternalShared.Instance.Scheduler.ScheduleNonDedicated(executorId);
            if (ti != null)
            {
                //logger.Debug("Schedule-non-dedicated gave Ti:"+ti.ThreadId);
                scheduled = true;
            }
            else
            {
                // no thread, so can release lock immediately
                Monitor.Exit(InternalShared.Instance);
                //logger.Debug("No thread. so releasing lock immediately.");
            }
            // TODO: hierarchical grids ignored until after v1.0.0
            /*
            else if ((ti == null) & (Manager != null))
            {
                // no local threads .. request thread from next manager and "simulate" the fact that it was scheduled locally
                ti = Manager.Executor_GetNextScheduledThreadIdentifier(null, _Id);

                if (ti != null)
                {
                    scheduled = true;
                    MThread t = new MThread(ti);
                    t.Init(false);
                    t.Priority = ti.Priority + 1;
                }
            }
            */

            if (scheduled)
            {
                logger.Debug("obtained thread..."+ti.ThreadId);
                MThread t = new MThread(ti);
                t.State = ThreadState.Scheduled;
                t.CurrentExecutorId = executorId;
                // finished scheduling thread, can release lock
                Monitor.Exit(InternalShared.Instance);
                logger.Debug("set state of thread to scheduled. set executorID for the thread. released lock");
            }

            return ti;
        }
Пример #6
0
 /// <summary>
 /// Constructor that takes the thread identifier and mthread.
 /// </summary>
 /// <param name="oThreadIdentifier">thread identifier parameter</param>
 /// <param name="oMThread">mthread parameter</param>
 public ExecuteCurrentThreadParameters(ThreadIdentifier oThreadIdentifier, MThread oMThread)
 {
     _ThreadIdentifier = oThreadIdentifier;
     _MThread          = oMThread;
 }
Пример #7
0
        /// <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;
        }