Free cookie consent management tool by TermsFeed Policy Generator

source: branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Services.Hive.DataAccess/3.4/HiveDao.cs @ 5593

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

#1233

  • changed the way lifecycle methods are called. The new service method TriggerLifecycle checks when the latest cleanup was made and performs one (if necessary). This can also be called by an external program (like a windows task)
  • robustified logging
File size: 21.9 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2010 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.Linq.Expressions;
26
27namespace HeuristicLab.Services.Hive.DataAccess {
28  using HeuristicLab.Services.Hive.Common.DataTransfer;
29  using HeuristicLab.Services.Hive.DataAccess.Properties;
30  using DT = HeuristicLab.Services.Hive.Common.DataTransfer;
31
32  public class HiveDao : IHiveDao {
33    public static HiveDataContext CreateContext() {
34      return new HiveDataContext(Settings.Default.HeuristicLab_Hive_LinqConnectionString);
35    }
36
37    public HiveDao() {
38    }
39
40    #region Job Methods
41    public DT.Job GetJob(Guid id) {
42      using (var db = CreateContext()) {
43        return Convert.ToDto(db.Jobs.SingleOrDefault(x => x.JobId == id));
44      }
45    }
46
47    public IEnumerable<DT.Job> GetJobs(Expression<Func<Job, bool>> predicate) {
48      using (var db = CreateContext()) {
49        return db.Jobs.Where(predicate).Select(x => Convert.ToDto(x)).ToArray();
50      }
51    }
52
53    public Guid AddJob(DT.Job dto) {
54      using (var db = CreateContext()) {
55        var entity = Convert.ToEntity(dto);
56        db.Jobs.InsertOnSubmit(entity);
57        db.SubmitChanges();
58        foreach (Guid pluginId in dto.PluginsNeededIds) {
59          db.RequiredPlugins.InsertOnSubmit(new RequiredPlugin() { JobId = entity.JobId, PluginId = pluginId });
60        }
61        db.SubmitChanges();
62        return entity.JobId;
63      }
64    }
65
66    public void UpdateJob(DT.Job dto) {
67      using (var db = CreateContext()) {
68        var entity = db.Jobs.FirstOrDefault(x => x.JobId == dto.Id);
69        if (entity == null) db.Jobs.InsertOnSubmit(Convert.ToEntity(dto));
70        else Convert.ToEntity(dto, entity);
71        // todo: update required plugins
72        db.SubmitChanges();
73      }
74    }
75
76    public void DeleteJob(Guid id) {
77      using (var db = CreateContext()) {
78        var entity = db.Jobs.FirstOrDefault(x => x.JobId == id);
79        if (entity != null) db.Jobs.DeleteOnSubmit(entity);
80        db.SubmitChanges(); // JobData and child jobs are deleted by db-trigger
81      }
82    }
83
84    /// <summary>
85    /// returns all parent jobs which are waiting for their child jobs to finish
86    /// </summary>
87    /// <param name="resourceIds">list of resourceids which for which the jobs should be valid</param>
88    /// <param name="count">maximum number of jobs to return</param>
89    /// <param name="finished">if true, all parent jobs which have FinishWhenChildJobsFinished=true are returned, otherwise only FinishWhenChildJobsFinished=false are returned</param>
90    /// <returns></returns>
91    public IEnumerable<DT.Job> GetParentJobs(IEnumerable<Guid> resourceIds, int count, bool finished) {
92      using (var db = CreateContext()) {
93        var query = from ar in db.AssignedResources
94                    where resourceIds.Contains(ar.ResourceId)
95                       && ar.Job.State == JobState.Waiting
96                       && ar.Job.IsParentJob
97                       && (finished ? ar.Job.FinishWhenChildJobsFinished : !ar.Job.FinishWhenChildJobsFinished)
98                       && (from child in db.Jobs
99                           where child.ParentJobId == ar.Job.JobId
100                           select child.State == JobState.Finished).All(x => x)
101                       && (from child in db.Jobs // avoid returning WaitForChildJobs jobs where no child-jobs exist (yet)
102                           where child.ParentJobId == ar.Job.JobId
103                           select child).Count() > 0
104                    orderby ar.Job.Priority descending
105                    select Convert.ToDto(ar.Job);
106        return count == 0 ? query.ToArray() : query.Take(count).ToArray();
107      }
108    }
109
110    public IEnumerable<DT.Job> GetWaitingJobs(DT.Slave slave, int count) {
111      using (var db = CreateContext()) {
112        var resourceIds = GetParentResources(slave.Id).Select(r => r.Id);
113        var waitingParentJobs = GetParentJobs(resourceIds, count, false);
114        if (count > 0 && waitingParentJobs.Count() >= count) return waitingParentJobs.Take(count).ToArray();
115
116        var query = from ar in db.AssignedResources
117                    where resourceIds.Contains(ar.ResourceId)
118                       && !(ar.Job.IsParentJob && ar.Job.FinishWhenChildJobsFinished)
119                       && ar.Job.State == JobState.Waiting
120                       && ar.Job.CoresNeeded <= slave.FreeCores
121                       && ar.Job.MemoryNeeded <= slave.FreeMemory
122                    orderby ar.Job.Priority descending
123                    select Convert.ToDto(ar.Job);
124        var waitingJobs = (count == 0 ? query : query.Take(count)).ToArray();
125        return waitingJobs.Union(waitingParentJobs).OrderByDescending(x => x.Priority);
126      }
127    }
128    #endregion
129
130    #region JobData Methods
131
132    public DT.JobData GetJobData(Guid id) {
133      using (var db = CreateContext()) {
134        return Convert.ToDto(db.JobDatas.SingleOrDefault(x => x.JobId == id));
135      }
136    }
137
138    public IEnumerable<DT.JobData> GetJobDatas(Expression<Func<JobData, bool>> predicate) {
139      using (var db = CreateContext()) {
140        return db.JobDatas.Where(predicate).Select(x => Convert.ToDto(x)).ToArray();
141      }
142    }
143
144    public Guid AddJobData(DT.JobData dto) {
145      using (var db = CreateContext()) {
146        var entity = Convert.ToEntity(dto);
147        db.JobDatas.InsertOnSubmit(entity);
148        db.SubmitChanges();
149        return entity.JobId;
150      }
151    }
152
153    public void UpdateJobData(DT.JobData dto) {
154      using (var db = CreateContext()) {
155        var entity = db.JobDatas.FirstOrDefault(x => x.JobId == dto.JobId);
156        if (entity == null) db.JobDatas.InsertOnSubmit(Convert.ToEntity(dto));
157        else Convert.ToEntity(dto, entity);
158        db.SubmitChanges();
159      }
160    }
161
162    public void DeleteJobData(Guid id) {
163      using (var db = CreateContext()) {
164        var entity = db.JobDatas.FirstOrDefault(x => x.JobId == id); // check if all the byte[] is loaded into memory here. otherwise work around to delete without loading it
165        if (entity != null) db.JobDatas.DeleteOnSubmit(entity);
166        db.SubmitChanges();
167      }
168    }
169    #endregion
170
171    #region StateLog Methods
172
173    public DT.StateLog GetStateLog(Guid id) {
174      using (var db = CreateContext()) {
175        return Convert.ToDto(db.StateLogs.SingleOrDefault(x => x.StateLogId == id));
176      }
177    }
178
179    public IEnumerable<DT.StateLog> GetStateLogs(Expression<Func<StateLog, bool>> predicate) {
180      using (var db = CreateContext()) {
181        return db.StateLogs.Where(predicate).Select(x => Convert.ToDto(x)).ToArray();
182      }
183    }
184
185    public Guid AddStateLog(DT.StateLog dto) {
186      using (var db = CreateContext()) {
187        var entity = Convert.ToEntity(dto);
188        db.StateLogs.InsertOnSubmit(entity);
189        db.SubmitChanges();
190        return entity.StateLogId;
191      }
192    }
193
194    public void UpdateStateLog(DT.StateLog dto) {
195      using (var db = CreateContext()) {
196        var entity = db.StateLogs.FirstOrDefault(x => x.StateLogId == dto.Id);
197        if (entity == null) db.StateLogs.InsertOnSubmit(Convert.ToEntity(dto));
198        else Convert.ToEntity(dto, entity);
199        db.SubmitChanges();
200      }
201    }
202
203    public void DeleteStateLog(Guid id) {
204      using (var db = CreateContext()) {
205        var entity = db.StateLogs.FirstOrDefault(x => x.StateLogId == id);
206        if (entity != null) db.StateLogs.DeleteOnSubmit(entity);
207        db.SubmitChanges();
208      }
209    }
210    #endregion
211
212    #region HiveExperiment Methods
213    public DT.HiveExperiment GetHiveExperiment(Guid id) {
214      using (var db = CreateContext()) {
215        return Convert.ToDto(db.HiveExperiments.SingleOrDefault(x => x.HiveExperimentId == id));
216      }
217    }
218
219    public IEnumerable<DT.HiveExperiment> GetHiveExperiments(Expression<Func<HiveExperiment, bool>> predicate) {
220      using (var db = CreateContext()) {
221        return db.HiveExperiments.Where(predicate).Select(x => Convert.ToDto(x)).ToArray();
222      }
223    }
224
225    public Guid AddHiveExperiment(DT.HiveExperiment dto) {
226      using (var db = CreateContext()) {
227        var entity = Convert.ToEntity(dto);
228        db.HiveExperiments.InsertOnSubmit(entity);
229        db.SubmitChanges();
230        return entity.HiveExperimentId;
231      }
232    }
233
234    public void UpdateHiveExperiment(DT.HiveExperiment dto) {
235      using (var db = CreateContext()) {
236        var entity = db.HiveExperiments.FirstOrDefault(x => x.HiveExperimentId == dto.Id);
237        if (entity == null) db.HiveExperiments.InsertOnSubmit(Convert.ToEntity(dto));
238        else Convert.ToEntity(dto, entity);
239        db.SubmitChanges();
240      }
241    }
242
243    public void DeleteHiveExperiment(Guid id) {
244      using (var db = CreateContext()) {
245        var entity = db.HiveExperiments.FirstOrDefault(x => x.HiveExperimentId == id);
246        if (entity != null) db.HiveExperiments.DeleteOnSubmit(entity);
247        db.SubmitChanges();
248      }
249    }
250    #endregion
251
252    #region HiveExperimentPermission Methods
253
254    public DT.HiveExperimentPermission GetHiveExperimentPermission(Guid hiveExperimentId, Guid grantedUserId) {
255      using (var db = CreateContext()) {
256        return Convert.ToDto(db.HiveExperimentPermissions.SingleOrDefault(x => x.HiveExperimentId == hiveExperimentId && x.GrantedUserId == grantedUserId));
257      }
258    }
259
260    public IEnumerable<DT.HiveExperimentPermission> GetHiveExperimentPermissions(Expression<Func<HiveExperimentPermission, bool>> predicate) {
261      using (var db = CreateContext()) {
262        return db.HiveExperimentPermissions.Where(predicate).Select(x => Convert.ToDto(x)).ToArray();
263      }
264    }
265
266    public void AddHiveExperimentPermission(DT.HiveExperimentPermission dto) {
267      using (var db = CreateContext()) {
268        var entity = Convert.ToEntity(dto);
269        db.HiveExperimentPermissions.InsertOnSubmit(entity);
270        db.SubmitChanges();
271      }
272    }
273
274    public void UpdateHiveExperimentPermission(DT.HiveExperimentPermission dto) {
275      using (var db = CreateContext()) {
276        var entity = db.HiveExperimentPermissions.FirstOrDefault(x => x.HiveExperimentId == dto.HiveExperimentId && x.GrantedUserId == dto.GrantedUserId);
277        if (entity == null) db.HiveExperimentPermissions.InsertOnSubmit(Convert.ToEntity(dto));
278        else Convert.ToEntity(dto, entity);
279        db.SubmitChanges();
280      }
281    }
282
283    public void DeleteHiveExperimentPermission(Guid hiveExperimentId, Guid grantedUserId) {
284      using (var db = CreateContext()) {
285        var entity = db.HiveExperimentPermissions.FirstOrDefault(x => x.HiveExperimentId == hiveExperimentId && x.GrantedUserId == grantedUserId);
286        if (entity != null) db.HiveExperimentPermissions.DeleteOnSubmit(entity);
287        db.SubmitChanges();
288      }
289    }
290
291    #endregion
292
293    #region Plugin Methods
294    public DT.Plugin GetPlugin(Guid id) {
295      using (var db = CreateContext()) {
296        return Convert.ToDto(db.Plugins.SingleOrDefault(x => x.PluginId == id));
297      }
298    }
299
300    public IEnumerable<DT.Plugin> GetPlugins(Expression<Func<Plugin, bool>> predicate) {
301      using (var db = CreateContext()) {
302        return db.Plugins.Where(predicate).Select(x => Convert.ToDto(x)).ToArray();
303      }
304    }
305
306    public Guid AddPlugin(DT.Plugin dto) {
307      using (var db = CreateContext()) {
308        var entity = Convert.ToEntity(dto);
309        db.Plugins.InsertOnSubmit(entity);
310        db.SubmitChanges();
311        return entity.PluginId;
312      }
313    }
314
315    public void UpdatePlugin(DT.Plugin dto) {
316      using (var db = CreateContext()) {
317        var entity = db.Plugins.FirstOrDefault(x => x.PluginId == dto.Id);
318        if (entity == null) db.Plugins.InsertOnSubmit(Convert.ToEntity(dto));
319        else Convert.ToEntity(dto, entity);
320        db.SubmitChanges();
321      }
322    }
323
324    public void DeletePlugin(Guid id) {
325      using (var db = CreateContext()) {
326        var entity = db.Plugins.FirstOrDefault(x => x.PluginId == id);
327        if (entity != null) db.Plugins.DeleteOnSubmit(entity);
328        db.SubmitChanges();
329      }
330    }
331    #endregion
332
333    #region PluginData Methods
334
335    public DT.PluginData GetPluginData(Guid id) {
336      using (var db = CreateContext()) {
337        return Convert.ToDto(db.PluginDatas.SingleOrDefault(x => x.PluginDataId == id));
338      }
339    }
340
341    public IEnumerable<DT.PluginData> GetPluginDatas(Expression<Func<PluginData, bool>> predicate) {
342      using (var db = CreateContext()) {
343        return db.PluginDatas.Where(predicate).Select(x => Convert.ToDto(x)).ToArray();
344      }
345    }
346
347    public Guid AddPluginData(DT.PluginData dto) {
348      using (var db = CreateContext()) {
349        var entity = Convert.ToEntity(dto);
350        db.PluginDatas.InsertOnSubmit(entity);
351        db.SubmitChanges();
352        return entity.PluginDataId;
353      }
354    }
355
356    public void UpdatePluginData(DT.PluginData dto) {
357      using (var db = CreateContext()) {
358        var entity = db.PluginDatas.FirstOrDefault(x => x.PluginId == dto.PluginId);
359        if (entity == null) db.PluginDatas.InsertOnSubmit(Convert.ToEntity(dto));
360        else Convert.ToEntity(dto, entity);
361        db.SubmitChanges();
362      }
363    }
364
365    public void DeletePluginData(Guid id) {
366      using (var db = CreateContext()) {
367        var entity = db.PluginDatas.FirstOrDefault(x => x.PluginDataId == id); // todo: check if all the byte[] is loaded into memory here. otherwise work around to delete without loading it
368        if (entity != null) db.PluginDatas.DeleteOnSubmit(entity);
369        db.SubmitChanges();
370      }
371    }
372    #endregion
373
374    #region Slave Methods
375    public DT.Slave GetSlave(Guid id) {
376      using (var db = CreateContext()) {
377        return Convert.ToDto(db.Resources.OfType<Slave>().SingleOrDefault(x => x.ResourceId == id));
378      }
379    }
380
381    public IEnumerable<DT.Slave> GetSlaves(Expression<Func<Slave, bool>> predicate) {
382      using (var db = CreateContext()) {
383        return db.Resources.OfType<Slave>().Where(predicate).Select(x => Convert.ToDto(x)).ToArray();
384      }
385    }
386
387    public Guid AddSlave(DT.Slave dto) {
388      using (var db = CreateContext()) {
389        var entity = Convert.ToEntity(dto);
390        db.Resources.InsertOnSubmit(entity);
391        db.SubmitChanges();
392        return entity.ResourceId;
393      }
394    }
395
396    public void UpdateSlave(DT.Slave dto) {
397      using (var db = CreateContext()) {
398        var entity = db.Resources.OfType<Slave>().FirstOrDefault(x => x.ResourceId == dto.Id);
399        if (entity == null) db.Resources.InsertOnSubmit(Convert.ToEntity(dto));
400        else Convert.ToEntity(dto, entity);
401        db.SubmitChanges();
402      }
403    }
404
405    public void DeleteSlave(Guid id) {
406      using (var db = CreateContext()) {
407        var entity = db.Resources.OfType<Slave>().FirstOrDefault(x => x.ResourceId == id);
408        if (entity != null) db.Resources.DeleteOnSubmit(entity);
409        db.SubmitChanges();
410      }
411    }
412    #endregion
413
414    #region SlaveGroup Methods
415    public DT.SlaveGroup GetSlaveGroup(Guid id) {
416      using (var db = CreateContext()) {
417        return Convert.ToDto(db.Resources.OfType<SlaveGroup>().SingleOrDefault(x => x.ResourceId == id));
418      }
419    }
420
421    public IEnumerable<DT.SlaveGroup> GetSlaveGroups(Expression<Func<SlaveGroup, bool>> predicate) {
422      using (var db = CreateContext()) {
423        return db.Resources.OfType<SlaveGroup>().Where(predicate).Select(x => Convert.ToDto(x)).ToArray();
424      }
425    }
426
427    public Guid AddSlaveGroup(DT.SlaveGroup dto) {
428      using (var db = CreateContext()) {
429        if (dto.Id == Guid.Empty)
430          dto.Id = Guid.NewGuid();
431        var entity = Convert.ToEntity(dto);
432        db.Resources.InsertOnSubmit(entity);
433        db.SubmitChanges();
434        return entity.ResourceId;
435      }
436    }
437
438    public void UpdateSlaveGroup(DT.SlaveGroup dto) {
439      using (var db = CreateContext()) {
440        var entity = db.Resources.OfType<SlaveGroup>().FirstOrDefault(x => x.ResourceId == dto.Id);
441        if (entity == null) db.Resources.InsertOnSubmit(Convert.ToEntity(dto));
442        else Convert.ToEntity(dto, entity);
443        db.SubmitChanges();
444      }
445    }
446
447    public void DeleteSlaveGroup(Guid id) {
448      using (var db = CreateContext()) {
449        var entity = db.Resources.OfType<SlaveGroup>().FirstOrDefault(x => x.ResourceId == id);
450        if (entity != null) {
451          if (db.Resources.Where(r => r.ParentResourceId == id).Count() > 0) {
452            throw new DaoException("Cannot delete SlaveGroup as long as there are Slaves in the group");
453          }
454          db.Resources.DeleteOnSubmit(entity);
455        }
456        db.SubmitChanges();
457      }
458    }
459    #endregion
460
461    #region Resource Methods
462    public DT.Resource GetResource(Guid id) {
463      using (var db = CreateContext()) {
464        return Convert.ToDto(db.Resources.SingleOrDefault(x => x.ResourceId == id));
465      }
466    }
467
468    public IEnumerable<DT.Resource> GetResources(Expression<Func<Resource, bool>> predicate) {
469      using (var db = CreateContext()) {
470        return db.Resources.Where(predicate).Select(x => Convert.ToDto(x)).ToArray();
471      }
472    }
473
474    public Guid AddResource(DT.Resource dto) {
475      using (var db = CreateContext()) {
476        var entity = Convert.ToEntity(dto);
477        db.Resources.InsertOnSubmit(entity);
478        db.SubmitChanges();
479        return entity.ResourceId;
480      }
481    }
482
483    public void UpdateResource(DT.Resource dto) {
484      using (var db = CreateContext()) {
485        var entity = db.Resources.FirstOrDefault(x => x.ResourceId == dto.Id);
486        if (entity == null) db.Resources.InsertOnSubmit(Convert.ToEntity(dto));
487        else Convert.ToEntity(dto, entity);
488        db.SubmitChanges();
489      }
490    }
491
492    public void DeleteResource(Guid id) {
493      using (var db = CreateContext()) {
494        var entity = db.Resources.FirstOrDefault(x => x.ResourceId == id);
495        if (entity != null) db.Resources.DeleteOnSubmit(entity);
496        db.SubmitChanges();
497      }
498    }
499
500    public void AssignJobToResource(Guid jobId, Guid resourceId) {
501      using (var db = CreateContext()) {
502        var job = db.Jobs.Where(x => x.JobId == jobId).Single();
503        job.AssignedResources.Add(new AssignedResource() { JobId = jobId, ResourceId = resourceId });
504        db.SubmitChanges();
505      }
506    }
507
508    public IEnumerable<DT.Resource> GetAssignedResources(Guid jobId) {
509      using (var db = CreateContext()) {
510        var job = db.Jobs.Where(x => x.JobId == jobId).Single();
511        return job.AssignedResources.Select(x => Convert.ToDto(x.Resource)).ToArray();
512      }
513    }
514
515    /// <summary>
516    /// Returns all parent resources of a resource (the given resource is also added)
517    /// </summary>
518    private IEnumerable<DT.Resource> GetParentResources(Guid resourceId) {
519      using (var db = CreateContext()) {
520        var resources = new List<Resource>();
521        CollectParentResources(resources, db.Resources.Where(r => r.ResourceId == resourceId).Single());
522        return resources.Select(r => Convert.ToDto(r)).ToArray();
523      }
524    }
525
526    private void CollectParentResources(List<Resource> resources, Resource resource) {
527      if (resource == null) return;
528      resources.Add(resource);
529      CollectParentResources(resources, resource.ParentResource);
530    }
531    #endregion
532
533    #region Authorization Methods
534    public Permission GetPermissionForJob(Guid jobId, Guid userId) {
535      using (var db = CreateContext()) {
536        return GetPermissionForExperiment(GetExperimentForJob(jobId), userId);
537      }
538    }
539
540    public Permission GetPermissionForExperiment(Guid experimentId, Guid userId) {
541      using (var db = CreateContext()) {
542        HiveExperimentPermission permission = db.HiveExperimentPermissions.SingleOrDefault(p => p.HiveExperimentId == experimentId && p.GrantedUserId == userId);
543        return permission != null ? permission.Permission : Permission.NotAllowed;
544      }
545    }
546
547    public Guid GetExperimentForJob(Guid jobId) {
548      using (var db = CreateContext()) {
549        var job = db.Jobs.SingleOrDefault(j => j.JobId == jobId);
550        if (job.ParentJobId.HasValue) {
551          return GetExperimentForJob(job.ParentJobId.Value);
552        } else {
553          return db.HiveExperiments.SingleOrDefault(he => he.RootJobId == jobId).HiveExperimentId;
554        }
555      }
556    }
557
558    #endregion
559
560    #region Lifecycle Methods
561    public DateTime GetLastCleanup() {
562      using (var db = CreateContext()) {
563        var entity = db.Lifecycles.SingleOrDefault();
564        return entity != null ? entity.LastCleanup : DateTime.MinValue;
565      }
566    }
567
568    public void SetLastCleanup(DateTime datetime) {
569      using (var db = CreateContext()) {
570        var entity = db.Lifecycles.SingleOrDefault();
571        if (entity != null) {
572          entity.LastCleanup = datetime;
573        } else {
574          entity = new Lifecycle();
575          entity.LifecycleId = 0; // always only one entry with ID:0
576          entity.LastCleanup = datetime;
577          db.Lifecycles.InsertOnSubmit(entity);
578        }
579        db.SubmitChanges();
580      }
581    }
582    #endregion
583  }
584}
Note: See TracBrowser for help on using the repository browser.