Free cookie consent management tool by TermsFeed Policy Generator

source: branches/HivePerformance/sources/HeuristicLab.Services.Hive/3.3/OptimizedHiveDao.cs @ 9634

Last change on this file since 9634 was 9634, checked in by pfleck, 10 years ago

#2030:
Updated license year in headers and AssemblyInfo.
Removed empty regions in OptimizedHiveDao and IOptimizedHiveDao.
The ServiceLocator handles creation of the OptimizedHiveDao different to make the OptimizedHiveDao available for non-service operation calls:

  • if the ServiceLocator is called _within_ a service operation, the same DB-context is used for the whole service operation, and therefore is stored in the service operation context.
  • if the ServiceLocator is called _outside_ a service operation, a new DB-context is created on each ServiceLocator call.
File size: 9.3 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2013 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.Data.Linq;
25using System.Linq;
26using DT = HeuristicLab.Services.Hive.DataTransfer;
27
28namespace HeuristicLab.Services.Hive.DataAccess {
29  public class OptimizedHiveDao : IOptimizedHiveDao {
30    private HiveDataContext Db { get; set; }
31
32    public OptimizedHiveDao(HiveDataContext db) {
33      Db = db;
34    }
35
36    #region Task Methods
37    public Task GetTaskById(Guid taskId) {
38      return GetTaskByIdQuery(Db, taskId).SingleOrDefault();
39    }
40
41    private static readonly Func<HiveDataContext, Guid, IQueryable<Task>> GetTaskByIdQuery = CompiledQuery.Compile((HiveDataContext db, Guid taskId) =>
42      from t in db.Tasks
43      where t.TaskId == taskId
44      select t
45    );
46
47    public Task GetTaskByDto(DT.Task taskDto) {
48      var task = GetTaskById(taskDto.Id);
49      DT.Convert.ToEntity(taskDto, task);
50      return task;
51    }
52
53    public Tuple<Task, Guid?> GetTaskByIdAndLastStateLogSlaveId(Guid taskId) {
54      return GetTaskByIdAndLastStateLogSlaveIdQuery(Db, taskId).SingleOrDefault();
55    }
56
57    private static readonly Func<HiveDataContext, Guid, IQueryable<Tuple<Task, Guid?>>> GetTaskByIdAndLastStateLogSlaveIdQuery = CompiledQuery.Compile((HiveDataContext db, Guid taskId) =>
58       from t in db.Tasks
59       join sl in db.StateLogs on t.TaskId equals sl.TaskId
60       where t.TaskId == taskId
61       orderby sl.DateTime descending
62       group sl by t into logs
63       select new Tuple<Task, Guid?>(logs.Key, logs.First().SlaveId)
64    );
65
66    private const string GetWaitingTasksQueryString = @"
67      WITH pr AS (
68        SELECT ResourceId, ParentResourceId
69        FROM [Resource]
70        WHERE ResourceId = {0}
71        UNION ALL
72        SELECT r.ResourceId, r.ParentResourceId
73        FROM [Resource] r JOIN pr ON r.ResourceId = pr.ParentResourceId
74      )
75      SELECT DISTINCT t.TaskId, t.JobId, t.Priority
76      FROM pr JOIN AssignedResources ar ON ar.ResourceId = pr.ResourceId
77          JOIN Task t ON t.TaskId = ar.TaskId
78      WHERE NOT (t.IsParentTask = 1 AND t.FinishWhenChildJobsFinished = 1)
79          AND t.TaskState = {1}
80          AND t.CoresNeeded <= {2}
81          AND t.MemoryNeeded <= {3}
82    ";
83
84    public IEnumerable<TaskInfoForScheduler> GetWaitingTasks(Slave slave) {
85      //Originally we checked here if there are parent tasks which should be calculated (with GetParentTasks(resourceIds, count, false);).
86      //Because there is at the moment no case where this makes sense (there don't exist parent tasks which need to be calculated),
87      //we skip this step because it's wasted runtime
88      return Db.ExecuteQuery<TaskInfoForScheduler>(GetWaitingTasksQueryString, slave.ResourceId, Enum.GetName(typeof(TaskState), TaskState.Waiting), slave.FreeCores, slave.FreeMemory);
89    }
90
91    public IQueryable<DT.LightweightTask> GetLightweightTasks(Guid jobId) {
92      return GetLightweightTasksQuery(Db, jobId);
93    }
94
95    private static readonly Func<HiveDataContext, Guid, IQueryable<DT.LightweightTask>> GetLightweightTasksQuery = CompiledQuery.Compile((HiveDataContext db, Guid jobId) =>
96        from task in db.Tasks
97        where task.JobId == jobId
98        select new DT.LightweightTask {
99          Id = task.TaskId,
100          ExecutionTime = TimeSpan.FromMilliseconds(task.ExecutionTimeMs),
101          ParentTaskId = task.ParentTaskId,
102          StateLog = task.StateLogs.Select(sl => ConvertStateLog(sl)).ToList(),
103          State = ConvertTaskState(task.State),
104          Command = ConvertCommand(task.Command),
105          LastTaskDataUpdate = task.JobData.LastUpdate
106        }
107    );
108
109    private static readonly Func<StateLog, DT.StateLog> ConvertStateLog = sl => DT.Convert.ToDto(sl);
110    private static readonly Func<TaskState, DT.TaskState> ConvertTaskState = ts => DT.Convert.ToDto(ts);
111    private static readonly Func<Command?, DT.Command?> ConvertCommand = c => DT.Convert.ToDto(c);
112
113    public void UpdateTask(Task task) {
114      Db.SubmitChanges();
115    }
116
117    public Task UpdateTaskState(Guid taskId, TaskState taskState, Guid? slaveId, Guid? userId, string exception) {
118      Db.StateLogs.InsertOnSubmit(new StateLog {
119        TaskId = taskId,
120        State = taskState,
121        SlaveId = slaveId,
122        UserId = userId,
123        Exception = exception,
124        DateTime = DateTime.Now
125      });
126
127      var task = GetTaskById(taskId);
128      task.State = taskState;
129
130      Db.SubmitChanges();
131
132      return task;
133    }
134
135    public Guid AddTask(Task task) {
136      Db.Tasks.InsertOnSubmit(task);
137      Db.SubmitChanges();
138      return task.TaskId;
139    }
140
141    public void AssignJobToResource(Guid taskId, IEnumerable<Guid> resourceIds) {
142      Db.AssignedResources.InsertAllOnSubmit(resourceIds.Select(resourceId => new AssignedResource { TaskId = taskId, ResourceId = resourceId }));
143      Db.SubmitChanges();
144    }
145
146    private const string TaskIsAllowedToBeCalculatedBySlaveQueryString = @"
147      WITH pr AS (
148        SELECT ResourceId, ParentResourceId
149        FROM [Resource]
150        WHERE ResourceId = {0}
151        UNION ALL
152        SELECT r.ResourceId, r.ParentResourceId
153        FROM [Resource] r JOIN pr ON r.ResourceId = pr.ParentResourceId
154      )
155      SELECT COUNT(ar.TaskId)
156      FROM pr JOIN AssignedResources ar ON pr.ResourceId = ar.ResourceId
157      WHERE ar.TaskId = {1}
158    ";
159
160    public bool TaskIsAllowedToBeCalculatedBySlave(Guid taskId, Guid slaveId) {
161      return Db.ExecuteQuery<int>(TaskIsAllowedToBeCalculatedBySlaveQueryString, slaveId, taskId).First() > 0;
162    }
163    #endregion
164
165    #region TaskData Methods
166    public TaskData GetTaskDataById(Guid id) {
167      return GetTaskDataByIdQuery(Db, id).SingleOrDefault();
168    }
169
170    private static readonly Func<HiveDataContext, Guid, IQueryable<TaskData>> GetTaskDataByIdQuery = CompiledQuery.Compile((HiveDataContext db, Guid id) =>
171      from t in db.TaskDatas
172      where t.TaskId == id
173      select t
174    );
175
176    public TaskData GetTaskDataByDto(DT.TaskData dto) {
177      var taskData = GetTaskDataById(dto.TaskId);
178      DT.Convert.ToEntity(dto, taskData);
179      return taskData;
180    }
181
182    public void UpdateTaskData(TaskData taskData) {
183      Db.SubmitChanges();
184    }
185    #endregion
186
187    #region Plugin Methods
188    public Plugin GetPluginById(Guid pluginId) {
189      return GetPluginByIdQuery(Db, pluginId).SingleOrDefault();
190    }
191
192    private static readonly Func<HiveDataContext, Guid, IQueryable<Plugin>> GetPluginByIdQuery = CompiledQuery.Compile((HiveDataContext db, Guid pluginId) =>
193      from p in db.Plugins
194      where p.PluginId == pluginId
195      select p
196    );
197    #endregion
198
199    #region Slave Methods
200    public Slave GetSlaveById(Guid id) {
201      return GetSlaveByIdQuery(Db, id).SingleOrDefault();
202    }
203
204    private static readonly Func<HiveDataContext, Guid, IQueryable<Slave>> GetSlaveByIdQuery = CompiledQuery.Compile((HiveDataContext db, Guid slaveId) =>
205      from s in db.Resources.OfType<Slave>()
206      where s.ResourceId == slaveId
207      select s
208    );
209
210    public void UpdateSlave(Slave slave) {
211      Db.SubmitChanges();
212    }
213
214    private const string DowntimeQueryString = @"
215      WITH pr AS (
216        SELECT ResourceId, ParentResourceId
217        FROM [Resource]
218        WHERE ResourceId = {0}
219        UNION ALL
220        SELECT r.ResourceId, r.ParentResourceId
221        FROM [Resource] r JOIN pr ON r.ResourceId = pr.ParentResourceId
222      )
223      SELECT COUNT(dt.DowntimeId)
224      FROM pr JOIN [Downtime] dt ON pr.ResourceId = dt.ResourceId
225      WHERE {1} BETWEEN dt.StartDate AND dt.EndDate
226        AND dt.DowntimeType = {2}
227      ";
228
229    public bool SlaveHasToShutdownComputer(Guid slaveId) {
230      return Db.ExecuteQuery<int>(DowntimeQueryString, slaveId, DateTime.Now, DowntimeType.Shutdown.ToString()).FirstOrDefault() > 0;
231    }
232
233    public bool SlaveIsAllowedToCalculate(Guid slaveId) {
234      return Db.ExecuteQuery<int>(DowntimeQueryString, slaveId, DateTime.Now, DowntimeType.Offline.ToString()).FirstOrDefault() == 0;
235    }
236    #endregion
237
238    #region Resource Methods
239    public IEnumerable<Guid> GetAssignedResourceIds(Guid taskId) {
240      return GetAssignedResourceIdsQuery(Db, taskId);
241    }
242
243    private static readonly Func<HiveDataContext, Guid, IQueryable<Guid>> GetAssignedResourceIdsQuery = CompiledQuery.Compile((HiveDataContext db, Guid taskId) =>
244      from ar in db.AssignedResources
245      where ar.TaskId == taskId
246      select ar.ResourceId
247    );
248    #endregion
249  }
250}
Note: See TracBrowser for help on using the repository browser.