Free cookie consent management tool by TermsFeed Policy Generator

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

Last change on this file since 4264 was 4264, checked in by cneumuel, 14 years ago

Split up "State" to "JobState" and "SlaveState" (#1159)

File size: 12.1 KB
RevLine 
[4060]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;
[4092]39using IsolationLevel = System.Transactions.IsolationLevel;
[4263]40using HeuristicLab.Hive.Contracts.ResponseObjects;
[4060]41
42namespace HeuristicLab.Hive.Server.Core {
43  internal class JobManager : IJobManager, IInternalJobManager {
44    private ILifecycleManager lifecycleManager;
45
46    #region IJobManager Members
47
48    public JobManager() {
49      lifecycleManager = ServiceLocator.GetLifecycleManager();
50
51      lifecycleManager.RegisterStartup(new EventHandler(lifecycleManager_OnStartup));
[4254]52      lifecycleManager.RegisterShutdown(new EventHandler(lifecycleManager_OnShutdown));
[4060]53    }
54
[4092]55    private void CheckForDeadJobs() {
[4060]56      Logger.Info("Searching for dead Jobs");
[4092]57
[4254]58      List<JobDto> allJobs = new List<JobDto>(DaoLocator.JobDao.FindAll());
59      foreach (JobDto curJob in allJobs) {
[4264]60        if (curJob.State != JobState.Calculating && curJob.State != JobState.Finished) {
[4254]61          DaoLocator.JobDao.SetJobOffline(curJob);
[4060]62        }
63      }
64    }
65
66    private void lifecycleManager_OnStartup(object sender, EventArgs e) {
67      Logger.Info("Startup Event Fired, Checking DB for consistency");
[4092]68      CheckForDeadJobs();
[4060]69      Logger.Info("Startup Event Done");
70    }
71
72    private void lifecycleManager_OnShutdown(object sender, EventArgs e) {
73      Logger.Info("Startup Event Fired, Checking DB for consistency");
[4092]74      CheckForDeadJobs();
[4060]75      Logger.Info("Startup Event Done");
76    }
77
78    /// <summary>
79    /// returns all jobs stored in the database
80    /// </summary>
81    /// <returns></returns>
82    public ResponseList<JobDto> GetAllJobs() {
83      ResponseList<JobDto> response = new ResponseList<JobDto>();
84      response.List = new List<JobDto>(DaoLocator.JobDao.FindAll());
85      return response;
86    }
87
[4264]88    public ResponseList<JobDto> GetAllJobsWithFilter(JobState jobState, int offset, int count) {
[4060]89      ResponseList<JobDto> response = new ResponseList<JobDto>();
90      response.List = new List<JobDto>(DaoLocator.JobDao.FindWithLimitations(jobState, offset, count));
91      return response;
92    }
93
94    /// <summary>
95    /// Gets the streamed job
96    /// </summary>
97    /// <param name="jobId"></param>
98    /// <returns></returns>
99    public Stream GetJobStreamById(Guid jobId) {
100      return DaoLocator.JobDao.GetSerializedJobStream(jobId);
101    }
102
103    /// <summary>
104    /// returns the job with the specified id
105    /// </summary>
106    /// <returns></returns>
107    public ResponseObject<JobDto> GetJobById(Guid jobId) {
108      ResponseObject<JobDto> response = new ResponseObject<JobDto>();
109
110      response.Obj = DaoLocator.JobDao.FindById(jobId);
111      if (response.Obj != null) {
[4263]112        response.StatusMessage = ResponseStatus.Ok;
[4092]113      } else {
[4263]114        response.StatusMessage = ResponseStatus.GetJobById_JobDoesNotExist;
[4060]115      }
116
117      return response;
118    }
119
[4121]120    /// <summary>
121    /// Returns JobDto object with Client-Object attached
122    /// </summary>
[4060]123    public ResponseObject<JobDto> GetJobByIdWithDetails(Guid jobId) {
124      ResponseObject<JobDto> job = new ResponseObject<JobDto>();
125      job.Obj = DaoLocator.JobDao.FindById(jobId);
126      if (job.Obj != null) {
[4263]127        job.StatusMessage = ResponseStatus.Ok;
[4060]128
129        job.Obj.Client = DaoLocator.ClientDao.GetClientForJob(jobId);
[4092]130      } else {
[4263]131        job.StatusMessage = ResponseStatus.GetJobByIdWithDetails_JobDoesNotExist;
[4060]132      }
133      return job;
134    }
135
136    public ResponseObject<JobDto> AddJobWithGroupStrings(SerializedJob job, IEnumerable<string> resources) {
137      IClientGroupDao cgd = DaoLocator.ClientGroupDao;
138      foreach (string res in resources) {
139        foreach (ClientGroupDto cg in cgd.FindByName(res)) {
140          job.JobInfo.AssignedResourceIds.Add(cg.Id);
141        }
142      }
143      return AddNewJob(job);
144    }
145
146    /// <summary>
147    /// Adds a new job into the database
148    /// </summary>
149    /// <param name="job"></param>
150    /// <returns></returns>
151    public ResponseObject<JobDto> AddNewJob(SerializedJob job) {
152      ResponseObject<JobDto> response = new ResponseObject<JobDto>();
153
154      if (job != null && job.JobInfo != null) {
[4264]155        if (job.JobInfo.State != JobState.Offline) {
[4263]156          response.StatusMessage = ResponseStatus.AddNewJob_JobStateMustBeOffline;
[4060]157          return response;
158        }
159        if (job.JobInfo.Id != Guid.Empty) {
[4263]160          response.StatusMessage = ResponseStatus.AddNewJob_JobIdMustNotBeSet;
[4060]161          return response;
162        }
163        if (job.SerializedJobData == null) {
[4263]164          response.StatusMessage = ResponseStatus.AddNewJob_JobNull;
[4060]165          return response;
166        }
167
168        job.JobInfo.DateCreated = DateTime.Now;
169        DaoLocator.JobDao.InsertWithAttachedJob(job);
170        DaoLocator.PluginInfoDao.InsertPluginDependenciesForJob(job.JobInfo);
171
172        response.Obj = job.JobInfo;
[4092]173      } else {
[4263]174        response.StatusMessage = ResponseStatus.AddNewJob_JobNull;
[4060]175      }
176
177      return response;
178    }
179
180    /// <summary>
181    /// Removes a job from the database
[4263]182    ///
183    /// [chn] this is currently not used anywhere -> check redundancy with AbortJob
[4060]184    /// </summary>
185    /// <param name="jobId"></param>
186    /// <returns></returns>
[4263]187    //public Response RemoveJob(Guid jobId) {
188    //  Response response = new Response();
[4060]189
[4263]190    //  JobDto job = DaoLocator.JobDao.FindById(jobId);
191    //  if (job == null) {
192    //    response.StatusMessage = ResponseStatusMessage.RemoveJob_JobDoesNotExist;
193    //    return response;
194    //  }
195    //  DaoLocator.JobDao.Delete(job);
[4060]196
[4263]197    //  return response;
198    //}
[4060]199
[4263]200    ///
201    /// [chn] currently not used anywhere
202    ///
203    //public ResponseObject<JobDto> GetLastJobResultOf(Guid jobId) {
204    //  ResponseObject<JobDto> result = new ResponseObject<JobDto>();
[4060]205
[4263]206    //  result.Obj = DaoLocator.JobDao.FindById(jobId);
207    //  if (result.Obj == null) {
208    //    result.StatusMessage = ResponseStatusMessage.
209    //  }
[4060]210
[4263]211    //  return result;
212    //}
[4060]213
[4120]214    // [chn] [refactor] why does this method handle 3 different cases? wouldn't 3 methods be easier?
[4060]215    //Requested means: there MUST be a job result which gets sent back
[4173]216    // requested==true: resultat mit job
217    // requested==false:
[4263]218    public ResponseObject<SerializedJob> GetLastSerializedResult(Guid jobId, bool requested, bool snapshot) {
[4120]219      ResponseObject<SerializedJob> response = new ResponseObject<SerializedJob>();
[4060]220
221      JobDto job = DaoLocator.JobDao.FindById(jobId);
222
223      //if it's a snapshot but the result hasn't reached the server yet...
[4264]224      if (snapshot && (job.State == JobState.SnapshotRequested || job.State == JobState.SnapshotSent)) {
[4263]225        response.StatusMessage = ResponseStatus.GetLastSerializedResult_JobResultNotYetThere;
[4060]226
227        return response;
228      }
229
230      //if it's NOT a snapshot, NEITHER request NOR is it finished
[4264]231      if (!requested && !snapshot && job.State != JobState.Finished) {
[4263]232        response.StatusMessage = ResponseStatus.GetLastSerializedResult_JobResultNotYetThere;
[4060]233
234        return response;
235      }
236
237      //every other case - snapshot, job finished or it's requested
238      response.Obj = new SerializedJob();
239      response.Obj.JobInfo = job;
240
[4119]241      response.Obj.SerializedJobData = DaoLocator.JobDao.GetBinaryJobFile(jobId);
[4060]242
243      return response;
244    }
245
246    public Response RequestSnapshot(Guid jobId) {
247      Response response = new Response();
248
249      JobDto job = DaoLocator.JobDao.FindById(jobId);
[4264]250      if (job.State == JobState.SnapshotRequested || job.State == JobState.SnapshotSent) {
[4263]251        response.StatusMessage = ResponseStatus.RequestSnapshot_SnapshotAlreadyRequested;
[4060]252        return response;
253      }
[4264]254      if (job.State != JobState.Calculating) {
[4263]255        response.StatusMessage = ResponseStatus.RequestSnapshot_JobIsNotBeeingCalculated;
[4060]256        return response;
257      }
258      // job is in correct state
[4264]259      job.State = JobState.SnapshotRequested;
[4060]260      DaoLocator.JobDao.Update(job);
261
262      return response;
263    }
264
[4263]265    /// <summary>
266    /// [chn] rename to RequestAbortJob?
267    /// </summary>
[4060]268    public Response AbortJob(Guid jobId) {
269      Response response = new Response();
270
271      JobDto job = DaoLocator.JobDao.FindById(jobId);
272      if (job == null) {
[4263]273        //response.Success = false;
274        response.StatusMessage = ResponseStatus.AbortJob_JobDoesNotExist;
[4060]275        return response; // no commit needed
276      }
[4264]277      if (job.State == JobState.Aborted) {
[4263]278        //response.Success = true;
279        response.StatusMessage = ResponseStatus.AbortJob_AbortAlreadyRequested;
[4060]280        return response; // no commit needed
281      }
[4264]282      if (job.State != JobState.Calculating && job.State != JobState.SnapshotRequested && job.State != JobState.SnapshotSent) {
[4263]283        //response.Success = false;
284        response.StatusMessage = ResponseStatus.AbortJob_JobIsNotBeeingCalculated;
[4060]285        return response; // no commit needed
286      }
287      // job is in correct state
[4264]288      job.State = JobState.Aborted;
[4060]289      DaoLocator.JobDao.Update(job);
290
291      return response;
292    }
293
[4254]294    /// <summary>
295    /// Returns the current state for all jobs requested
296    /// </summary>
297    /// <param name="jobIds"></param>
298    /// <returns></returns>
[4263]299    public ResponseObject<JobResultList> GetJobResults(IEnumerable<Guid> jobIds) {
[4170]300      ResponseObject<JobResultList> response = new ResponseObject<JobResultList>();
301      JobResultList jobResultList = new JobResultList();
302      IEnumerable<JobDto> jobs = DaoLocator.JobDao.FindJobsById(jobIds);
303      foreach (JobDto job in jobs) {
304        jobResultList.Add(new JobResult() {
305          JobId = job.Id,
306          State = job.State,
307          DateCalculated = job.DateCalculated,
308          DateFinished = job.DateFinished,
309          Exception = job.Exception,
310          Percentage = job.Percentage
[4254]311        });
[4170]312      }
313      response.Obj = jobResultList;
314      return response;
[4060]315    }
316
[4254]317    public byte[] GetSerializedJobDataById(Guid jobId) {
318      return DaoLocator.JobDao.GetBinaryJobFile(jobId);
319    }
320
321    public void SetSerializedJobDataById(Guid jobId, byte[] data) {
322      DaoLocator.JobDao.SetBinaryJobFile(jobId, data);
323    }
324
325    #endregion
326
327    #region Project handling (currently unimplemented)
328
[4060]329    public ResponseList<ProjectDto> GetAllProjects() {
[4254]330      throw new NotImplementedException();
[4060]331    }
332
[4254]333    private Response CreateUpdateProject(ProjectDto project) {
334      throw new NotImplementedException();
[4060]335    }
336
337    public Response CreateProject(ProjectDto project) {
[4254]338      return CreateUpdateProject(project);
[4060]339    }
340
341    public Response ChangeProject(ProjectDto project) {
[4254]342      return CreateUpdateProject(project);
[4060]343    }
344
345    public Response DeleteProject(Guid projectId) {
[4254]346      throw new NotImplementedException();
[4060]347    }
348
349    public ResponseList<JobDto> GetJobsByProject(Guid projectId) {
[4254]350      throw new NotImplementedException();
[4060]351    }
352    #endregion
353  }
354}
Note: See TracBrowser for help on using the repository browser.