Free cookie consent management tool by TermsFeed Policy Generator

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

Last change on this file since 5789 was 5789, checked in by ascheibe, 14 years ago

#1233

  • added autostart for tray icon to installer
  • machine unique id now includes the machine name
  • core: check if job already exists on slave
  • already finished jobs now fail and are sent back
File size: 7.8 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2010 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
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;
23using System.Collections.Generic;
24using System.Linq;
25using System.Threading;
26using HeuristicLab.Common;
27using HeuristicLab.Core;
28using HeuristicLab.Hive;
29using HeuristicLab.PluginInfrastructure;
30
31
32namespace HeuristicLab.Clients.Hive.SlaveCore {
33  public class Executor : MarshalByRefObject, IDisposable {
34    public Guid JobId { get; set; }
35    public IJob Job { get; set; }
36    private bool wasJobAborted = false;
37    public Core Core { get; set; }
38    private Semaphore pauseStopSem = new Semaphore(0, 1);
39
40    private Exception currentException;
41    public String CurrentException {
42      get {
43        if (currentException != null) {
44          return currentException.ToString();
45        } else {
46          return string.Empty;
47        }
48      }
49    }
50
51    public ExecutionState ExecutionState {
52      get {
53        return Job != null ? Job.ExecutionState : HeuristicLab.Core.ExecutionState.Stopped;
54      }
55    }
56
57    public TimeSpan ExecutionTime {
58      get {
59        return Job != null ? Job.ExecutionTime : new TimeSpan(0, 0, 0);
60      }
61    }
62
63    public DateTime CreationTime { get; set; }
64
65    /// <param name="serializedJob"></param>
66    /// <param name="collectChildJobs">if true, all child-jobs are downloaded and the job will be resumed.</param>
67    public void Start(byte[] serializedJob) {
68      try {
69        CreationTime = DateTime.Now;
70        Job = PersistenceUtil.Deserialize<IJob>(serializedJob);
71
72        RegisterJobEvents();
73
74        if (Job.CollectChildJobs) {
75          IEnumerable<JobData> childjobs = WcfService.Instance.GetChildJobs(JobId);
76          Job.Resume(childjobs.Select(j => PersistenceUtil.Deserialize<IJob>(j.Data)));
77        } else {
78          Job.Prepare();
79          Job.Start();
80        }
81      }
82      catch (Exception e) {
83        this.currentException = e;
84        Job_JobFailed(this, new HeuristicLab.Common.EventArgs<Exception>(e));
85      }
86    }
87
88    public void Pause() {
89      if (Job == null) {
90        throw new InvalidStateException("Job is null");
91      }
92
93      if (Job.ExecutionState == HeuristicLab.Core.ExecutionState.Started) {
94        try {
95          Job.Pause();
96          //we need to block the pause...
97          pauseStopSem.WaitOne();
98        }
99        catch (Exception ex) {
100          SlaveClientCom.Instance.ClientCom.LogMessage("Error pausing job:" + ex.ToString());
101        }
102      }
103    }
104
105    public void Stop() {
106      if (Job == null) {
107        throw new InvalidStateException("Job is null");
108      }
109      wasJobAborted = true;
110
111      if ((ExecutionState == ExecutionState.Started) || (ExecutionState == ExecutionState.Paused)) {
112        try {
113          Job.Stop();
114          pauseStopSem.WaitOne();
115        }
116        catch (Exception ex) {
117          SlaveClientCom.Instance.ClientCom.LogMessage("Error stopping job:" + ex.ToString());
118        }
119      }
120    }
121
122    private void RegisterJobEvents() {
123      Job.JobStopped += new EventHandler(Job_JobStopped);
124      Job.JobFailed += new EventHandler(Job_JobFailed);
125      Job.NewChildJob += new EventHandler<EventArgs<IJob>>(Job_NewChildJob);
126      Job.WaitForChildJobs += new EventHandler(Job_WaitForChildJobs);
127      Job.DeleteChildJobs += new EventHandler(Job_DeleteChildJobs);
128      Job.JobPaused += new EventHandler(Job_JobPaused);
129    }
130
131    private void DeregisterJobEvents() {
132      Job.JobStopped -= new EventHandler(Job_JobStopped);
133      Job.JobFailed -= new EventHandler(Job_JobFailed);
134      Job.NewChildJob -= new EventHandler<EventArgs<IJob>>(Job_NewChildJob);
135      Job.WaitForChildJobs -= new EventHandler(Job_WaitForChildJobs);
136      Job.DeleteChildJobs -= new EventHandler(Job_DeleteChildJobs);
137      Job.JobPaused -= new EventHandler(Job_JobPaused);
138    }
139
140    private List<Guid> FindPluginsNeeded(IJob obj) {
141      List<Guid> guids = new List<Guid>();
142      foreach (IPluginDescription desc in PluginUtil.GetDeclaringPlugins(obj)) {
143      }
144      throw new NotImplementedException("FindPluginsNeeded for Job_NewChildJob");
145
146      return guids;
147    }
148
149    private void Job_NewChildJob(object sender, EventArgs<IJob> e) {
150      JobData childJobData = new JobData();
151      childJobData.Data = PersistenceUtil.Serialize(e.Value);
152
153      Job childJob = new Job();
154      childJob.CoresNeeded = 1;
155      childJob.MemoryNeeded = 0;
156      childJob.PluginsNeededIds = FindPluginsNeeded(e.Value);
157
158      //TODO: is return value needed?
159      WcfService.Instance.AddChildJob(this.JobId, childJob, childJobData);
160    }
161
162    private void Job_WaitForChildJobs(object sender, EventArgs e) {
163      // Pause the job and send it back to the hive. The server will awake it when all child-jobs are finished
164      this.Job.CollectChildJobs = true;
165
166      JobData jdata = new JobData();
167      jdata.Data = PersistenceUtil.Serialize(Job);
168      jdata.JobId = this.JobId;
169
170      Core.PauseWaitJob(jdata);
171    }
172
173    private void Job_DeleteChildJobs(object sender, EventArgs e) {
174      WcfService.Instance.DeleteChildJobs(JobId);
175    }
176
177    private void Job_JobFailed(object sender, EventArgs e) {
178      //TODO: get exception to client
179      HeuristicLab.Common.EventArgs<Exception> ex = (HeuristicLab.Common.EventArgs<Exception>)e;
180      currentException = ex.Value;
181      Core.EnqueueExecutorMessage(Core.SendFinishedJob, JobId);
182    }
183
184    private void Job_JobStopped(object sender, EventArgs e) {
185      if (wasJobAborted) {
186        pauseStopSem.Release();
187      } else {
188        //it's a clean and finished job, so send it
189        Core.EnqueueExecutorMessage(Core.SendFinishedJob, JobId);
190      }
191    }
192
193    public JobData GetFinishedJob() {
194      if (Job == null) {
195        throw new InvalidStateException("Job is null");
196      }
197
198      if (Job.ExecutionState == HeuristicLab.Core.ExecutionState.Started) {
199        try {
200          Job.Stop();
201          wasJobAborted = true;
202          pauseStopSem.WaitOne();
203        }
204        catch (Exception ex) {
205          SlaveClientCom.Instance.ClientCom.LogMessage("Error stopping job:" + ex.ToString());
206        }
207      }
208
209      return GetJob();
210    }
211
212
213    public JobData GetPausedJob() {
214      if (Job.ExecutionState != HeuristicLab.Core.ExecutionState.Paused) {
215        throw new Exception("Executor: Job has to be paused before fetching results.");
216      }
217      return GetJob();
218    }
219
220    private void Job_JobPaused(object sender, EventArgs e) {
221      pauseStopSem.Release();
222    }
223
224    private JobData GetJob() {
225      if (Job.ExecutionState == HeuristicLab.Core.ExecutionState.Started) {
226        throw new InvalidStateException("Job is still running");
227      } else {
228        JobData jdata = new JobData();
229        jdata.Data = PersistenceUtil.Serialize(Job);
230        jdata.JobId = JobId;
231        return jdata;
232      }
233    }
234
235    public Executor() {
236    }
237
238    public void Dispose() {
239      if (Job != null)
240        DeregisterJobEvents();
241      Job = null;
242    }
243  }
244}
Note: See TracBrowser for help on using the repository browser.