Free cookie consent management tool by TermsFeed Policy Generator

source: branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Clients.Hive.Slave/3.3/Executor.cs @ 6725

Last change on this file since 6725 was 6725, checked in by ascheibe, 13 years ago

#1233 more renaming for more consistency

File size: 7.4 KB
RevLine 
[5105]1#region License Information
2/* HeuristicLab
[6371]3 * Copyright (C) 2002-2011 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
[5105]4 *
5 * This file is part of HeuristicLab.
6 *
7 * HeuristicLab is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * HeuristicLab is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
19 */
20#endregion
21
22using System;
[5782]23using System.Threading;
[6456]24using HeuristicLab.Clients.Hive.SlaveCore.Properties;
[5105]25using HeuristicLab.Common;
26using HeuristicLab.Core;
27using HeuristicLab.Hive;
28
[5599]29namespace HeuristicLab.Clients.Hive.SlaveCore {
[6371]30  /// <summary>
[6725]31  /// The executor runs in the appdomain and handles the execution of an Hive task.
[6371]32  /// </summary>
[5105]33  public class Executor : MarshalByRefObject, IDisposable {
[6725]34    private bool wasTaskAborted = false;
[6464]35    private AutoResetEvent pauseStopSem = new AutoResetEvent(false);
[6725]36    private AutoResetEvent startTaskSem = new AutoResetEvent(false); // block start method call
37    private AutoResetEvent taskStartedSem = new AutoResetEvent(false); // make pause or stop wait until start is finished
[6371]38    private ExecutorQueue executorQueue;
[6725]39    private bool taskDataInvalid = false; // if true, the jobdata is not sent when the task is failed
40    private ITask task;
[6419]41    private DateTime creationTime;
42
[6725]43    public Guid TaskId { get; set; }
[6419]44    public int CoresNeeded { get; set; }
45    public int MemoryNeeded { get; set; }
[6357]46    public bool IsStopping { get; set; }
47    public bool IsPausing { get; set; }
[6419]48
[6464]49    public Exception CurrentException;
50    public String CurrentExceptionStr {
[5105]51      get {
[6464]52        if (CurrentException != null) {
53          return CurrentException.ToString();
[5105]54        } else {
55          return string.Empty;
56        }
57      }
58    }
[5137]59
[6419]60    public ExecutorQueue ExecutorCommandQueue {
61      get { return executorQueue; }
62    }
63
[6371]64    private ExecutionState ExecutionState {
[6725]65      get { return task != null ? task.ExecutionState : HeuristicLab.Core.ExecutionState.Stopped; }
[5105]66    }
67
68    public TimeSpan ExecutionTime {
[6725]69      get { return task != null ? task.ExecutionTime : new TimeSpan(0, 0, 0); }
[5105]70    }
71
[6004]72    public Executor() {
[6357]73      IsStopping = false;
74      IsPausing = false;
[6203]75      executorQueue = new ExecutorQueue();
[6004]76    }
[5105]77
78    public void Start(byte[] serializedJob) {
79      try {
[6419]80        creationTime = DateTime.Now;
[6725]81        task = PersistenceUtil.Deserialize<ITask>(serializedJob);
[5105]82
83        RegisterJobEvents();
84
[6725]85        task.Start();
86        if (!startTaskSem.WaitOne(Settings.Default.ExecutorSemTimeouts)) {
87          taskDataInvalid = true;
88          throw new TimeoutException("Timeout when starting the task. TaskStarted event was not fired.");
[5105]89        }
90      }
91      catch (Exception e) {
[6464]92        this.CurrentException = e;
[6725]93        Task_TaskFailed(this, new EventArgs<Exception>(e));
[5105]94      }
[6464]95      finally {
[6725]96        taskStartedSem.Set();
[6464]97      }
[5105]98    }
99
[5314]100    public void Pause() {
[6357]101      IsPausing = true;
[6725]102      // wait until task is started. if this does not happen, the Task is null an we give up
103      taskStartedSem.WaitOne(Settings.Default.ExecutorSemTimeouts);
104      if (task == null) {
105        CurrentException = new Exception("Pausing task " + this.TaskId + ": Task is null");
[6464]106        executorQueue.AddMessage(ExecutorMessageType.ExceptionOccured);
[6203]107        return;
[5782]108      }
[5469]109
[6725]110      if (task.ExecutionState == ExecutionState.Started) {
[5782]111        try {
[6725]112          task.Pause();
[5782]113          //we need to block the pause...
114          pauseStopSem.WaitOne();
115        }
116        catch (Exception ex) {
[6725]117          CurrentException = new Exception("Error pausing task " + this.TaskId + ": " + ex.ToString());
[6464]118          executorQueue.AddMessage(ExecutorMessageType.ExceptionOccured);
[5782]119        }
120      }
[5314]121    }
122
[5450]123    public void Stop() {
[6357]124      IsStopping = true;
[6725]125      // wait until task is started. if this does not happen, the Task is null an we give up
126      taskStartedSem.WaitOne(Settings.Default.ExecutorSemTimeouts);
127      if (task == null) {
128        CurrentException = new Exception("Stopping task " + this.TaskId + ": Task is null");
[6464]129        executorQueue.AddMessage(ExecutorMessageType.ExceptionOccured);
[5782]130      }
[6725]131      wasTaskAborted = true;
[5782]132
[5105]133      if ((ExecutionState == ExecutionState.Started) || (ExecutionState == ExecutionState.Paused)) {
[5782]134        try {
[6725]135          task.Stop();
[5782]136          pauseStopSem.WaitOne();
137        }
138        catch (Exception ex) {
[6725]139          CurrentException = new Exception("Error stopping task " + this.TaskId + ": " + ex.ToString());
[6464]140          executorQueue.AddMessage(ExecutorMessageType.ExceptionOccured);
[5782]141        }
[5105]142      }
143    }
144
145    private void RegisterJobEvents() {
[6725]146      task.TaskStopped += new EventHandler(Task_TaskStopped);
147      task.TaskFailed += new EventHandler(Task_TaskFailed);
148      task.TaskPaused += new EventHandler(Task_TaskPaused);
149      task.TaskStarted += new EventHandler(Task_TaskStarted);
[5105]150    }
151
152    private void DeregisterJobEvents() {
[6725]153      task.TaskStopped -= new EventHandler(Task_TaskStopped);
154      task.TaskFailed -= new EventHandler(Task_TaskFailed);
155      task.TaskPaused -= new EventHandler(Task_TaskPaused);
156      task.TaskStarted -= new EventHandler(Task_TaskStarted);
[5105]157    }
158
[6721]159    #region Task Events
[6725]160    private void Task_TaskFailed(object sender, EventArgs e) {
[6381]161      IsStopping = true;
[6357]162      EventArgs<Exception> ex = (EventArgs<Exception>)e;
[6464]163      CurrentException = ex.Value;
[6725]164      executorQueue.AddMessage(ExecutorMessageType.TaskFailed);
[5105]165    }
166
[6725]167    private void Task_TaskStopped(object sender, EventArgs e) {
[6381]168      IsStopping = true;
[6725]169      if (wasTaskAborted) {
[6464]170        pauseStopSem.Set();
171      }
[6725]172      executorQueue.AddMessage(ExecutorMessageType.TaskStopped);
[5778]173    }
174
[6725]175    private void Task_TaskPaused(object sender, EventArgs e) {
[6381]176      IsPausing = true;
[6464]177      pauseStopSem.Set();
[6725]178      executorQueue.AddMessage(ExecutorMessageType.TaskPaused);
[5782]179    }
180
[6725]181    private void Task_TaskStarted(object sender, EventArgs e) {
182      startTaskSem.Set();
183      executorQueue.AddMessage(ExecutorMessageType.TaskStarted);
[6112]184    }
[6357]185    #endregion
[6112]186
[6725]187    public TaskData GetTaskData() {
188      if (taskDataInvalid) return null;
[6419]189
[6725]190      if (task.ExecutionState == ExecutionState.Started) {
[6721]191        throw new InvalidStateException("Task is still running");
[5105]192      } else {
[6725]193        TaskData taskData = new TaskData();
194        if (task == null) {
195          //send empty task and save exception
196          taskData.Data = PersistenceUtil.Serialize(new TaskData());
[6464]197          if (CurrentException == null) {
[6725]198            CurrentException = new Exception("Task with id " + this.TaskId + " is null, sending empty task");
[6203]199          }
200        } else {
[6725]201          taskData.Data = PersistenceUtil.Serialize(task);
[6203]202        }
[6725]203        taskData.TaskId = TaskId;
204        return taskData;
[5105]205      }
[5137]206    }
207
[5105]208    public void Dispose() {
[6725]209      if (task != null)
[5105]210        DeregisterJobEvents();
[6725]211      task = null;
[5105]212    }
213  }
214}
Note: See TracBrowser for help on using the repository browser.