Free cookie consent management tool by TermsFeed Policy Generator

source: branches/3.2/sources/HeuristicLab.Hive.Server.Core/3.2/JobManager.cs @ 3931

Last change on this file since 3931 was 3931, checked in by kgrading, 14 years ago

added minor speedups and better transaction handling to the server (#828)

File size: 11.9 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;
40
41namespace HeuristicLab.Hive.Server.Core {
42  internal class JobManager : IJobManager, IInternalJobManager {
43    //ISessionFactory factory;
44    private ILifecycleManager lifecycleManager;
45
46    #region IJobManager Members
47
48    public JobManager() {
49      //factory = ServiceLocator.GetSessionFactory();
50      lifecycleManager = ServiceLocator.GetLifecycleManager();
51
52      lifecycleManager.RegisterStartup(new EventHandler(lifecycleManager_OnStartup));
53      lifecycleManager.RegisterStartup(new EventHandler(lifecycleManager_OnShutdown));
54    }
55
56    private JobDto GetLastJobResult(Guid jobId) {
57      return DaoLocator.JobDao.FindById(jobId);
58    }
59
60
61    private void checkForDeadJobs() {
62      Logger.Info("Searching for dead Jobs");
63      using (
64        TransactionScope scope = new TransactionScope(TransactionScopeOption.Required,
65                                                      new TransactionOptions
66                                                      {IsolationLevel = ApplicationConstants.ISOLATION_LEVEL_SCOPE})) {
67        List<JobDto> allJobs = new List<JobDto>(DaoLocator.JobDao.FindAll());
68        foreach (JobDto curJob in allJobs) {
69          if (curJob.State != State.calculating && curJob.State != State.finished) {
70            DaoLocator.JobDao.SetJobOffline(curJob);
71          }
72        }
73        scope.Complete();
74      }
75      DaoLocator.DestroyContext();
76    }
77
78    private void lifecycleManager_OnStartup(object sender, EventArgs e) {
79      Logger.Info("Startup Event Fired, Checking DB for consistency");
80      checkForDeadJobs();
81      Logger.Info("Startup Event Done");
82    }
83
84    private void lifecycleManager_OnShutdown(object sender, EventArgs e) {
85      Logger.Info("Startup Event Fired, Checking DB for consistency");
86      checkForDeadJobs();
87      Logger.Info("Startup Event Done");
88    }
89
90    /// <summary>
91    /// returns all jobs stored in the database
92    /// </summary>
93    /// <returns></returns>
94    public ResponseList<JobDto> GetAllJobs() {
95      ResponseList<JobDto> response = new ResponseList<JobDto>();
96
97      response.List = new List<JobDto>(DaoLocator.JobDao.FindAll());
98      response.Success = true;
99      response.StatusMessage = ApplicationConstants.RESPONSE_JOB_ALL_JOBS;
100
101      return response;
102    }
103
104    public ResponseList<JobDto> GetAllJobsWithFilter(State jobState, int offset, int count) {
105      ResponseList<JobDto> response = new ResponseList<JobDto>();
106      response.List = new List<JobDto>(DaoLocator.JobDao.FindWithLimitations(jobState, offset, count));
107      return response;
108    }
109
110    /// <summary>
111    /// Gets the streamed job
112    /// </summary>
113    /// <param name="jobId"></param>
114    /// <returns></returns>
115    public Stream GetJobStreamById(Guid jobId) {
116      return DaoLocator.JobDao.GetSerializedJobStream(jobId);
117    }
118
119    /// <summary>
120    /// returns the job with the specified id
121    /// </summary>
122    /// <returns></returns>
123    public ResponseObject<JobDto> GetJobById(Guid jobId) {
124      ResponseObject<JobDto> response = new ResponseObject<JobDto>();
125
126      response.Obj = DaoLocator.JobDao.FindById(jobId);
127      if (response.Obj != null) {
128        response.Success = true;
129        response.StatusMessage = ApplicationConstants.RESPONSE_JOB_GET_JOB_BY_ID;
130      }
131      else {
132        response.Success = false;
133        response.StatusMessage = ApplicationConstants.RESPONSE_JOB_JOB_DOESNT_EXIST;
134      }
135
136      return response;
137    }
138
139    public ResponseObject<JobDto> GetJobByIdWithDetails(Guid jobId) {
140      ResponseObject<JobDto> job = new ResponseObject<JobDto>();
141      job.Obj = DaoLocator.JobDao.FindById(jobId);
142      if (job.Obj != null) {
143        job.Success = true;
144        job.StatusMessage = ApplicationConstants.RESPONSE_JOB_GET_JOB_BY_ID;
145
146        job.Obj.Client = DaoLocator.ClientDao.GetClientForJob(jobId);
147      }
148      else {
149        job.Success = false;
150        job.StatusMessage = ApplicationConstants.RESPONSE_JOB_JOB_DOESNT_EXIST;
151      }
152      return job;
153    }
154
155    public ResponseObject<JobDto> AddJobWithGroupStrings(SerializedJob job, IEnumerable<string> resources) {
156      IClientGroupDao cgd = DaoLocator.ClientGroupDao;
157      foreach (string res in resources) {
158        foreach (ClientGroupDto cg in cgd.FindByName(res)) {
159          job.JobInfo.AssignedResourceIds.Add(cg.Id);
160        }
161      }
162      return AddNewJob(job);
163    }
164
165    /// <summary>
166    /// Adds a new job into the database
167    /// </summary>
168    /// <param name="job"></param>
169    /// <returns></returns>
170    public ResponseObject<JobDto> AddNewJob(SerializedJob job) {
171      ResponseObject<JobDto> response = new ResponseObject<JobDto>();
172
173      if (job != null && job.JobInfo != null) {
174        if (job.JobInfo.State != State.offline) {
175          response.Success = false;
176          response.StatusMessage = ApplicationConstants.RESPONSE_JOB_JOBSTATE_MUST_BE_OFFLINE;
177          return response;
178        }
179        if (job.JobInfo.Id != Guid.Empty) {
180          response.Success = false;
181          response.StatusMessage = ApplicationConstants.RESPONSE_JOB_ID_MUST_NOT_BE_SET;
182          return response;
183        }
184        if (job.SerializedJobData == null) {
185          response.StatusMessage = ApplicationConstants.RESPONSE_JOB_JOB_NULL;
186          response.Success = false;
187          return response;
188        }
189
190        job.JobInfo.DateCreated = DateTime.Now;
191        DaoLocator.JobDao.InsertWithAttachedJob(job);
192        DaoLocator.PluginInfoDao.InsertPluginDependenciesForJob(job.JobInfo);
193
194        response.Success = true;
195        response.Obj = job.JobInfo;
196        response.StatusMessage = ApplicationConstants.RESPONSE_JOB_JOB_ADDED;
197      }
198      else {
199        response.Success = false;
200        response.StatusMessage = ApplicationConstants.RESPONSE_JOB_JOB_NULL;
201      }
202
203      return response;
204    }
205
206    /// <summary>
207    /// Removes a job from the database
208    /// </summary>
209    /// <param name="jobId"></param>
210    /// <returns></returns>
211    public Response RemoveJob(Guid jobId) {
212      Response response = new Response();
213
214      JobDto job = DaoLocator.JobDao.FindById(jobId);
215      if (job == null) {
216        response.Success = false;
217        response.StatusMessage = ApplicationConstants.RESPONSE_JOB_JOB_DOESNT_EXIST;
218        return response;
219      }
220      DaoLocator.JobDao.Delete(job);
221      response.Success = false;
222      response.StatusMessage = ApplicationConstants.RESPONSE_JOB_JOB_REMOVED;
223
224      return response;
225    }
226
227    public ResponseObject<JobDto> GetLastJobResultOf(Guid jobId) {
228      ResponseObject<JobDto> result =
229        new ResponseObject<JobDto>();
230
231      result.Obj =
232        GetLastJobResult(jobId);
233      result.Success =
234        result.Obj != null;
235
236      return result;
237    }
238
239    public ResponseObject<SerializedJob>
240      GetLastSerializedJobResultOf(Guid jobId, bool requested) {
241      ResponseObject<SerializedJob> response =
242        new ResponseObject<SerializedJob>();
243
244      JobDto job = DaoLocator.JobDao.FindById(jobId);
245      if (requested && (job.State == State.requestSnapshot || job.State == State.requestSnapshotSent)) {
246        response.Success = true;
247        response.StatusMessage = ApplicationConstants.RESPONSE_JOB_RESULT_NOT_YET_HERE;
248
249        return response;
250      }
251
252      response.Success = true;
253      response.StatusMessage = ApplicationConstants.RESPONSE_JOB_JOB_RESULT_SENT;
254      response.Obj = new SerializedJob();
255      response.Obj.JobInfo = job;
256      response.Obj.SerializedJobData =
257        DaoLocator.JobDao.GetBinaryJobFile(jobId);
258      return response;
259    }
260
261
262    public Response RequestSnapshot(Guid jobId) {
263      Response response = new Response();
264
265
266      JobDto job = DaoLocator.JobDao.FindById(jobId);
267      if (job.State == State.requestSnapshot || job.State == State.requestSnapshotSent) {
268        response.Success = true;
269        response.StatusMessage = ApplicationConstants.RESPONSE_JOB_REQUEST_ALLREADY_SET;
270        return response;
271      }
272      if (job.State != State.calculating) {
273        response.Success = false;
274        response.StatusMessage = ApplicationConstants.RESPONSE_JOB_IS_NOT_BEEING_CALCULATED;
275        return response;
276      }
277      // job is in correct state
278      job.State = State.requestSnapshot;
279      DaoLocator.JobDao.Update(job);
280
281      response.Success = true;
282      response.StatusMessage = ApplicationConstants.RESPONSE_JOB_REQUEST_SET;
283
284      return response;
285    }
286
287    public Response AbortJob(Guid jobId) {
288      Response response = new Response();
289
290      JobDto job = DaoLocator.JobDao.FindById(jobId);
291      if (job == null) {
292        response.Success = false;
293        response.StatusMessage = ApplicationConstants.RESPONSE_JOB_JOB_DOESNT_EXIST;
294        return response; // no commit needed
295      }
296      if (job.State == State.abort) {
297        response.Success = true;
298        response.StatusMessage = ApplicationConstants.RESPONSE_JOB_ABORT_REQUEST_ALLREADY_SET;
299        return response; // no commit needed
300      }
301      if (job.State != State.calculating && job.State != State.requestSnapshot && job.State != State.requestSnapshotSent) {
302        response.Success = false;
303        response.StatusMessage = ApplicationConstants.RESPONSE_JOB_IS_NOT_BEEING_CALCULATED;
304        return response; // no commit needed
305      }
306      // job is in correct state
307      job.State = State.abort;
308      DaoLocator.JobDao.Update(job);
309
310      response.Success = true;
311      response.StatusMessage = ApplicationConstants.RESPONSE_JOB_ABORT_REQUEST_SET;
312
313      return response;
314    }
315
316    public ResponseList<JobResult> GetAllJobResults(Guid jobId) {
317      return new ResponseList<JobResult>();
318    }
319
320    public ResponseList<ProjectDto> GetAllProjects() {
321      return null;
322    }
323
324    private Response createUpdateProject(ProjectDto project) {
325      return null;
326    }
327
328    public Response CreateProject(ProjectDto project) {
329      return createUpdateProject(project);
330    }
331
332    public Response ChangeProject(ProjectDto project) {
333      return createUpdateProject(project);
334    }
335
336    public Response DeleteProject(Guid projectId) {
337      return null;
338    }
339
340    public ResponseList<JobDto> GetJobsByProject(Guid projectId) {
341      return null;
342    }
343
344    public byte[] GetSerializedJobDataById(Guid jobId) {
345      return DaoLocator.JobDao.GetBinaryJobFile(jobId);
346    }
347
348    public void SetSerializedJobDataById(Guid jobId, byte[] data) {
349      DaoLocator.JobDao.SetBinaryJobFile(jobId, data);
350    }
351
352    #endregion
353  }
354}
Note: See TracBrowser for help on using the repository browser.