source: trunk/sources/HeuristicLab.Hive.Server.Core/3.2/JobManager.cs @ 1831

Last change on this file since 1831 was 1831, checked in by msteinbi, 12 years ago

corrected job state handling (#466)

File size: 11.6 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;
32
33namespace HeuristicLab.Hive.Server.Core {
34  class JobManager: IJobManager, IInternalJobManager {
35
36    ISessionFactory factory;
37    ILifecycleManager lifecycleManager;
38
39    #region IJobManager Members
40
41    public JobManager() {
42      factory = ServiceLocator.GetSessionFactory();
43      lifecycleManager = ServiceLocator.GetLifecycleManager();
44
45      lifecycleManager.RegisterStartup(new EventHandler(lifecycleManager_OnStartup));
46      lifecycleManager.RegisterStartup(new EventHandler(lifecycleManager_OnShutdown));
47    }
48
49    private JobResult GetLastJobResult(Job job) {
50      ISession session = factory.GetSessionForCurrentThread();
51
52      try {
53        IJobResultsAdapter jobResultAdapter =
54            session.GetDataAdapter<JobResult, IJobResultsAdapter>();
55
56        List<JobResult> allJobResults = new List<JobResult>(jobResultAdapter.GetResultsOf(job));
57        JobResult lastJobResult = null;
58        foreach (JobResult jR in allJobResults) {
59          // if lastJobResult was before the current jobResult the lastJobResult must be updated
60          if (lastJobResult == null ||
61              (jR.Timestamp > lastJobResult.Timestamp))
62            lastJobResult = jR;
63        }
64        return lastJobResult;
65      }
66      finally {
67        if (session != null)
68          session.EndSession();
69      }
70    }
71
72    public void ResetJobsDependingOnResults(Job job) {
73      ISession session = factory.GetSessionForCurrentThread();
74
75      try {
76        IJobAdapter jobAdapter =
77            session.GetDataAdapter<Job, IJobAdapter>();
78
79        JobResult lastJobResult = GetLastJobResult(job);
80        if (lastJobResult != null) {
81          job.Percentage = lastJobResult.Percentage;
82          job.SerializedJob = lastJobResult.Result;
83        } else {
84          job.Percentage = 0;
85        }
86
87        job.Client = null;
88        job.State = State.offline;
89
90        jobAdapter.Update(job);
91      }
92      finally {
93        if (session != null)
94          session.EndSession();
95      }
96    }
97
98    void checkForDeadJobs() {
99       ISession session = factory.GetSessionForCurrentThread();
100
101       try {
102         IJobAdapter jobAdapter =
103             session.GetDataAdapter<Job, IJobAdapter>();
104
105         List<Job> allJobs = new List<Job>(jobAdapter.GetAll());
106         foreach (Job curJob in allJobs) {
107           if (curJob.State == State.calculating) {
108             ResetJobsDependingOnResults(curJob);
109           }
110         }
111       }
112       finally {
113         if (session != null)
114           session.EndSession();
115       }
116    }
117
118    void lifecycleManager_OnStartup(object sender, EventArgs e) {
119      checkForDeadJobs();
120    }
121
122    void lifecycleManager_OnShutdown(object sender, EventArgs e) {
123      checkForDeadJobs();
124    }
125
126    /// <summary>
127    /// returns all jobs stored in the database
128    /// </summary>
129    /// <returns></returns>
130    public ResponseList<Job> GetAllJobs() {
131       ISession session = factory.GetSessionForCurrentThread();
132
133       try {
134         IJobAdapter jobAdapter =
135             session.GetDataAdapter<Job, IJobAdapter>();
136
137         ResponseList<Job> response = new ResponseList<Job>();
138
139         response.List = new List<Job>(jobAdapter.GetAll());
140         response.Success = true;
141         response.StatusMessage = ApplicationConstants.RESPONSE_JOB_ALL_JOBS;
142
143         return response;
144       }
145       finally {
146         if (session != null)
147           session.EndSession();
148       }
149    }
150
151    /// <summary>
152    /// Adds a new job into the database
153    /// </summary>
154    /// <param name="job"></param>
155    /// <returns></returns>
156    public ResponseObject<Job> AddNewJob(Job job) {
157      ISession session = factory.GetSessionForCurrentThread();
158
159      try {
160        IJobAdapter jobAdapter =
161            session.GetDataAdapter<Job, IJobAdapter>();
162
163        ResponseObject<Job> response = new ResponseObject<Job>();
164
165        if (job != null) {
166          if (job.State != State.offline) {
167            response.Success = false;
168            response.StatusMessage = ApplicationConstants.RESPONSE_JOB_JOBSTATE_MUST_BE_OFFLINE;
169            return response;
170          }
171          if (job.Id != Guid.Empty) {
172            response.Success = false;
173            response.StatusMessage = ApplicationConstants.RESPONSE_JOB_ID_MUST_NOT_BE_SET;
174            return response;
175          }
176          if (job.SerializedJob == null) {
177            response.StatusMessage = ApplicationConstants.RESPONSE_JOB_JOB_NULL;
178            response.Success = false;
179            return response;
180          }
181
182          job.DateCreated = DateTime.Now;
183          jobAdapter.Update(job);
184          response.Success = true;
185          response.Obj = job;
186          response.StatusMessage = ApplicationConstants.RESPONSE_JOB_JOB_ADDED;
187        } else {
188          response.Success = false;
189          response.StatusMessage = ApplicationConstants.RESPONSE_JOB_JOB_NULL;
190        }
191
192        return response;
193      }
194      finally {
195        if (session != null)
196          session.EndSession();
197      }
198    }
199
200    /// <summary>
201    /// Removes a job from the database
202    /// </summary>
203    /// <param name="jobId"></param>
204    /// <returns></returns>
205    public Response RemoveJob(Guid jobId) {
206      ISession session = factory.GetSessionForCurrentThread();
207
208      try {
209        IJobAdapter jobAdapter =
210            session.GetDataAdapter<Job, IJobAdapter>();
211        Response response = new Response();
212
213        Job job = jobAdapter.GetById(jobId);
214        if (job == null) {
215          response.Success = false;
216          response.StatusMessage = ApplicationConstants.RESPONSE_JOB_JOB_DOESNT_EXIST;
217          return response;
218        }
219        jobAdapter.Delete(job);
220        response.Success = false;
221        response.StatusMessage = ApplicationConstants.RESPONSE_JOB_JOB_REMOVED;
222
223        return response;
224      }
225      finally {
226        if (session != null)
227          session.EndSession();
228      }
229    }
230
231    public ResponseObject<JobResult> GetLastJobResultOf(Guid jobId, bool requested) {
232      ISession session = factory.GetSessionForCurrentThread();
233
234      try {
235        IJobAdapter jobAdapter =
236            session.GetDataAdapter<Job, IJobAdapter>();
237
238        ResponseObject<JobResult> response = new ResponseObject<JobResult>();
239
240        Job job = jobAdapter.GetById(jobId);
241        if (requested && (job.State == State.requestSnapshot || job.State == State.requestSnapshotSent)) {
242          response.Success = true;
243          response.StatusMessage = ApplicationConstants.RESPONSE_JOB_RESULT_NOT_YET_HERE;
244          return response;
245        }
246         
247        response.Success = true;
248        response.StatusMessage = ApplicationConstants.RESPONSE_JOB_JOB_RESULT_SENT;
249        response.Obj = GetLastJobResult(job);
250
251        return response;
252      }
253      finally {
254        if(session != null)
255          session.EndSession();
256      }
257    }
258
259    public Response RequestSnapshot(Guid jobId) {
260      ISession session = factory.GetSessionForCurrentThread();
261      Response response = new Response();
262     
263      try {
264        IJobAdapter jobAdapter = session.GetDataAdapter<Job, IJobAdapter>();
265
266        Job job = jobAdapter.GetById(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; // no commit needed
271        }
272        if (job.State != State.calculating) {
273          response.Success = false;
274          response.StatusMessage = ApplicationConstants.RESPONSE_JOB_IS_NOT_BEEING_CALCULATED;
275          return response; // no commit needed
276        }
277        // job is in correct state
278        job.State = State.requestSnapshot;
279        jobAdapter.Update(job);
280
281        response.Success = true;
282        response.StatusMessage = ApplicationConstants.RESPONSE_JOB_REQUEST_SET;
283
284        return response;
285      }
286      finally {
287        if (session != null)
288          session.EndSession();
289      }
290    }
291
292    public Response AbortJob(Guid jobId) {
293      ISession session = factory.GetSessionForCurrentThread();
294      Response response = new Response();
295
296      try {
297        IJobAdapter jobAdapter = session.GetDataAdapter<Job, IJobAdapter>();
298
299        Job job = jobAdapter.GetById(jobId);
300        if (job == null) {
301          response.Success = false;
302          response.StatusMessage = ApplicationConstants.RESPONSE_JOB_JOB_DOESNT_EXIST;
303          return response; // no commit needed
304        }
305        if (job.State == State.abort) {
306          response.Success = true;
307          response.StatusMessage = ApplicationConstants.RESPONSE_JOB_ABORT_REQUEST_ALLREADY_SET;
308          return response; // no commit needed
309        }
310        if (job.State != State.calculating && job.State != State.requestSnapshot && job.State != State.requestSnapshotSent) {
311          response.Success = false;
312          response.StatusMessage = ApplicationConstants.RESPONSE_JOB_IS_NOT_BEEING_CALCULATED;
313          return response; // no commit needed
314        }
315        // job is in correct state
316        job.State = State.abort;
317        jobAdapter.Update(job);
318
319        response.Success = true;
320        response.StatusMessage = ApplicationConstants.RESPONSE_JOB_ABORT_REQUEST_SET;
321
322        return response;
323      }
324      finally {
325        if (session != null)
326          session.EndSession();
327      }
328    }
329
330    public ResponseList<JobResult> GetAllJobResults(Guid jobId) {
331      ISession session = factory.GetSessionForCurrentThread();
332      ResponseList<JobResult> response = new ResponseList<JobResult>();
333
334      try {
335        IJobResultsAdapter jobResultAdapter =
336            session.GetDataAdapter<JobResult, IJobResultsAdapter>();
337        IJobAdapter jobAdapter = session.GetDataAdapter<Job, IJobAdapter>();
338
339        Job job = jobAdapter.GetById(jobId);
340        if (job == null) {
341          response.Success = false;
342          response.StatusMessage = ApplicationConstants.RESPONSE_JOB_JOB_DOESNT_EXIST;
343          return response;
344        }
345        response.List = new List<JobResult>(jobResultAdapter.GetResultsOf(job));
346        response.Success = true;
347        response.StatusMessage = ApplicationConstants.RESPONSE_JOB_JOB_RESULT_SENT;
348
349        return response;
350      }
351      finally {
352        if(session != null)
353          session.EndSession();
354      }
355    }
356     
357    #endregion
358  }
359}
Note: See TracBrowser for help on using the repository browser.