Free cookie consent management tool by TermsFeed Policy Generator

source: branches/3.3-Hive/sources/HeuristicLab.Hive/HeuristicLab.Hive.Server.Core/3.3/JobManager.cs @ 4368

Last change on this file since 4368 was 4368, checked in by cneumuel, 14 years ago
  • created HiveClient which shows an overview over all submitted HiveExperiments
  • its possible to download all submitted HiveExperiments including results
  • Experiments are now sent as a whole to the Hive and the Hive-Slaves take care of creating child-jobs (if necessary). The parent job is then paused and will be reactivated when all child-jobs are finished
  • WcfService-Clients are now consistently managed by WcfServicePool which allows to use IDisposable-Pattern and always keeps exactly one proxy-object until all callers disposed them.
  • created ProgressView which is able to lock a View and display progress of an action. It also allows to simulate progress if no progress-information is available so that users don't get too nervous while waiting.
File size: 14.5 KB
Line 
1#region License Information
2
3/* HeuristicLab
4 * Copyright (C) 2002-2008 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
5 *
6 * This file is part of HeuristicLab.
7 *
8 * HeuristicLab is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation, either version 3 of the License, or
11 * (at your option) any later version.
12 *
13 * HeuristicLab is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
20 */
21
22#endregion
23
24using System;
25using System.Collections.Generic;
26using System.Linq;
27using System.Text;
28using HeuristicLab.Hive.Contracts.Interfaces;
29using HeuristicLab.Hive.Contracts.BusinessObjects;
30using HeuristicLab.Hive.Contracts;
31using HeuristicLab.Hive.Server.DataAccess;
32using HeuristicLab.Hive.Server.Core.InternalInterfaces;
33using HeuristicLab.DataAccess.Interfaces;
34using System.Data;
35using System.IO;
36using HeuristicLab.Tracing;
37using System.Transactions;
38using HeuristicLab.Hive.Server.LINQDataAccess;
39using IsolationLevel = System.Transactions.IsolationLevel;
40using HeuristicLab.Hive.Contracts.ResponseObjects;
41using HeuristicLab.Hive.JobBase;
42
43namespace HeuristicLab.Hive.Server.Core {
44  internal class JobManager : IJobManager, IInternalJobManager {
45    private ILifecycleManager lifecycleManager;
46
47    #region IJobManager Members
48
49    public JobManager() {
50      lifecycleManager = ServiceLocator.GetLifecycleManager();
51
52      lifecycleManager.RegisterStartup(new EventHandler(lifecycleManager_OnStartup));
53      lifecycleManager.RegisterShutdown(new EventHandler(lifecycleManager_OnShutdown));
54    }
55
56    private void CheckForDeadJobs() {
57      Logger.Info("Searching for dead Jobs");
58
59      List<JobDto> allJobs = new List<JobDto>(DaoLocator.JobDao.FindAll());
60      foreach (JobDto curJob in allJobs) {
61        if (curJob.State != JobState.Calculating && curJob.State != JobState.Finished) {
62          DaoLocator.JobDao.SetJobOffline(curJob);
63        }
64      }
65    }
66
67    private void lifecycleManager_OnStartup(object sender, EventArgs e) {
68      Logger.Info("Startup Event Fired, Checking DB for consistency");
69      CheckForDeadJobs();
70      Logger.Info("Startup Event Done");
71    }
72
73    private void lifecycleManager_OnShutdown(object sender, EventArgs e) {
74      Logger.Info("Startup Event Fired, Checking DB for consistency");
75      CheckForDeadJobs();
76      Logger.Info("Startup Event Done");
77    }
78
79    /// <summary>
80    /// returns all jobs stored in the database
81    /// </summary>
82    /// <returns></returns>
83    public ResponseList<JobDto> GetAllJobs() {
84      ResponseList<JobDto> response = new ResponseList<JobDto>();
85      response.List = new List<JobDto>(DaoLocator.JobDao.FindAll());
86      return response;
87    }
88
89    public ResponseList<JobDto> GetAllJobsWithFilter(JobState jobState, int offset, int count) {
90      ResponseList<JobDto> response = new ResponseList<JobDto>();
91      response.List = new List<JobDto>(DaoLocator.JobDao.FindWithLimitations(jobState, offset, count));
92      return response;
93    }
94
95    /// <summary>
96    /// Gets the streamed job
97    /// </summary>
98    /// <param name="jobId"></param>
99    /// <returns></returns>
100    public Stream GetJobStreamById(Guid jobId) {
101      return DaoLocator.JobDao.GetSerializedJobStream(jobId);
102    }
103
104    /// <summary>
105    /// returns the job with the specified id
106    /// </summary>
107    /// <returns></returns>
108    public ResponseObject<JobDto> GetJobById(Guid jobId) {
109      ResponseObject<JobDto> response = new ResponseObject<JobDto>();
110
111      response.Obj = DaoLocator.JobDao.FindById(jobId);
112      if (response.Obj != null) {
113        response.StatusMessage = ResponseStatus.Ok;
114      } else {
115        response.StatusMessage = ResponseStatus.GetJobById_JobDoesNotExist;
116      }
117
118      return response;
119    }
120
121    /// <summary>
122    /// Returns JobDto object with Slave-Object attached
123    /// </summary>
124    public ResponseObject<JobDto> GetJobByIdWithDetails(Guid jobId) {
125      ResponseObject<JobDto> job = new ResponseObject<JobDto>();
126      job.Obj = DaoLocator.JobDao.FindById(jobId);
127      if (job.Obj != null) {
128        job.StatusMessage = ResponseStatus.Ok;
129
130        job.Obj.Slave = DaoLocator.SlaveDao.GetSlaveForJob(jobId);
131      } else {
132        job.StatusMessage = ResponseStatus.GetJobByIdWithDetails_JobDoesNotExist;
133      }
134      return job;
135    }
136
137    public ResponseObject<JobDto> AddJobWithGroupStrings(SerializedJob job, IEnumerable<string> resources) {
138      ISlaveGroupDao cgd = DaoLocator.SlaveGroupDao;
139      foreach (string res in resources) {
140        foreach (SlaveGroupDto cg in cgd.FindByName(res)) {
141          job.JobInfo.AssignedResourceIds.Add(cg.Id);
142        }
143      }
144      return AddNewJob(job, true);
145    }
146
147    /// <summary>
148    /// Adds a new job into the database
149    /// </summary>
150    /// <param name="job"></param>
151    /// <param name="overrideUserid">if false, job.JobInfo.UserId will not be overridden</param>
152    /// <returns></returns>
153    public ResponseObject<JobDto> AddNewJob(SerializedJob job, bool overrideUserid) {
154      ResponseObject<JobDto> response = new ResponseObject<JobDto>();
155
156      if (job != null && job.JobInfo != null) {
157        if (job.JobInfo.State != JobState.Offline) {
158          response.StatusMessage = ResponseStatus.AddNewJob_JobStateMustBeOffline;
159          return response;
160        }
161        if (job.JobInfo.Id != Guid.Empty) {
162          response.StatusMessage = ResponseStatus.AddNewJob_JobIdMustNotBeSet;
163          return response;
164        }
165        if (job.SerializedJobData == null) {
166          response.StatusMessage = ResponseStatus.AddNewJob_JobNull;
167          return response;
168        }
169
170        job.JobInfo.DateCreated = DateTime.Now;
171        if (overrideUserid) {
172          job.JobInfo.UserId = ServiceLocator.GetAuthorizationManager().UserId;
173        }
174        DaoLocator.JobDao.InsertWithAttachedJob(job);
175        DaoLocator.PluginInfoDao.InsertPluginDependenciesForJob(job.JobInfo);
176
177        response.Obj = job.JobInfo;
178      } else {
179        response.StatusMessage = ResponseStatus.AddNewJob_JobNull;
180      }
181
182      return response;
183    }
184
185    public ResponseObject<JobDto> AddNewJob(SerializedJob job) {
186      return AddNewJob(job, true);
187    }
188
189    /// <summary>
190    /// Removes a job from the database
191    ///
192    /// [chn] this is currently not used anywhere -> check redundancy with AbortJob
193    /// </summary>
194    /// <param name="jobId"></param>
195    /// <returns></returns>
196    //public Response RemoveJob(Guid jobId) {
197    //  Response response = new Response();
198
199    //  JobDto job = DaoLocator.JobDao.FindById(jobId);
200    //  if (job == null) {
201    //    response.StatusMessage = ResponseStatusMessage.RemoveJob_JobDoesNotExist;
202    //    return response;
203    //  }
204    //  DaoLocator.JobDao.Delete(job);
205
206    //  return response;
207    //}
208
209    ///
210    /// [chn] currently not used anywhere
211    ///
212    //public ResponseObject<JobDto> GetLastJobResultOf(Guid jobId) {
213    //  ResponseObject<JobDto> result = new ResponseObject<JobDto>();
214
215    //  result.Obj = DaoLocator.JobDao.FindById(jobId);
216    //  if (result.Obj == null) {
217    //    result.StatusMessage = ResponseStatusMessage.
218    //  }
219
220    //  return result;
221    //}
222
223    public ResponseObject<SerializedJob> GetLastSerializedResult(Guid jobId) {
224      ResponseObject<SerializedJob> response = new ResponseObject<SerializedJob>();
225      JobDto job = DaoLocator.JobDao.FindById(jobId);
226
227      response.Obj = new SerializedJob();
228      response.Obj.JobInfo = job;
229
230      response.Obj.SerializedJobData = DaoLocator.JobDao.GetBinaryJobFile(jobId);
231
232      return response;
233    }
234
235    public ResponseObject<SerializedJob> GetSnapshotResult(Guid jobId) {
236      ResponseObject<SerializedJob> response = new ResponseObject<SerializedJob>();
237
238      JobDto job = DaoLocator.JobDao.FindById(jobId);
239
240      //if it's a snapshot but the result hasn't reached the server yet...
241      if (job.State == JobState.SnapshotRequested || job.State == JobState.SnapshotSent) {
242        response.StatusMessage = ResponseStatus.GetSnapshotResult_JobResultNotYetThere;
243        return response;
244      }
245
246      response.Obj = new SerializedJob();
247      response.Obj.JobInfo = job;
248      response.Obj.SerializedJobData = DaoLocator.JobDao.GetBinaryJobFile(jobId);
249
250      return response;
251    }
252
253    public Response RequestSnapshot(Guid jobId) {
254      Response response = new Response();
255
256      JobDto job = DaoLocator.JobDao.FindById(jobId);
257      if (job.State == JobState.SnapshotRequested || job.State == JobState.SnapshotSent) {
258        response.StatusMessage = ResponseStatus.RequestSnapshot_SnapshotAlreadyRequested;
259        return response;
260      }
261      if (job.State != JobState.Calculating) {
262        response.StatusMessage = ResponseStatus.RequestSnapshot_JobIsNotBeeingCalculated;
263        return response;
264      }
265      // job is in correct state
266      job.State = JobState.SnapshotRequested;
267      DaoLocator.JobDao.Update(job);
268
269      return response;
270    }
271
272    /// <summary>
273    /// [chn] rename to RequestAbortJob?
274    /// </summary>
275    public Response AbortJob(Guid jobId) {
276      Response response = new Response();
277
278      JobDto job = DaoLocator.JobDao.FindById(jobId);
279      if (job == null) {
280        //response.Success = false;
281        response.StatusMessage = ResponseStatus.AbortJob_JobDoesNotExist;
282        return response; // no commit needed
283      }
284      if (job.State == JobState.Aborted) {
285        //response.Success = true;
286        response.StatusMessage = ResponseStatus.AbortJob_AbortAlreadyRequested;
287        return response; // no commit needed
288      }
289      if (job.State != JobState.Calculating && job.State != JobState.SnapshotRequested && job.State != JobState.SnapshotSent) {
290        //response.Success = false;
291        response.StatusMessage = ResponseStatus.AbortJob_JobIsNotBeeingCalculated;
292        return response; // no commit needed
293      }
294      // job is in correct state
295      job.State = JobState.Aborted;
296      DaoLocator.JobDao.Update(job);
297
298      return response;
299    }
300
301    /// <summary>
302    /// Returns the current state for all jobs requested
303    /// </summary>
304    /// <param name="jobIds"></param>
305    /// <returns></returns>
306    public ResponseObject<JobResultList> GetJobResults(IEnumerable<Guid> jobIds) {
307      ResponseObject<JobResultList> response = new ResponseObject<JobResultList>();
308      JobResultList jobResultList = new JobResultList();
309      IEnumerable<JobDto> jobs = DaoLocator.JobDao.FindJobsById(jobIds);
310      foreach (JobDto job in jobs) {
311        jobResultList.Add(new JobResult() {
312          Id = job.Id,
313          State = job.State,
314          DateCalculated = job.DateCalculated,
315          DateFinished = job.DateFinished,
316          Exception = job.Exception,
317          Percentage = job.Percentage
318        });
319      }
320      response.Obj = jobResultList;
321      return response;
322    }
323
324    public byte[] GetSerializedJobDataById(Guid jobId) {
325      return DaoLocator.JobDao.GetBinaryJobFile(jobId);
326    }
327
328    public void SetSerializedJobDataById(Guid jobId, byte[] data) {
329      DaoLocator.JobDao.SetBinaryJobFile(jobId, data);
330    }
331
332    public ResponseObject<JobResultList> GetChildJobResults(Guid? parentJobId, bool recursive, bool includeParent) {
333      ResponseObject<JobResultList> response = new ResponseObject<JobResultList>();
334      JobResultList jobResultList = new JobResultList();
335
336      IList<JobDto> jobs = DaoLocator.JobDao.FindJobsByParentId(parentJobId, recursive).ToList();
337      if (!parentJobId.HasValue) {
338        jobs = jobs.Where(job => job.UserId == ServiceLocator.GetAuthorizationManager().UserId).ToList();
339      }
340
341      if (includeParent && parentJobId.HasValue) {
342        jobs.Add(DaoLocator.JobDao.FindById(parentJobId.Value));
343      }
344
345      foreach (JobDto job in jobs) {
346        if (job != null) {
347          jobResultList.Add(new JobResult() {
348            Id = job.Id,
349            State = job.State,
350            DateCreated = job.DateCreated,
351            DateCalculated = job.DateCalculated,
352            DateFinished = job.DateFinished,
353            Exception = job.Exception,
354            Percentage = job.Percentage,
355            ParentJobId = job.ParentJob != null ? new Nullable<Guid>(job.ParentJob.Id) : null
356          });
357        }
358      }
359     
360      response.Obj = jobResultList;
361      return response;
362    }
363
364    public ResponseObject<JobDto> AddChildJob(Guid parentJobId, SerializedJob serializedJob) {
365      JobDto parentJob = DaoLocator.JobDao.FindById(parentJobId);
366
367      serializedJob.JobInfo.ParentJob = parentJob;
368      serializedJob.JobInfo.UserId = parentJob.UserId;
369      serializedJob.JobInfo.AssignedResourceIds = parentJob.AssignedResourceIds;
370
371      return AddNewJob(serializedJob, false);
372    }
373
374    public ResponseObject<JobDto> PauseJob(SerializedJob serializedJob) {
375      JobDto jobDto = DaoLocator.JobDao.FindById(serializedJob.JobInfo.Id);
376
377      jobDto.State = serializedJob.JobInfo.State;
378      jobDto.Percentage = serializedJob.JobInfo.Percentage;
379     
380
381      DaoLocator.JobDao.SetBinaryJobFile(serializedJob.JobInfo.Id, serializedJob.SerializedJobData);
382      DaoLocator.JobDao.Update(jobDto);
383
384      DaoLocator.JobDao.UnAssignSlaveToJob(jobDto.Id);
385
386      return new ResponseObject<JobDto>() {
387        Obj = jobDto,
388        StatusMessage = ResponseStatus.Ok
389      };
390    }
391
392    #endregion
393
394    #region Project handling (currently unimplemented)
395
396    public ResponseList<ProjectDto> GetAllProjects() {
397      throw new NotImplementedException();
398    }
399
400    private Response CreateUpdateProject(ProjectDto project) {
401      throw new NotImplementedException();
402    }
403
404    public Response CreateProject(ProjectDto project) {
405      return CreateUpdateProject(project);
406    }
407
408    public Response ChangeProject(ProjectDto project) {
409      return CreateUpdateProject(project);
410    }
411
412    public Response DeleteProject(Guid projectId) {
413      throw new NotImplementedException();
414    }
415
416    public ResponseList<JobDto> GetJobsByProject(Guid projectId) {
417      throw new NotImplementedException();
418    }
419    #endregion
420
421
422   
423
424  }
425}
Note: See TracBrowser for help on using the repository browser.