internal static TaskBase CreateInstanceInAppDomain(string className, AppDomain jobDomain)
        {
            //try multiple times before giving up!
            for (int i = 0; i < 4; i++)
            {
                try
                {
                    return((TaskBase)Activator.CreateInstanceFrom(jobDomain, _TaskAssemblyDict[className], className).Unwrap());
                }
                catch (Exception ex)
                {
                    SamayLogger.LogWarning("Unable to create instance of " + className + " on Try " + i.ToString() + " Trying Again" + "\nERROR:" + ex.ToString(), SamayLogger.SamayEngineLogJobName, "Engine", SamayLogger.SamayEngineLoggingGUID, DateTime.Now);
                    System.Threading.Thread.Sleep(500);
                }
            }

            return((TaskBase)Activator.CreateInstanceFrom(jobDomain, _TaskAssemblyDict[className], className).Unwrap());
        }
Exemple #2
0
        private System.Threading.Tasks.Task ExecuteJob(Job job, JobSchedule schedule, long runCount)
        {
            //FUTURE: Spawn each Job out in a seperate exe?!
            //FUTURE: Send message to Tasks when stopped is recieve so that they can wrap up if they can
            TaskContext tc = new TaskContext();
            tc.jobName = job.JobName;
            tc.runCount = _currentlyRunningJobs[job.JobName + schedule.ID].count;
            tc.jobGUId = _currentlyRunningJobs[job.JobName + schedule.ID].jobGUID.ToString();
            tc.jobId = job.Id;

            //PLEASE ALWAYS MAKE IT EASY TO TURN OFF TASKS by using #defines as shown below
#if USETASKS
            System.Threading.Tasks.Task t = System.Threading.Tasks.Task.Factory.StartNew(() =>
#endif
            {
                AppDomain jobDomain = null;
                if (TASKS_IN_APPDOMAINS)
                {
                    System.AppDomainSetup appDomainSetup = new AppDomainSetup();
                    appDomainSetup.ShadowCopyFiles = "true";
                    appDomainSetup.ShadowCopyDirectories = _tasksFolder;
                    appDomainSetup.CachePath = _tasksFolder;

                    jobDomain = AppDomain.CreateDomain(Guid.NewGuid().ToString(),
                        new System.Security.Policy.Evidence(AppDomain.CurrentDomain.Evidence), appDomainSetup);
                }

                try
                {
                    object prevTaskOP = null;

                    foreach (Technisient.SamayConfig.Task task in job.TaskChain.Task)
                    {
                        if (_TaskAssemblyDict.ContainsKey(task.ClassName))
                        {
                            try
                            {
                                TaskBase TASK;
                                if (TASKS_IN_APPDOMAINS)
                                {
                                    TASK = CreateInstanceInAppDomain(task.ClassName, jobDomain);
                                }
                                else
                                {
                                    TASK = (TaskBase)CreateInstance(task.ClassName);
                                }
                                if (task.param != null)
                                    //     AssignParameters(TASK, task.param);
                                    TASK.AssignParameters(GetParameters(TASK, task.param));

                                tc.logLevel = task.LogLevel;
                                tc.taskId = task.Id;
                                TASK._taskContext = tc;

                                TASK.InitListener("net.pipe://localhost/SamayEngineListener");

                                SamayLogger.LogInfo("Running " + task.ClassName, job.JobName, task.ClassName, task.Id);

                                //FUTURE: Impersonation in config
                                if (task.RetryOnError == null)
                                {
                                    //try only once
                                    prevTaskOP = TASK.Run(prevTaskOP);
                                }
                                else
                                {
                                    bool ranSucessfully = false;
                                    for (int i = 0; i < task.RetryOnError.RetryTimes; i++)
                                    {
                                        #region RetryOnError

                                        try
                                        {
                                            prevTaskOP = TASK.Run(prevTaskOP);
                                            ranSucessfully = true;
                                            break;
                                        }
                                        catch (Exception ex)
                                        {
                                            SamayLogger.LogWarning("Failed Executing " + task.ClassName + " in Job " + job.JobName +
                                                " (Attempt " + (i + 1).ToString() + " of " + task.RetryOnError.RetryTimes.ToString() + ")\n" + ex.ToString(),
                                                job.JobName, task.ClassName, task.Id);
                                        }

                                        Thread.Sleep(task.RetryOnError.RetryDelay_msec);

                                        #endregion RetryOnError
                                    }
                                    if (!ranSucessfully)
                                        throw new Exception("Aborting Execution of " + task.ClassName + " in Job " + job.JobName + " (Attempts Failed = " + task.RetryOnError.RetryTimes.ToString() + ")");
                                }
                            }
                            catch (Exception ex)
                            {
                                SamayLogger.LogError("Aborting execution of the Task. " + ex.ToString(), job.JobName, task.ClassName, task.Id);
                                if (!job.TaskChain.ContinueOnError)
                                    break;
                            }
                        }
                        else
                        {
                            SamayLogger.LogError("Unable to find assembly for " + task.ClassName + ". Task cannot be executed!", job.JobName, task.ClassName, task.Id);
                            if (!job.TaskChain.ContinueOnError)
                                break;
                        }
                    }

#if ALLOW_CONCURRENT
                if (!job.AllowConcurrent)
                    lock (_currentlyRunningJobs)
                    {
                        _currentlyRunningJobs[job.JobName].jobChainBusy = false;
                    }
#endif
                }
                catch (Exception ex)
                {
                    SamayLogger.LogError(ex.ToString(), job.JobName, "Engine", job.Id);
                }
                finally
                {
                    if (TASKS_IN_APPDOMAINS)
                    {
                        AppDomain.Unload(jobDomain);
                    }
                }
            }

#if USETASKS
, TaskCreationOptions.LongRunning// | TaskCreationOptions.PreferFairness -- LOOKS GOOD WITHOUT USING FAIRNESS -- DONT USE
                /* Long-Running Tasks:
                 * You may want to explicitly prevent a task from being put on a local queue. For example, you may know that a
                 * particular work item will run for a relatively long time and is likely to block all other work items on
                 * the local queue. In this case, you can specify the LongRunning option, which provides a hint to the scheduler
                 * that an additional thread might be required for the task so that it does not block the forward progress of
                 * other threads or work items on the local queue. By using this option you avoid the ThreadPool completely,
                 * including the global and local queues.
                 * */
   );

            return t;
#else
            return null;
#endif
        }