Beispiel #1
0
		/// <summary>
		/// This method is called when the job is triggered to execute.
		/// </summary>
		/// <param name="jobContext"></param>
		public void Execute(IJobExecutionContext jobContext)
		{
			// Initialize and set context
			var dataMap = jobContext.MergedJobDataMap;
			var applicationContext = (MansionContext) dataMap["applicationContext"];
			var jobNode = (Node) dataMap["jobNode"];


			var typeService = applicationContext.Nucleus.ResolveSingle<ITypeService>();
			var type = typeService.Load(applicationContext, jobNode.Type);

			// get all tasks
			_queuedTaskDescriptors = type.GetDescriptors<RegisterTaskDescriptor>()
				.Select(descriptor => descriptor).ToList();

			// Save the current time as the last run of the current Job
			var context = new MansionContext(applicationContext.Nucleus);
			using (RepositoryUtil.Open(context))
			{
				var repository = context.Repository;
				repository.UpdateNode(context, jobNode, new PropertyBag
				{
					{"lastRun", DateTime.Now}
				});
			}

			// Start tasks that have no dependency on other tasks
			foreach (var taskDescriptor in _queuedTaskDescriptors
				.Select(descriptor => descriptor)
				.Where(descriptor => descriptor.TaskWaitsFor.IsNullOrWhiteSpace()))
			{
				var descriptor = taskDescriptor;
				System.Threading.Tasks.Task.Factory.StartNew(() => ExecuteTask(applicationContext, descriptor, jobNode));
			}
		}
Beispiel #2
0
		/// <summary>
		/// Start the given task
		/// </summary>
		/// <param name="applicationContext"></param>
		/// <param name="taskDescriptor"></param>
		/// <param name="jobNode"></param>
		private void ExecuteTask(IMansionContext applicationContext, RegisterTaskDescriptor taskDescriptor, Node jobNode)
		{
			// Initialize and set context
			var mailReportWhenFailed = jobNode.Get(applicationContext, "mailReportWhenFailed", false);
			var context = new MansionContext(applicationContext.Nucleus);
			var editProperties = new PropertyBag();
			var taskOutput = new StringBuilder();
			var taskType = taskDescriptor.TaskType;
			var task = (Task) Activator.CreateInstance(taskType);
			bool ranSuccessfully = false;

			using (RepositoryUtil.Open(context))
			{
				var taskStopwatch = new Stopwatch();
				try
				{
					// Execute the asynchronous task
					taskStopwatch.Start();
					var theActualTask = Task<bool>.Factory.StartNew(() => task.DoExecute(context, jobNode, ref taskOutput));
					System.Threading.Tasks.Task.Factory.ContinueWhenAll(new[] {theActualTask}, tasks => taskStopwatch.Stop());
					ranSuccessfully = theActualTask.Result;

					editProperties.Add(taskType.Name + ".exceptionThrown", false);

					if (!ranSuccessfully)
					{
						if (mailReportWhenFailed)
							SendErrorReportEmail(applicationContext, jobNode, taskType, task, taskOutput);
					}
				}
				catch (Exception e)
				{
					// Catch any exception that is thrown by the task and save it on the job node
					ranSuccessfully = false;
					editProperties.Add(taskType.Name + ".exceptionThrown", true);
					editProperties.Add(taskType.Name + ".exceptionMessage", e.InnerException.Message);

					if (mailReportWhenFailed)
						SendErrorReportEmail(applicationContext, jobNode, taskType, task, taskOutput, e.InnerException);
				}
				finally
				{
					// Update job node with task results
					editProperties.Add(taskType.Name + ".lastRunSuccessfull", ranSuccessfully);
					editProperties.Add(taskType.Name + ".lastRun", DateTime.Now);
					editProperties.Add(taskType.Name + ".lastDuration", taskStopwatch.Elapsed);
					editProperties.Add(taskType.Name + ".taskOutput", taskOutput);
					editProperties.Add("_scheduleStatusUpdate", taskOutput);

					lock (_jobLock)
					{
						var repository = context.Repository;
						repository.UpdateNode(context, jobNode, editProperties);
					}

					
					if (ranSuccessfully)
					{
						// Find out what tasks can be started next
						lock (_queueLock)
						{
							_queuedTaskDescriptors.Remove(taskDescriptor);
							_finishedTaskDescriptors.Add(taskDescriptor);

							// Only loop those tasks that have a dependency on the current task
							foreach (var descriptor in _queuedTaskDescriptors
								.Where(descriptor => !descriptor.TaskWaitsFor.IsNullOrWhiteSpace())
								.Where(descriptor => descriptor.TaskWaitsFor.Split(',')
									.Contains(taskDescriptor.TaskId.ToString(CultureInfo.InvariantCulture))))
							{
								var waitsFor = descriptor.TaskWaitsFor.Split(',');


								// Check if all other dependencies of the queued task are finished
								var allDependenciesFinished = waitsFor.All(waitFor => _finishedTaskDescriptors
									.Select(finishedDescriptor => finishedDescriptor)
									.Count(finishedDescriptor => finishedDescriptor.TaskId.ToString(CultureInfo.InvariantCulture).Equals(waitFor)) != 0);

								if (allDependenciesFinished)
									System.Threading.Tasks.Task.Factory.StartNew(() => ExecuteTask(applicationContext, descriptor, jobNode));
							}
						}
					}
				}
			}
			
		}