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 @ 4263

Last change on this file since 4263 was 4263, checked in by cneumuel, 12 years ago

consolidated Response objects to use only StatusMessage with enums instead of strings.
removed Success property from Response. success is now represented by StatusMessage alone. (#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 != State.Calculating && curJob.State != State.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(State 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 != State.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 == State.RequestSnapshot || job.State == State.RequestSnapshotSent)) {
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 != State.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 == State.RequestSnapshot || job.State == State.RequestSnapshotSent) {
251        response.StatusMessage = ResponseStatus.RequestSnapshot_SnapshotAlreadyRequested;
252        return response;
253      }
254      if (job.State != State.Calculating) {
255        response.StatusMessage = ResponseStatus.RequestSnapshot_JobIsNotBeeingCalculated;
256        return response;
257      }
258      // job is in correct state
259      job.State = State.RequestSnapshot;
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 == State.Abort) {
278        //response.Success = true;
279        response.StatusMessage = ResponseStatus.AbortJob_AbortAlreadyRequested;
280        return response; // no commit needed
281      }
282      if (job.State != State.Calculating && job.State != State.RequestSnapshot && job.State != State.RequestSnapshotSent) {
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 = State.Abort;
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.