#region License Information /* HeuristicLab * Copyright (C) 2002-2010 Heuristic and Evolutionary Algorithms Laboratory (HEAL) * * This file is part of HeuristicLab. * * HeuristicLab is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * HeuristicLab is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with HeuristicLab. If not, see . */ #endregion using System; using System.Collections.Generic; using System.Data.SqlClient; using System.IO; using System.Linq; using HeuristicLab.Hive.Contracts.BusinessObjects; using HeuristicLab.Hive.Server.DataAccess; namespace HeuristicLab.Hive.Server.LINQDataAccess { public class JobDao : BaseDao, IJobDao { #region IGenericDao Members public JobDto FindById(Guid id) { return (from job in Context.Jobs where job.JobId.Equals(id) select EntityToDto(job, null)).SingleOrDefault(); } public IEnumerable FindAll() { return (from job in Context.Jobs select EntityToDto(job, null)).ToArray(); } public IEnumerable FindWithLimitations(JobState jobState, int offset, int count) { IQueryable query = null; if (jobState == JobState.Finished) { query = from job in Context.Jobs where job.JobState == Enum.GetName(typeof(JobState), jobState) orderby job.DateFinished select EntityToDto(job, null); } else if (jobState == JobState.Calculating || jobState == JobState.SnapshotRequested || jobState == JobState.SnapshotSent) { query = from job in Context.Jobs where job.JobState == Enum.GetName(typeof(JobState), jobState) orderby job.DateCalculated select EntityToDto(job, null); } else { query = from job in Context.Jobs where job.JobState == Enum.GetName(typeof(JobState), jobState) orderby job.DateCreated select EntityToDto(job, null); } return query.Skip(offset).Take(count).ToList(); } public byte[] GetBinaryJobFile(Guid jobId) { return (from job in Context.Jobs where job.JobId.Equals(jobId) select job.SerializedJob).SingleOrDefault().ToArray(); } public JobDto Insert(JobDto bObj) { Job j = DtoToEntity(bObj, null); Context.Jobs.InsertOnSubmit(j); CommitChanges(); bObj.Id = j.JobId; return bObj; } public void SetBinaryJobFile(Guid jobId, byte[] data) { Job j = (from job in Context.Jobs where job.JobId.Equals(jobId) select job).SingleOrDefault(); j.SerializedJob = data; CommitChanges(); } public SerializedJob InsertWithAttachedJob(SerializedJob job) { Job j = DtoToEntity(job.JobInfo, null); j.SerializedJob = job.SerializedJobData; //foreach (Guid assignRessourceId in job.JobInfo.AssignedResourceIds) // j.AssignedResources.Add(new AssignedResource { ResourceId = assignRessourceId }); Context.Jobs.InsertOnSubmit(j); CommitChanges(); job.JobInfo.Id = j.JobId; return job; } public void Delete(Guid id) { Job job = Context.Jobs.SingleOrDefault(j => j.JobId.Equals(id)); Context.Jobs.DeleteOnSubmit(job); CommitChanges(); } public void Update(JobDto bObj) { Job job = Context.Jobs.SingleOrDefault(j => j.JobId.Equals(bObj.Id)); DtoToEntity(bObj, job); CommitChanges(); } public IEnumerable FindActiveJobsOfSlave(SlaveDto slave) { return (from j in Context.Jobs where (j.JobState == Enum.GetName(typeof(JobState), JobState.Calculating) || j.JobState == Enum.GetName(typeof(JobState), JobState.Aborted) || j.JobState == Enum.GetName(typeof(JobState), JobState.SnapshotRequested) || j.JobState == Enum.GetName(typeof(JobState), JobState.SnapshotSent) || j.JobState == Enum.GetName(typeof(JobState), JobState.WaitForChildJobs)) && (j.ResourceId.Equals(slave.Id)) select EntityToDto(j, null)).ToList(); } public IEnumerable FindFittingJobs(JobState state, int freeCores, int freeMemory, Guid slaveId) { SlaveGroupDao cgd = new SlaveGroupDao(); List idList = new List(cgd.FindAllGroupAndParentGroupIdsForSlave(slaveId)); //Add myself too - enables jobs for one specific host! idList.Add(slaveId); var q = (from ar in Context.AssignedResources where ar.Job.JobState == Enum.GetName(typeof(JobState), state) && ar.Job.CoresNeeded <= freeCores && ar.Job.MemoryNeeded <= freeMemory && idList.Contains(ar.ResourceId) orderby ar.Job.Priority descending select EntityToDto(ar.Job, null)); return q.ToList(); } public IEnumerable FindJobsWithFinishedChilds(Guid slaveId) { SlaveGroupDao cgd = new SlaveGroupDao(); List idList = new List(cgd.FindAllGroupAndParentGroupIdsForSlave(slaveId)); //Add myself too - enables jobs for one specific host! idList.Add(slaveId); var query = from ar in Context.AssignedResources where ar.Job.JobState == Enum.GetName(typeof(JobState), JobState.WaitForChildJobs) && (from child in Context.Jobs where child.ParentJobId == ar.Job.JobId select (child.JobState == Enum.GetName(typeof(JobState), JobState.Finished) || child.JobState == Enum.GetName(typeof(JobState), JobState.Failed) || child.JobState == Enum.GetName(typeof(JobState), JobState.Aborted)) ).All(x => x) && (from child in Context.Jobs // avoid returning WaitForChildJobs jobs where no child-jobs exist (yet) where child.ParentJobId == ar.Job.JobId select child).Count() > 0 orderby ar.Job.Priority descending select EntityToDto(ar.Job, null); var list = query.ToList(); return list; } public IEnumerable GetJobsByState(JobState state) { return (from j in Context.Jobs where (j.JobState == Enum.GetName(typeof(JobState), state)) select EntityToDto(j, null)).ToList(); } public void AssignSlaveToJob(Guid slaveId, Guid jobId) { Slave s = Context.Resources.OfType().SingleOrDefault(slave => slave.ResourceId.Equals(slaveId)); Job j = Context.Jobs.SingleOrDefault(job => job.JobId.Equals(jobId)); s.Jobs.Add(j); j.Slave = s; CommitChanges(); } public void UnAssignSlaveToJob(Guid jobId) { Job j = Context.Jobs.SingleOrDefault(job => job.JobId.Equals(jobId)); j.Slave = null; CommitChanges(); } public void SetJobOffline(JobDto job) { Job j = Context.Jobs.SingleOrDefault(jq => jq.JobId.Equals(job.Id)); j.Slave = null; var childJobs = Context.Jobs.Where(child => child.ParentJobId == j.JobId); if (childJobs.Count() > 0) { j.JobState = JobState.WaitForChildJobs.ToString(); } else { j.JobState = JobState.Offline.ToString(); } CommitChanges(); } public Stream GetSerializedJobStream(Guid jobId) { VarBinarySource source = new VarBinarySource((SqlConnection)Context.Connection, null, "Job", "SerializedJob", "JobId", jobId); return new VarBinaryStream(source); } public IEnumerable FindJobsById(IEnumerable jobIds) { IQueryable jobs = from job in Context.Jobs where jobIds.Contains(job.JobId) select EntityToDto(job, null); return jobs.ToList(); } public bool IsUserAuthorizedForJobs(Guid userId, params Guid[] jobIds) { var jobs = from job in Context.Jobs where jobIds.Contains(job.JobId) select job; return jobs.All(job => job.UserId == userId); } public IEnumerable FindJobsByParentId(Guid? parentJobId, bool recursive) { IQueryable query = from job in Context.Jobs where parentJobId == null ? !job.ParentJobId.HasValue : job.ParentJobId.Value == parentJobId select EntityToDto(job, null); List jobs = query.ToList(); if (recursive) { List childs = new List(); foreach (JobDto job in jobs) { childs.AddRange(FindJobsByParentId(job.Id, recursive)); } jobs.AddRange(childs); } return jobs; } #endregion public override Job DtoToEntity(JobDto source, Job target) { if (source == null) return null; if (target == null) target = new Job(); target.CoresNeeded = source.CoresNeeded; target.MemoryNeeded = source.MemoryNeeded; target.DateCalculated = source.DateCalculated; target.DateCreated = source.DateCreated; target.DateFinished = source.DateFinished; target.JobId = source.Id; target.ExecutionTime = source.ExecutionTime.ToString(); target.Exception = source.Exception; target.Priority = source.Priority; target.JobState = Enum.GetName(typeof(JobState), source.State); target.UserId = source.UserId; target.ParentJobId = source.ParentJobId; foreach (Guid assignRessourceId in source.AssignedResourceIds) { if (!target.AssignedResources.Select(x => x.ResourceId).Contains(assignRessourceId)) { target.AssignedResources.Add(new AssignedResource { ResourceId = assignRessourceId }); } } return target; } //Slave is not used ATM - not sure when we stopped using those... public override JobDto EntityToDto(Job source, JobDto target) { if (source == null) return null; if (target == null) target = new JobDto(); target.CoresNeeded = source.CoresNeeded; target.MemoryNeeded = source.MemoryNeeded; target.DateCalculated = source.DateCalculated; target.DateCreated = source.DateCreated; target.DateFinished = source.DateFinished; target.Id = source.JobId; target.Exception = source.Exception; TimeSpan ts; if (!TimeSpan.TryParse(source.ExecutionTime, out ts)) ts = TimeSpan.Zero; target.ExecutionTime = ts; target.Priority = source.Priority; target.State = (JobState)Enum.Parse(typeof(JobState), source.JobState, true); target.UserId = source.UserId; target.ParentJobId = source.ParentJobId; target.AssignedResourceIds = source.AssignedResources.Select(x => x.ResourceId).ToList(); return target; } } }