Free cookie consent management tool by TermsFeed Policy Generator

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

Last change on this file since 5155 was 2099, checked in by svonolfe, 16 years ago

Further avoided out of memory exceptions by updating the JobResult DAO (#372)

File size: 17.7 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2008 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
4 *
5 * This file is part of HeuristicLab.
6 *
7 * HeuristicLab is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * HeuristicLab is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
19 */
20#endregion
21
22using System;
23using System.Collections.Generic;
24using System.Linq;
25using System.Text;
26using HeuristicLab.Hive.Contracts.Interfaces;
27using HeuristicLab.Hive.Contracts.BusinessObjects;
28using HeuristicLab.Hive.Contracts;
29using HeuristicLab.Hive.Server.DataAccess;
30using HeuristicLab.Hive.Server.Core.InternalInterfaces;
31using HeuristicLab.DataAccess.Interfaces;
32using System.Data;
33
34namespace HeuristicLab.Hive.Server.Core {
35  class JobManager: IJobManager, IInternalJobManager {
36
37    ISessionFactory factory;
38    ILifecycleManager lifecycleManager;
39
40    #region IJobManager Members
41
42    public JobManager() {
43      factory = ServiceLocator.GetSessionFactory();
44      lifecycleManager = ServiceLocator.GetLifecycleManager();
45
46      lifecycleManager.RegisterStartup(new EventHandler(lifecycleManager_OnStartup));
47      lifecycleManager.RegisterStartup(new EventHandler(lifecycleManager_OnShutdown));
48    }
49
50    private JobResult GetLastJobResult(Guid jobId) {
51      ISession session = factory.GetSessionForCurrentThread();
52
53      try {
54        IJobResultsAdapter jobResultAdapter =
55            session.GetDataAdapter<JobResult, IJobResultsAdapter>();
56
57        return jobResultAdapter.GetLastResultOf(jobId);
58      }
59      finally {
60        if (session != null)
61          session.EndSession();
62      }
63    }
64
65    public void ResetJobsDependingOnResults(Job job) {
66      ISession session = factory.GetSessionForCurrentThread();
67      ITransaction tx = null;
68
69      try {
70        IJobAdapter jobAdapter =
71            session.GetDataAdapter<Job, IJobAdapter>();
72
73        IJobResultsAdapter jobResultsAdapter =
74          session.GetDataAdapter<JobResult, IJobResultsAdapter>();
75
76        tx = session.BeginTransaction();
77
78        if (job != null) {
79          SerializedJob computableJob =
80              new SerializedJob();
81          computableJob.JobInfo =
82            job;
83
84          JobResult lastResult =
85            GetLastJobResult(job.Id);
86
87          if (lastResult != null) {
88            SerializedJobResult lastJobResult =
89              jobResultsAdapter.GetSerializedJobResult(lastResult.Id);
90
91            if (lastJobResult != null) {
92              computableJob.JobInfo.Percentage = lastJobResult.JobResult.Percentage;
93              computableJob.SerializedJobData = lastJobResult.SerializedJobResultData;
94
95              jobAdapter.UpdateSerializedJob(computableJob);
96            } else {
97              computableJob.JobInfo.Percentage = 0;
98            }
99          } else {
100            computableJob.JobInfo.Percentage = 0;
101          }
102
103          computableJob.JobInfo.Client = null;
104          computableJob.JobInfo.State = State.offline;
105
106          jobAdapter.Update(computableJob.JobInfo);
107        }
108
109        tx.Commit();
110      }
111      catch (Exception ex) {
112        if (tx != null)
113          tx.Rollback();
114        throw ex;
115      }
116      finally {
117        if (session != null)
118          session.EndSession();
119      }
120    }
121
122    void checkForDeadJobs() {
123       ISession session = factory.GetSessionForCurrentThread();
124
125       try {
126         IJobAdapter jobAdapter =
127             session.GetDataAdapter<Job, IJobAdapter>();
128
129         List<Job> allJobs = new List<Job>(jobAdapter.GetAll());
130         foreach (Job curJob in allJobs) {
131           if (curJob.State == State.calculating) {
132             ResetJobsDependingOnResults(curJob);
133           }
134         }
135       }
136       finally {
137         if (session != null)
138           session.EndSession();
139       }
140    }
141
142    void lifecycleManager_OnStartup(object sender, EventArgs e) {
143      checkForDeadJobs();
144    }
145
146    void lifecycleManager_OnShutdown(object sender, EventArgs e) {
147      checkForDeadJobs();
148    }
149
150    /// <summary>
151    /// returns all jobs stored in the database
152    /// </summary>
153    /// <returns></returns>
154    public ResponseList<Job> GetAllJobs() {
155       ISession session = factory.GetSessionForCurrentThread();
156
157       try {
158         IJobAdapter jobAdapter =
159             session.GetDataAdapter<Job, IJobAdapter>();
160
161         ResponseList<Job> response = new ResponseList<Job>();
162
163         response.List = new List<Job>(jobAdapter.GetAll());
164         response.Success = true;
165         response.StatusMessage = ApplicationConstants.RESPONSE_JOB_ALL_JOBS;
166
167         return response;
168       }
169       finally {
170         if (session != null)
171           session.EndSession();
172       }
173    }
174
175    /// <summary>
176    /// returns the job with the specified id
177    /// </summary>
178    /// <returns></returns>
179    public ResponseObject<Job> GetJobById(Guid jobId) {
180      ISession session = factory.GetSessionForCurrentThread();
181
182      try {
183        IJobAdapter jobAdapter =
184            session.GetDataAdapter<Job, IJobAdapter>();
185
186        ResponseObject<Job> response = new ResponseObject<Job>();
187
188        response.Obj = jobAdapter.GetById(jobId);
189        if (response.Obj != null) {
190          response.Success = true;
191          response.StatusMessage = ApplicationConstants.RESPONSE_JOB_GET_JOB_BY_ID;
192        } else {
193          response.Success = false;
194          response.StatusMessage = ApplicationConstants.RESPONSE_JOB_JOB_DOESNT_EXIST;
195        }
196
197        return response;
198      }
199      finally {
200        if (session != null)
201          session.EndSession();
202      }
203    }
204
205    /// <summary>
206    /// Adds a new job into the database
207    /// </summary>
208    /// <param name="job"></param>
209    /// <returns></returns>
210    public ResponseObject<Job> AddNewJob(SerializedJob job) {
211      ISession session = factory.GetSessionForCurrentThread();
212
213      try {
214        IJobAdapter jobAdapter =
215            session.GetDataAdapter<Job, IJobAdapter>();
216
217        ResponseObject<Job> response = new ResponseObject<Job>();
218
219        if (job != null && job.JobInfo != null) {
220          if (job.JobInfo.State != State.offline) {
221            response.Success = false;
222            response.StatusMessage = ApplicationConstants.RESPONSE_JOB_JOBSTATE_MUST_BE_OFFLINE;
223            return response;
224          }
225          if (job.JobInfo.Id != Guid.Empty) {
226            response.Success = false;
227            response.StatusMessage = ApplicationConstants.RESPONSE_JOB_ID_MUST_NOT_BE_SET;
228            return response;
229          }
230          if (job.SerializedJobData == null) {
231            response.StatusMessage = ApplicationConstants.RESPONSE_JOB_JOB_NULL;
232            response.Success = false;
233            return response;
234          }
235
236          job.JobInfo.DateCreated = DateTime.Now;
237          jobAdapter.UpdateSerializedJob(job);
238          response.Success = true;
239          response.Obj = job.JobInfo;
240          response.StatusMessage = ApplicationConstants.RESPONSE_JOB_JOB_ADDED;
241        } else {
242          response.Success = false;
243          response.StatusMessage = ApplicationConstants.RESPONSE_JOB_JOB_NULL;
244        }
245
246        return response;
247      }
248      finally {
249        if (session != null)
250          session.EndSession();
251      }
252    }
253
254    /// <summary>
255    /// Removes a job from the database
256    /// </summary>
257    /// <param name="jobId"></param>
258    /// <returns></returns>
259    public Response RemoveJob(Guid jobId) {
260      ISession session = factory.GetSessionForCurrentThread();
261
262      try {
263        IJobAdapter jobAdapter =
264            session.GetDataAdapter<Job, IJobAdapter>();
265        Response response = new Response();
266
267        Job job = jobAdapter.GetById(jobId);
268        if (job == null) {
269          response.Success = false;
270          response.StatusMessage = ApplicationConstants.RESPONSE_JOB_JOB_DOESNT_EXIST;
271          return response;
272        }
273        jobAdapter.Delete(job);
274        response.Success = false;
275        response.StatusMessage = ApplicationConstants.RESPONSE_JOB_JOB_REMOVED;
276
277        return response;
278      }
279      finally {
280        if (session != null)
281          session.EndSession();
282      }
283    }
284
285    public ResponseObject<JobResult> GetLastJobResultOf(Guid jobId) {
286       ResponseObject<JobResult> result =
287        new ResponseObject<JobResult>();
288
289       result.Obj =
290         GetLastJobResult(jobId);
291       result.Success =
292         result.Obj != null;
293
294       return result;
295    }
296
297    public ResponseObject<SerializedJobResult>
298      GetLastSerializedJobResultOf(Guid jobId, bool requested) {
299      ISession session = factory.GetSessionForCurrentThread();
300
301      ITransaction tx = null;
302
303      try {
304        IJobAdapter jobAdapter =
305            session.GetDataAdapter<Job, IJobAdapter>();
306
307        IJobResultsAdapter jobResultsAdapter =
308          session.GetDataAdapter<JobResult, IJobResultsAdapter>();
309
310        tx = session.BeginTransaction();
311
312        ResponseObject<SerializedJobResult> response =
313          new ResponseObject<SerializedJobResult>();
314
315        Job job = jobAdapter.GetById(jobId);
316        if (requested && (job.State == State.requestSnapshot || job.State == State.requestSnapshotSent)) {
317          response.Success = true;
318          response.StatusMessage = ApplicationConstants.RESPONSE_JOB_RESULT_NOT_YET_HERE;
319
320          tx.Commit();
321         
322          return response;
323        }
324
325        JobResult lastResult =
326          jobResultsAdapter.GetLastResultOf(job.Id);
327
328        if (lastResult != null) {
329          response.Success = true;
330          response.StatusMessage = ApplicationConstants.RESPONSE_JOB_JOB_RESULT_SENT;
331          response.Obj =
332            jobResultsAdapter.GetSerializedJobResult(
333              lastResult.Id);         
334        } else {
335          response.Success = false;
336        }
337
338        tx.Commit();
339        return response;
340      }
341      catch (Exception ex) {
342        if (tx != null)
343          tx.Rollback();
344        throw ex;
345      }
346      finally {
347        if (session != null)
348          session.EndSession();
349      }
350    }
351
352
353    public Response RequestSnapshot(Guid jobId) {
354      ISession session = factory.GetSessionForCurrentThread();
355      Response response = new Response();
356     
357      try {
358        IJobAdapter jobAdapter = session.GetDataAdapter<Job, IJobAdapter>();
359
360        Job job = jobAdapter.GetById(jobId);
361        if (job.State == State.requestSnapshot || job.State == State.requestSnapshotSent) {
362          response.Success = true;
363          response.StatusMessage = ApplicationConstants.RESPONSE_JOB_REQUEST_ALLREADY_SET;
364          return response; // no commit needed
365        }
366        if (job.State != State.calculating) {
367          response.Success = false;
368          response.StatusMessage = ApplicationConstants.RESPONSE_JOB_IS_NOT_BEEING_CALCULATED;
369          return response; // no commit needed
370        }
371        // job is in correct state
372        job.State = State.requestSnapshot;
373        jobAdapter.Update(job);
374
375        response.Success = true;
376        response.StatusMessage = ApplicationConstants.RESPONSE_JOB_REQUEST_SET;
377
378        return response;
379      }
380      finally {
381        if (session != null)
382          session.EndSession();
383      }
384    }
385
386    public Response AbortJob(Guid jobId) {
387      ISession session = factory.GetSessionForCurrentThread();
388      Response response = new Response();
389
390      try {
391        IJobAdapter jobAdapter = session.GetDataAdapter<Job, IJobAdapter>();
392
393        Job job = jobAdapter.GetById(jobId);
394        if (job == null) {
395          response.Success = false;
396          response.StatusMessage = ApplicationConstants.RESPONSE_JOB_JOB_DOESNT_EXIST;
397          return response; // no commit needed
398        }
399        if (job.State == State.abort) {
400          response.Success = true;
401          response.StatusMessage = ApplicationConstants.RESPONSE_JOB_ABORT_REQUEST_ALLREADY_SET;
402          return response; // no commit needed
403        }
404        if (job.State != State.calculating && job.State != State.requestSnapshot && job.State != State.requestSnapshotSent) {
405          response.Success = false;
406          response.StatusMessage = ApplicationConstants.RESPONSE_JOB_IS_NOT_BEEING_CALCULATED;
407          return response; // no commit needed
408        }
409        // job is in correct state
410        job.State = State.abort;
411        jobAdapter.Update(job);
412
413        response.Success = true;
414        response.StatusMessage = ApplicationConstants.RESPONSE_JOB_ABORT_REQUEST_SET;
415
416        return response;
417      }
418      finally {
419        if (session != null)
420          session.EndSession();
421      }
422    }
423
424    public ResponseList<JobResult> GetAllJobResults(Guid jobId) {
425      ISession session = factory.GetSessionForCurrentThread();
426      ResponseList<JobResult> response = new ResponseList<JobResult>();
427
428      try {
429        IJobResultsAdapter jobResultAdapter =
430            session.GetDataAdapter<JobResult, IJobResultsAdapter>();
431        IJobAdapter jobAdapter = session.GetDataAdapter<Job, IJobAdapter>();
432
433        Job job = jobAdapter.GetById(jobId);
434        if (job == null) {
435          response.Success = false;
436          response.StatusMessage = ApplicationConstants.RESPONSE_JOB_JOB_DOESNT_EXIST;
437          return response;
438        }
439        response.List = new List<JobResult>(jobResultAdapter.GetResultsOf(job.Id));
440        response.Success = true;
441        response.StatusMessage = ApplicationConstants.RESPONSE_JOB_JOB_RESULT_SENT;
442
443        return response;
444      }
445      finally {
446        if(session != null)
447          session.EndSession();
448      }
449    }
450
451    public ResponseList<Project> GetAllProjects() {
452      ISession session = factory.GetSessionForCurrentThread();
453      ResponseList<Project> response = new ResponseList<Project>();
454
455      try {
456        IProjectAdapter projectAdapter =
457          session.GetDataAdapter<Project, IProjectAdapter>();
458
459        List<Project> allProjects = new List<Project>(projectAdapter.GetAll());
460        response.List = allProjects;
461        response.Success = true;
462        return response;
463      }
464      finally {
465        if (session != null)
466          session.EndSession();
467      }
468    }
469
470    private Response createUpdateProject(Project project) {
471      ISession session = factory.GetSessionForCurrentThread();
472      Response response = new Response();
473      ITransaction tx = null;
474
475      try {
476        IProjectAdapter projectAdapter =
477          session.GetDataAdapter<Project, IProjectAdapter>();
478
479        if (project.Name == null || project.Name == "") {
480          response.Success = false;
481          response.StatusMessage = ApplicationConstants.RESPONSE_JOB_PROJECT_NAME_EMPTY;
482          return response;
483        }
484        tx = session.BeginTransaction();
485        projectAdapter.Update(project);
486
487        tx.Commit();
488        response.Success = true;
489        response.StatusMessage = ApplicationConstants.RESPONSE_JOB_PROJECT_ADDED;
490      } catch (ConstraintException ce) {
491        if (tx != null)
492          tx.Rollback();
493        response.Success = false;
494        response.StatusMessage = ce.Message;
495      }
496      catch (Exception ex) {
497        if (tx != null)
498          tx.Rollback();
499        throw ex;
500      }
501      finally {
502        if (session != null)
503          session.EndSession();
504      }
505      return response;
506    }
507
508    public Response CreateProject(Project project) {
509      return createUpdateProject(project);
510    }
511
512    public Response ChangeProject(Project project) {
513      return createUpdateProject(project);
514    }
515
516    public Response DeleteProject(Guid projectId) {
517      ISession session = factory.GetSessionForCurrentThread();
518      Response response = new Response();
519      ITransaction tx = null;
520
521      try {
522        IProjectAdapter projectAdapter =
523          session.GetDataAdapter<Project, IProjectAdapter>();
524
525        Project project = projectAdapter.GetById(projectId);
526        if (project == null) {
527          response.Success = false;
528          response.StatusMessage = ApplicationConstants.RESPONSE_JOB_PROJECT_DOESNT_EXIST;
529          return response;
530        }
531        projectAdapter.Delete(project);
532        tx.Commit();
533        response.Success = true;
534        response.StatusMessage = ApplicationConstants.RESPONSE_JOB_PROJECT_DELETED;
535      }
536      catch (Exception e) {
537        if (tx != null)
538          tx.Rollback();
539        response.Success = false;
540        response.StatusMessage = e.Message;
541      }
542      finally {
543        if (session != null)
544          session.EndSession();
545      }
546      return response;
547    }
548
549    public ResponseList<Job> GetJobsByProject(Guid projectId) {
550      ISession session = factory.GetSessionForCurrentThread();
551      ResponseList<Job> response = new ResponseList<Job>();
552
553      try {
554        IJobAdapter jobAdapter =
555          session.GetDataAdapter<Job, IJobAdapter>();
556        List<Job> jobsByProject = new List<Job>(jobAdapter.GetJobsByProject(projectId));
557        response.List = jobsByProject;
558        response.Success = true;
559      }
560      finally {
561        if (session != null)
562          session.EndSession();
563      }
564      return response;
565    }
566
567    #endregion
568  }
569}
Note: See TracBrowser for help on using the repository browser.