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, 12 years ago

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

File size: 12.1 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;
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));
52      lifecycleManager.RegisterShutdown(new EventHandler(lifecycleManager_OnShutdown));
53    }
54
55    private void CheckForDeadJobs() {
56      Logger.Info("Searching for dead Jobs");
57
58      List<JobDto> allJobs = new List<JobDto>(DaoLocator.JobDao.FindAll());
59      foreach (JobDto curJob in allJobs) {
60        if (curJob.State != JobState.Calculating && curJob.State != JobState.Finished) {
61          DaoLocator.JobDao.SetJobOffline(curJob);
62        }
63      }
64    }
65
66    private void lifecycleManager_OnStartup(object sender, EventArgs e) {
67      Logger.Info("Startup Event Fired, Checking DB for consistency");
68      CheckForDeadJobs();
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");
74      CheckForDeadJobs();
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
88    public ResponseList<JobDto> GetAllJobsWithFilter(JobState jobState, int offset, int count) {
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) {
112        response.StatusMessage = ResponseStatus.Ok;
113      } else {
114        response.StatusMessage = ResponseStatus.GetJobById_JobDoesNotExist;
115      }
116
117      return response;
118    }
119
120    /// <summary>
121    /// Returns JobDto object with Client-Object attached
122    /// </summary>
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) {
127        job.StatusMessage = ResponseStatus.Ok;
128
129        job.Obj.Client = DaoLocator.ClientDao.GetClientForJob(jobId);
130      } else {
131        job.StatusMessage = ResponseStatus.GetJobByIdWithDetails_JobDoesNotExist;
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) {
155        if (job.JobInfo.State != JobState.Offline) {
156          response.StatusMessage = ResponseStatus.AddNewJob_JobStateMustBeOffline;
157          return response;
158        }
159        if (job.JobInfo.Id != Guid.Empty) {
160          response.StatusMessage = ResponseStatus.AddNewJob_JobIdMustNotBeSet;
161          return response;
162        }
163        if (job.SerializedJobData == null) {
164          response.StatusMessage = ResponseStatus.AddNewJob_JobNull;
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;
173      } else {
174        response.StatusMessage = ResponseStatus.AddNewJob_JobNull;
175      }
176
177      return response;
178    }
179
180    /// <summary>
181    /// Removes a job from the database
182    ///
183    /// [chn] this is currently not used anywhere -> check redundancy with AbortJob
184    /// </summary>
185    /// <param name="jobId"></param>
186    /// <returns></returns>
187    //public Response RemoveJob(Guid jobId) {
188    //  Response response = new Response();
189
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);
196
197    //  return response;
198    //}
199
200    ///
201    /// [chn] currently not used anywhere
202    ///
203    //public ResponseObject<JobDto> GetLastJobResultOf(Guid jobId) {
204    //  ResponseObject<JobDto> result = new ResponseObject<JobDto>();
205
206    //  result.Obj = DaoLocator.JobDao.FindById(jobId);
207    //  if (result.Obj == null) {
208    //    result.StatusMessage = ResponseStatusMessage.
209    //  }
210
211    //  return result;
212    //}
213
214    // [chn] [refactor] why does this method handle 3 different cases? wouldn't 3 methods be easier?
215    //Requested means: there MUST be a job result which gets sent back
216    // requested==true: resultat mit job
217    // requested==false:
218    public ResponseObject<SerializedJob> GetLastSerializedResult(Guid jobId, bool requested, bool snapshot) {
219      ResponseObject<SerializedJob> response = new ResponseObject<SerializedJob>();
220
221      JobDto job = DaoLocator.JobDao.FindById(jobId);
222
223      //if it's a snapshot but the result hasn't reached the server yet...
224      if (snapshot && (job.State == JobState.SnapshotRequested || job.State == JobState.SnapshotSent)) {
225        response.StatusMessage = ResponseStatus.GetLastSerializedResult_JobResultNotYetThere;
226
227        return response;
228      }
229
230      //if it's NOT a snapshot, NEITHER request NOR is it finished
231      if (!requested && !snapshot && job.State != JobState.Finished) {
232        response.StatusMessage = ResponseStatus.GetLastSerializedResult_JobResultNotYetThere;
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
241      response.Obj.SerializedJobData = DaoLocator.JobDao.GetBinaryJobFile(jobId);
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);
250      if (job.State == JobState.SnapshotRequested || job.State == JobState.SnapshotSent) {
251        response.StatusMessage = ResponseStatus.RequestSnapshot_SnapshotAlreadyRequested;
252        return response;
253      }
254      if (job.State != JobState.Calculating) {
255        response.StatusMessage = ResponseStatus.RequestSnapshot_JobIsNotBeeingCalculated;
256        return response;
257      }
258      // job is in correct state
259      job.State = JobState.SnapshotRequested;
260      DaoLocator.JobDao.Update(job);
261
262      return response;
263    }
264
265    /// <summary>
266    /// [chn] rename to RequestAbortJob?
267    /// </summary>
268    public Response AbortJob(Guid jobId) {
269      Response response = new Response();
270
271      JobDto job = DaoLocator.JobDao.FindById(jobId);
272      if (job == null) {
273        //response.Success = false;
274        response.StatusMessage = ResponseStatus.AbortJob_JobDoesNotExist;
275        return response; // no commit needed
276      }
277      if (job.State == JobState.Aborted) {
278        //response.Success = true;
279        response.StatusMessage = ResponseStatus.AbortJob_AbortAlreadyRequested;
280        return response; // no commit needed
281      }
282      if (job.State != JobState.Calculating && job.State != JobState.SnapshotRequested && job.State != JobState.SnapshotSent) {
283        //response.Success = false;
284        response.StatusMessage = ResponseStatus.AbortJob_JobIsNotBeeingCalculated;
285        return response; // no commit needed
286      }
287      // job is in correct state
288      job.State = JobState.Aborted;
289      DaoLocator.JobDao.Update(job);
290
291      return response;
292    }
293
294    /// <summary>
295    /// Returns the current state for all jobs requested
296    /// </summary>
297    /// <param name="jobIds"></param>
298    /// <returns></returns>
299    public ResponseObject<JobResultList> GetJobResults(IEnumerable<Guid> jobIds) {
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
311        });
312      }
313      response.Obj = jobResultList;
314      return response;
315    }
316
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
329    public ResponseList<ProjectDto> GetAllProjects() {
330      throw new NotImplementedException();
331    }
332
333    private Response CreateUpdateProject(ProjectDto project) {
334      throw new NotImplementedException();
335    }
336
337    public Response CreateProject(ProjectDto project) {
338      return CreateUpdateProject(project);
339    }
340
341    public Response ChangeProject(ProjectDto project) {
342      return CreateUpdateProject(project);
343    }
344
345    public Response DeleteProject(Guid projectId) {
346      throw new NotImplementedException();
347    }
348
349    public ResponseList<JobDto> GetJobsByProject(Guid projectId) {
350      throw new NotImplementedException();
351    }
352    #endregion
353  }
354}
Note: See TracBrowser for help on using the repository browser.