Example #1
0
        internal Dictionary <string, string> Initialize()
        {
            Dictionary <string, string> TaskAssemblyDict = new Dictionary <string, string>();
            string taskDir = Technisient.SamayEngine.EnsureFullPath(Settings.Default.TasksDirectory);

            if (!Directory.Exists(taskDir))
            {
                Directory.CreateDirectory(taskDir);
            }

            //cache all Tasks assembly names in the beginning.
            DirectoryInfo dI = new DirectoryInfo(taskDir);

            FileInfo[] files = dI.GetFiles("*.dll");

            AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve);

            foreach (FileInfo f in files)
            {
                try
                {
                    Assembly assembly = System.Reflection.Assembly.LoadFrom(f.FullName);
                    foreach (Type classType in assembly.GetTypes())
                    {
                        if (!classType.IsClass)
                        {
                            continue;
                        }

                        if (classType.BaseType.FullName == "Technisient.TaskBase")
                        {
                            TaskAssemblyDict.Add(classType.FullName, f.FullName);
                        }
                    }
                }
                catch (Exception ex)
                {
                    SamayLogger.LogError("Unable to Load Assembly: " + f.FullName + "\n" + ex.ToString(), SamayLogger.SamayEngineLogJobName, "Engine", SamayLogger.SamayEngineLoggingGUID, DateTime.Now);
                }
            }

            AppDomain.CurrentDomain.AssemblyResolve -= new ResolveEventHandler(CurrentDomain_AssemblyResolve);

            return(TaskAssemblyDict);
        }
Example #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
        }