Index: /trunk/sources/HeuristicLab.Clients.Hive.Slave.ConsoleClient/3.3/app.config
===================================================================
--- /trunk/sources/HeuristicLab.Clients.Hive.Slave.ConsoleClient/3.3/app.config (revision 9664)
+++ /trunk/sources/HeuristicLab.Clients.Hive.Slave.ConsoleClient/3.3/app.config (revision 9665)
@@ -29,4 +29,14 @@
+
+
+
+
+
+
+
+
+
+
@@ -39,13 +49,14 @@
-
+
+
+
+
+
+
Index: /trunk/sources/HeuristicLab.Clients.Hive.Slave.WindowsService/3.3/app.config
===================================================================
--- /trunk/sources/HeuristicLab.Clients.Hive.Slave.WindowsService/3.3/app.config (revision 9664)
+++ /trunk/sources/HeuristicLab.Clients.Hive.Slave.WindowsService/3.3/app.config (revision 9665)
@@ -32,9 +32,5 @@
-
+
Index: /trunk/sources/HeuristicLab.Clients.Hive.Slave/3.3/app.config
===================================================================
--- /trunk/sources/HeuristicLab.Clients.Hive.Slave/3.3/app.config (revision 9664)
+++ /trunk/sources/HeuristicLab.Clients.Hive.Slave/3.3/app.config (revision 9665)
@@ -33,4 +33,14 @@
+
+
+
+
+
+
+
+
+
+
@@ -46,4 +56,9 @@
+
+
+
+
+
@@ -51,5 +66,5 @@
- 00:00:40
+ 00:00:30
Index: /trunk/sources/HeuristicLab.Clients.Hive/3.3/HiveServiceLocator.cs
===================================================================
--- /trunk/sources/HeuristicLab.Clients.Hive/3.3/HiveServiceLocator.cs (revision 9664)
+++ /trunk/sources/HeuristicLab.Clients.Hive/3.3/HiveServiceLocator.cs (revision 9665)
@@ -35,4 +35,7 @@
}
+ private HiveServiceLocator() {
+ }
+
private string username;
public string Username {
@@ -47,10 +50,39 @@
}
+ public int EndpointRetries { get; private set; }
+
+ public string WorkingEndpoint { get; private set; }
+
private HiveServiceClient NewServiceClient() {
- HiveServiceClient cl;
+ if (EndpointRetries >= Settings.Default.MaxEndpointRetries) {
+ return CreateClient(WorkingEndpoint);
+ }
+
+ var configurations = Settings.Default.EndpointConfigurationPriorities;
+
+ Exception exception = null;
+ foreach (var endpointConfigurationName in configurations) {
+ try {
+ var cl = CreateClient(endpointConfigurationName);
+ cl.Open();
+ WorkingEndpoint = endpointConfigurationName;
+ return cl;
+ }
+ catch (Exception exc) {
+ exception = exc;
+ EndpointRetries++;
+ }
+ }
+
+ throw exception ?? new Exception("No endpoint for Hive service found.");
+ }
+
+ private HiveServiceClient CreateClient(string endpointConfigurationName) {
+ HiveServiceClient cl = null;
+
if (string.IsNullOrEmpty(username) && string.IsNullOrEmpty(password))
- cl = ClientFactory.CreateClient();
+ cl = ClientFactory.CreateClient(endpointConfigurationName);
else
- cl = ClientFactory.CreateClient(null, null, username, password);
+ cl = ClientFactory.CreateClient(endpointConfigurationName, null, username, password);
return cl;
Index: /trunk/sources/HeuristicLab.Clients.Hive/3.3/Settings.Designer.cs
===================================================================
--- /trunk/sources/HeuristicLab.Clients.Hive/3.3/Settings.Designer.cs (revision 9664)
+++ /trunk/sources/HeuristicLab.Clients.Hive/3.3/Settings.Designer.cs (revision 9665)
@@ -2,5 +2,5 @@
//
// This code was generated by a tool.
-// Runtime Version:4.0.30319.586
+// Runtime Version:4.0.30319.18034
//
// Changes to this file may cause incorrect behavior and will be lost if
@@ -13,5 +13,5 @@
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
- [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "10.0.0.0")]
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")]
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
@@ -26,5 +26,5 @@
[global::System.Configuration.ApplicationScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
- [global::System.Configuration.DefaultSettingValueAttribute("1")]
+ [global::System.Configuration.DefaultSettingValueAttribute("2")]
public int MaxParallelUploads {
get {
@@ -53,5 +53,5 @@
[global::System.Configuration.ApplicationScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
- [global::System.Configuration.DefaultSettingValueAttribute("2")]
+ [global::System.Configuration.DefaultSettingValueAttribute("4")]
public int MaxParallelDownloads {
get {
@@ -77,4 +77,26 @@
}
}
+
+ [global::System.Configuration.ApplicationScopedSettingAttribute()]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Configuration.DefaultSettingValueAttribute(@"
+
+ netTcpBinding_IHiveService
+ wsHttpBinding_IHiveService
+")]
+ public global::System.Collections.Specialized.StringCollection EndpointConfigurationPriorities {
+ get {
+ return ((global::System.Collections.Specialized.StringCollection)(this["EndpointConfigurationPriorities"]));
+ }
+ }
+
+ [global::System.Configuration.ApplicationScopedSettingAttribute()]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Configuration.DefaultSettingValueAttribute("3")]
+ public int MaxEndpointRetries {
+ get {
+ return ((int)(this["MaxEndpointRetries"]));
+ }
+ }
}
}
Index: /trunk/sources/HeuristicLab.Clients.Hive/3.3/Settings.settings
===================================================================
--- /trunk/sources/HeuristicLab.Clients.Hive/3.3/Settings.settings (revision 9664)
+++ /trunk/sources/HeuristicLab.Clients.Hive/3.3/Settings.settings (revision 9665)
@@ -4,5 +4,5 @@
- 1
+ 2
@@ -13,5 +13,5 @@
- 2
+ 4
@@ -21,4 +21,14 @@
anonymous
+
+ <?xml version="1.0" encoding="utf-16"?>
+<ArrayOfString xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
+ <string>netTcpBinding_IHiveService</string>
+ <string>wsHttpBinding_IHiveService</string>
+</ArrayOfString>
+
+
+ 3
+
Index: /trunk/sources/HeuristicLab.Clients.Hive/3.3/app.config
===================================================================
--- /trunk/sources/HeuristicLab.Clients.Hive/3.3/app.config (revision 9664)
+++ /trunk/sources/HeuristicLab.Clients.Hive/3.3/app.config (revision 9665)
@@ -9,5 +9,5 @@
- 1
+ 2
@@ -18,5 +18,5 @@
- 2
+ 4
@@ -25,4 +25,16 @@
anonymous
+
+
+
+
+ netTcpBinding_IHiveService
+ wsHttpBinding_IHiveService
+
+
+
+
+ 3
@@ -38,24 +50,6 @@
-
-
-
+
+
@@ -65,9 +59,24 @@
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
Index: /trunk/sources/HeuristicLab.Services.Hive.DataAccess/3.3/HeuristicLab.Services.Hive.DataAccess-3.3.csproj
===================================================================
--- /trunk/sources/HeuristicLab.Services.Hive.DataAccess/3.3/HeuristicLab.Services.Hive.DataAccess-3.3.csproj (revision 9664)
+++ /trunk/sources/HeuristicLab.Services.Hive.DataAccess/3.3/HeuristicLab.Services.Hive.DataAccess-3.3.csproj (revision 9665)
@@ -149,4 +149,5 @@
+
Index: /trunk/sources/HeuristicLab.Services.Hive.DataAccess/3.3/HiveDataContext.cs
===================================================================
--- /trunk/sources/HeuristicLab.Services.Hive.DataAccess/3.3/HiveDataContext.cs (revision 9664)
+++ /trunk/sources/HeuristicLab.Services.Hive.DataAccess/3.3/HiveDataContext.cs (revision 9665)
@@ -23,11 +23,8 @@
using System.Data.Linq.Mapping;
namespace HeuristicLab.Services.Hive.DataAccess {
- partial class SlaveStatistics {
- }
-
partial class HiveDataContext {
// source: http://stackoverflow.com/questions/648196/random-row-from-linq-to-sql
[Function(Name = "NEWID", IsComposable = true)]
- public Guid Random() {
+ public Guid Random() {
// to prove not used by our C# code...
throw new NotImplementedException();
Index: /trunk/sources/HeuristicLab.Services.Hive.DataAccess/3.3/HiveDataContext.dbml
===================================================================
--- /trunk/sources/HeuristicLab.Services.Hive.DataAccess/3.3/HiveDataContext.dbml (revision 9664)
+++ /trunk/sources/HeuristicLab.Services.Hive.DataAccess/3.3/HiveDataContext.dbml (revision 9665)
@@ -114,5 +114,5 @@
-
+
@@ -123,5 +123,5 @@
-
+
Index: /trunk/sources/HeuristicLab.Services.Hive.DataAccess/3.3/HiveDataContext.dbml.layout
===================================================================
--- /trunk/sources/HeuristicLab.Services.Hive.DataAccess/3.3/HiveDataContext.dbml.layout (revision 9664)
+++ /trunk/sources/HeuristicLab.Services.Hive.DataAccess/3.3/HiveDataContext.dbml.layout (revision 9665)
@@ -3,56 +3,56 @@
-
+
-
-
-
-
+
+
+
+
-
-
-
-
+
+
+
+
-
-
-
-
+
+
+
+
-
-
-
-
+
+
+
+
-
-
-
-
+
+
+
+
-
-
-
-
+
+
+
+
-
-
-
-
+
+
+
+
-
-
-
-
+
+
+
+
-
+
@@ -69,5 +69,5 @@
-
+
@@ -76,14 +76,14 @@
-
+
-
-
-
-
+
+
+
+
-
+
@@ -109,14 +109,14 @@
-
+
-
-
-
-
+
+
+
+
-
+
@@ -128,32 +128,32 @@
-
+
-
-
-
-
+
+
+
+
-
-
-
-
+
+
+
+
-
-
-
-
+
+
+
+
-
-
-
-
+
+
+
+
-
+
@@ -228,8 +228,8 @@
-
+
-
+
@@ -241,8 +241,8 @@
-
+
-
+
Index: /trunk/sources/HeuristicLab.Services.Hive.DataAccess/3.3/HiveDataContext.designer.cs
===================================================================
--- /trunk/sources/HeuristicLab.Services.Hive.DataAccess/3.3/HiveDataContext.designer.cs (revision 9664)
+++ /trunk/sources/HeuristicLab.Services.Hive.DataAccess/3.3/HiveDataContext.designer.cs (revision 9665)
@@ -2661,5 +2661,5 @@
private System.Guid _JobId;
- private System.Data.Linq.Link _Data;
+ private System.Data.Linq.Link _Data;
private System.DateTime _LastUpdate;
@@ -2673,5 +2673,5 @@
partial void OnTaskIdChanging(System.Guid value);
partial void OnTaskIdChanged();
- partial void OnDataChanging(System.Data.Linq.Binary value);
+ partial void OnDataChanging(byte[] value);
partial void OnDataChanged();
partial void OnLastUpdateChanging(System.DateTime value);
@@ -2710,5 +2710,5 @@
[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_Data", DbType="VarBinary(MAX)", CanBeNull=false, UpdateCheck=UpdateCheck.Never)]
- public System.Data.Linq.Binary Data
+ public byte[] Data
{
get
@@ -2814,5 +2814,5 @@
private System.Guid _PluginId;
- private System.Data.Linq.Link _Data;
+ private System.Data.Linq.Link _Data;
private string _FileName;
@@ -2828,5 +2828,5 @@
partial void OnPluginIdChanging(System.Guid value);
partial void OnPluginIdChanged();
- partial void OnDataChanging(System.Data.Linq.Binary value);
+ partial void OnDataChanging(byte[] value);
partial void OnDataChanged();
partial void OnFileNameChanging(string value);
@@ -2885,5 +2885,5 @@
[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_Data", DbType="VarBinary(MAX) NOT NULL", CanBeNull=false, UpdateCheck=UpdateCheck.Never)]
- public System.Data.Linq.Binary Data
+ public byte[] Data
{
get
Index: /trunk/sources/HeuristicLab.Services.Hive.DataAccess/3.3/SQL Scripts/Initialize Hive Database.sql
===================================================================
--- /trunk/sources/HeuristicLab.Services.Hive.DataAccess/3.3/SQL Scripts/Initialize Hive Database.sql (revision 9664)
+++ /trunk/sources/HeuristicLab.Services.Hive.DataAccess/3.3/SQL Scripts/Initialize Hive Database.sql (revision 9665)
@@ -1,4 +1,9 @@
USE [HeuristicLab.Hive-3.3]
/* create and initialize hive database tables */
+
+EXEC sp_configure filestream_access_level, 2
+GO
+RECONFIGURE
+GO
SET ARITHABORT ON
@@ -88,13 +93,13 @@
)
CREATE TABLE [dbo].[TaskData](
- [TaskId] UniqueIdentifier NOT NULL,
- [Data] VarBinary(MAX) NOT NULL,
+ [TaskId] UniqueIdentifier RowGuidCol NOT NULL,
+ [Data] VarBinary(MAX) Filestream NOT NULL,
[LastUpdate] DateTime NOT NULL,
CONSTRAINT [PK_dbo.TaskData] PRIMARY KEY ([TaskId])
)
CREATE TABLE [dbo].[PluginData](
- [PluginDataId] UniqueIdentifier NOT NULL,
+ [PluginDataId] UniqueIdentifier RowGuidCol NOT NULL,
[PluginId] UniqueIdentifier NOT NULL,
- [Data] VarBinary(MAX) NOT NULL,
+ [Data] VarBinary(MAX) FileStream NOT NULL,
[FileName] VarChar(MAX) NOT NULL,
CONSTRAINT [PK_dbo.PluginData] PRIMARY KEY ([PluginDataId])
Index: /trunk/sources/HeuristicLab.Services.Hive.DataAccess/3.3/SQL Scripts/Migrate to Filestream.sql
===================================================================
--- /trunk/sources/HeuristicLab.Services.Hive.DataAccess/3.3/SQL Scripts/Migrate to Filestream.sql (revision 9665)
+++ /trunk/sources/HeuristicLab.Services.Hive.DataAccess/3.3/SQL Scripts/Migrate to Filestream.sql (revision 9665)
@@ -0,0 +1,77 @@
+USE [HeuristicLab.Hive-3.3]
+
+EXEC sp_configure filestream_access_level, 2
+GO
+RECONFIGURE
+GO
+
+/**********************************************************/
+
+/* Move old Task Data */
+
+CREATE TABLE [dbo].[TaskDataTemp](
+ [TaskId] UniqueIdentifier RowGuidCol NOT NULL,
+ [Data] VarBinary(MAX) Filestream NOT NULL,
+ [LastUpdate] DateTime NOT NULL,
+ CONSTRAINT [PK_dbo.TaskDataTemp] PRIMARY KEY ([TaskId])
+)
+
+INSERT INTO dbo.TaskDataTemp (TaskId, Data, LastUpdate)
+SELECT TaskId, Data, LastUpdate
+FROM dbo.TaskData
+
+DELETE FROM dbo.TaskData
+
+/* Alter TaskId and Data Column */
+
+ALTER TABLE dbo.TaskData
+ALTER COLUMN [TaskId] ADD RowGuidCol
+
+ALTER TABLE dbo.TaskData
+DROP COLUMN Data
+
+ALTER TABLE dbo.TaskData
+ADD [Data] VarBinary(MAX) Filestream NOT NULL
+
+/* Insert data */
+
+INSERT INTO dbo.TaskData (TaskId, Data, LastUpdate)
+SELECT TaskId, Data, LastUpdate
+FROM dbo.TaskDataTemp
+
+DROP TABLE dbo.TaskDataTemp
+
+
+/**********************************************************/
+
+/* Move old Plugin Data */
+
+CREATE TABLE [dbo].[PluginDataTemp](
+ [PluginDataId] UniqueIdentifier RowGuidCol NOT NULL,
+ [PluginId] UniqueIdentifier NOT NULL,
+ [Data] VarBinary(MAX) FileStream NOT NULL,
+ [FileName] VarChar(MAX) NOT NULL,
+ CONSTRAINT [PK_dbo.PluginDataTemp] PRIMARY KEY ([PluginDataId])
+)
+
+INSERT INTO dbo.PluginDataTemp (PluginDataId, PluginId, Data, [FileName])
+SELECT PluginDataId, PluginId, Data, [FileName]
+FROM dbo.PluginData
+
+DELETE FROM dbo.PluginData
+
+/* Alter Data Column */
+
+ALTER TABLE dbo.PluginData
+DROP COLUMN Data
+
+ALTER TABLE dbo.PluginData
+ADD [Data] VarBinary(MAX) Filestream NOT NULL
+
+/* Insert data */
+
+INSERT INTO dbo.PluginData (PluginDataId, PluginId, Data, [FileName])
+SELECT PluginDataId, PluginId, Data, [FileName]
+FROM dbo.PluginDataTemp
+
+DROP TABLE dbo.PluginDataTemp
Index: /trunk/sources/HeuristicLab.Services.Hive.DataAccess/3.3/SQL Scripts/Prepare Hive Database.sql
===================================================================
--- /trunk/sources/HeuristicLab.Services.Hive.DataAccess/3.3/SQL Scripts/Prepare Hive Database.sql (revision 9664)
+++ /trunk/sources/HeuristicLab.Services.Hive.DataAccess/3.3/SQL Scripts/Prepare Hive Database.sql (revision 9665)
@@ -41,5 +41,4 @@
ALTER TABLE dbo.Plugin WITH NOCHECK ADD CONSTRAINT [DF_Plugin_PluginId] DEFAULT (NEWSEQUENTIALID()) FOR PluginId;
-ALTER TABLE dbo.PluginData ALTER COLUMN PluginDataId ADD ROWGUIDCOL;
ALTER TABLE dbo.PluginData WITH NOCHECK ADD CONSTRAINT [DF_PluginData_PluginDataId] DEFAULT (NEWSEQUENTIALID()) FOR PluginDataId;
Index: /trunk/sources/HeuristicLab.Services.Hive.Web/Hive-3.3/Web.config
===================================================================
--- /trunk/sources/HeuristicLab.Services.Hive.Web/Hive-3.3/Web.config (revision 9664)
+++ /trunk/sources/HeuristicLab.Services.Hive.Web/Hive-3.3/Web.config (revision 9665)
@@ -54,10 +54,10 @@
-
+
-
+
@@ -67,4 +67,13 @@
+
+
+
+
+
+
+
+
+
@@ -88,6 +97,8 @@
-
-
+
+
+
+
Index: /trunk/sources/HeuristicLab.Services.Hive.Web/web_services.config
===================================================================
--- /trunk/sources/HeuristicLab.Services.Hive.Web/web_services.config (revision 9664)
+++ /trunk/sources/HeuristicLab.Services.Hive.Web/web_services.config (revision 9665)
@@ -29,8 +29,8 @@
-
+
-
+
@@ -55,6 +55,5 @@
-
-
+
@@ -67,6 +66,6 @@
@@ -78,4 +77,13 @@
+
+
+
+
+
+
+
+
+
@@ -105,8 +113,10 @@
-
+
-
-
+
+
+
+
Index: /trunk/sources/HeuristicLab.Services.Hive/3.3/Convert.cs
===================================================================
--- /trunk/sources/HeuristicLab.Services.Hive/3.3/Convert.cs (revision 9664)
+++ /trunk/sources/HeuristicLab.Services.Hive/3.3/Convert.cs (revision 9665)
@@ -102,5 +102,5 @@
public static DT.TaskData ToDto(DB.TaskData source) {
if (source == null) return null;
- return new DT.TaskData { TaskId = source.TaskId, Data = source.Data.ToArray(), LastUpdate = source.LastUpdate };
+ return new DT.TaskData { TaskId = source.TaskId, Data = source.Data, LastUpdate = source.LastUpdate };
}
public static DB.TaskData ToEntity(DT.TaskData source) {
@@ -111,5 +111,7 @@
public static void ToEntity(DT.TaskData source, DB.TaskData target) {
if ((source != null) && (target != null)) {
- target.TaskId = source.TaskId; target.Data = new Binary(source.Data); target.LastUpdate = source.LastUpdate;
+ target.TaskId = source.TaskId;
+ target.Data = source.Data;
+ target.LastUpdate = source.LastUpdate;
}
}
@@ -213,5 +215,8 @@
public static void ToEntity(DT.PluginData source, DB.PluginData target) {
if ((source != null) && (target != null)) {
- target.PluginDataId = source.Id; target.PluginId = source.PluginId; target.Data = new Binary(source.Data); target.FileName = source.FileName;
+ target.PluginDataId = source.Id;
+ target.PluginId = source.PluginId;
+ target.Data = source.Data;
+ target.FileName = source.FileName;
}
}
Index: /trunk/sources/HeuristicLab.Services.Hive/3.3/HeuristicLab.Services.Hive-3.3.csproj
===================================================================
--- /trunk/sources/HeuristicLab.Services.Hive/3.3/HeuristicLab.Services.Hive-3.3.csproj (revision 9664)
+++ /trunk/sources/HeuristicLab.Services.Hive/3.3/HeuristicLab.Services.Hive-3.3.csproj (revision 9665)
@@ -137,6 +137,9 @@
+
+
+
Index: /trunk/sources/HeuristicLab.Services.Hive/3.3/HiveDao.cs
===================================================================
--- /trunk/sources/HeuristicLab.Services.Hive/3.3/HiveDao.cs (revision 9664)
+++ /trunk/sources/HeuristicLab.Services.Hive/3.3/HiveDao.cs (revision 9665)
@@ -35,6 +35,4 @@
}
- public HiveDao() { }
-
#region Task Methods
public DT.Task GetTask(Guid id) {
@@ -666,5 +664,5 @@
}
- private void CollectParentResources(List resources, Resource resource) {
+ private static void CollectParentResources(ICollection resources, Resource resource) {
if (resource == null) return;
resources.Add(resource);
Index: /trunk/sources/HeuristicLab.Services.Hive/3.3/HiveOperationContext.cs
===================================================================
--- /trunk/sources/HeuristicLab.Services.Hive/3.3/HiveOperationContext.cs (revision 9665)
+++ /trunk/sources/HeuristicLab.Services.Hive/3.3/HiveOperationContext.cs (revision 9665)
@@ -0,0 +1,85 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2013 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.ObjectModel;
+using System.ServiceModel;
+using System.ServiceModel.Channels;
+using System.ServiceModel.Description;
+using System.ServiceModel.Dispatcher;
+using HeuristicLab.Services.Hive.DataAccess;
+
+namespace HeuristicLab.Services.Hive {
+ public class HiveOperationContext : IExtension {
+
+ public static HiveOperationContext Current {
+ get {
+ return OperationContext.Current != null
+ ? OperationContext.Current.Extensions.Find()
+ : null;
+ }
+ }
+
+ private HiveDataContext dataContext;
+ public HiveDataContext DataContext {
+ get {
+ return dataContext ?? (dataContext = new HiveDataContext(Settings.Default.HeuristicLab_Hive_LinqConnectionString));
+ }
+ }
+
+ public void Attach(OperationContext owner) {
+ }
+
+ public void Detach(OperationContext owner) {
+ if (dataContext != null) {
+ dataContext.Dispose();
+ }
+ }
+ }
+
+ public class HiveOperationContextMessageInspector : IDispatchMessageInspector {
+ public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext) {
+ OperationContext.Current.Extensions.Add(new HiveOperationContext());
+ return request.Headers.MessageId;
+ }
+
+ public void BeforeSendReply(ref Message reply, object correlationState) {
+ OperationContext.Current.Extensions.Remove(HiveOperationContext.Current);
+ }
+ }
+
+ public class HiveOperationContextBehaviorAttribute : Attribute, IServiceBehavior {
+ public void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase,
+ Collection endpoints, BindingParameterCollection bindingParameters) {
+ }
+
+ public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase) {
+ foreach (ChannelDispatcher cd in serviceHostBase.ChannelDispatchers) {
+ foreach (EndpointDispatcher ed in cd.Endpoints) {
+ ed.DispatchRuntime.MessageInspectors.Add(new HiveOperationContextMessageInspector());
+ }
+ }
+ }
+
+ public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase) {
+ }
+ }
+}
Index: /trunk/sources/HeuristicLab.Services.Hive/3.3/HiveService.cs
===================================================================
--- /trunk/sources/HeuristicLab.Services.Hive/3.3/HiveService.cs (revision 9664)
+++ /trunk/sources/HeuristicLab.Services.Hive/3.3/HiveService.cs (revision 9665)
@@ -37,8 +37,12 @@
///
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall, IgnoreExtensionDataObject = true)]
+ [HiveOperationContextBehavior]
public class HiveService : IHiveService {
private IHiveDao dao {
get { return ServiceLocator.Instance.HiveDao; }
}
+ private IOptimizedHiveDao optimizedDao {
+ get { return ServiceLocator.Instance.OptimizedHiveDao; }
+ }
private Access.IRoleVerifier authen {
get { return ServiceLocator.Instance.RoleVerifier; }
@@ -64,11 +68,17 @@
authen.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
return trans.UseTransaction(() => {
- task.Id = dao.AddTask(task);
- taskData.TaskId = task.Id;
- taskData.LastUpdate = DateTime.Now;
- dao.AssignJobToResource(task.Id, resourceIds);
- dao.AddTaskData(taskData);
- dao.UpdateTaskState(task.Id, DA.TaskState.Waiting, null, userManager.CurrentUserId, null);
- return taskData.TaskId;
+ var t = DT.Convert.ToEntity(task);
+ t.RequiredPlugins.AddRange(task.PluginsNeededIds.Select(pluginId => new DA.RequiredPlugin { Task = t, PluginId = pluginId }));
+
+ t.JobData = DT.Convert.ToEntity(taskData);
+ t.JobData.LastUpdate = DateTime.Now;
+
+ optimizedDao.AddTask(t);
+
+ dao.AssignJobToResource(t.TaskId, resourceIds);
+
+ optimizedDao.UpdateTaskState(t.TaskId, DA.TaskState.Waiting, null, userManager.CurrentUserId, null);
+
+ return t.TaskId;
}, false, true);
}
@@ -76,8 +86,6 @@
public Guid AddChildTask(Guid parentTaskId, Task task, TaskData taskData) {
authen.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
- return trans.UseTransaction(() => {
- task.ParentTaskId = parentTaskId;
- return AddTask(task, taskData, dao.GetAssignedResources(parentTaskId).Select(x => x.Id));
- }, false, true);
+ task.ParentTaskId = parentTaskId;
+ return AddTask(task, taskData, optimizedDao.GetAssignedResourceIds(parentTaskId));
}
@@ -87,5 +95,5 @@
return trans.UseTransaction(() => {
- return dao.GetTask(taskId);
+ return DT.Convert.ToDto(optimizedDao.GetTaskById(taskId));
}, false, false);
}
@@ -128,5 +136,5 @@
return trans.UseTransaction(() => {
- return dao.GetLightweightTasks(task => task.JobId == jobId).ToArray();
+ return optimizedDao.GetLightweightTasks(jobId).ToArray();
}, false, true);
}
@@ -155,5 +163,6 @@
trans.UseTransaction(() => {
- dao.UpdateTaskAndPlugins(taskDto);
+ var task = optimizedDao.GetTaskByDto(taskDto);
+ optimizedDao.UpdateTask(task);
});
}
@@ -164,10 +173,12 @@
trans.UseTransaction(() => {
- dao.UpdateTaskAndPlugins(task);
- });
-
- trans.UseTransaction(() => {
- taskData.LastUpdate = DateTime.Now;
- dao.UpdateTaskData(taskData);
+ var t = optimizedDao.GetTaskByDto(task);
+ optimizedDao.UpdateTask(t);
+ });
+
+ trans.UseTransaction(() => {
+ var data = optimizedDao.GetTaskDataByDto(taskData);
+ data.LastUpdate = DateTime.Now;
+ optimizedDao.UpdateTaskData(data);
});
}
@@ -196,20 +207,20 @@
authen.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client, HiveRoles.Slave);
author.AuthorizeForTask(taskId, Permission.Full);
- return trans.UseTransaction(() => {
- Task task = dao.UpdateTaskState(taskId, DataTransfer.Convert.ToEntity(taskState), slaveId, userId, exception);
-
- if (task.Command.HasValue && task.Command.Value == Command.Pause && task.State == TaskState.Paused) {
+
+ return trans.UseTransaction(() => {
+ var task = optimizedDao.UpdateTaskState(taskId, DT.Convert.ToEntity(taskState), slaveId, userId, exception);
+
+ if (task.Command.HasValue && task.Command.Value == DA.Command.Pause && task.State == DA.TaskState.Paused) {
task.Command = null;
- } else if (task.Command.HasValue && task.Command.Value == Command.Abort && task.State == TaskState.Aborted) {
+ } else if (task.Command.HasValue && task.Command.Value == DA.Command.Abort && task.State == DA.TaskState.Aborted) {
task.Command = null;
- } else if (task.Command.HasValue && task.Command.Value == Command.Stop && task.State == TaskState.Aborted) {
+ } else if (task.Command.HasValue && task.Command.Value == DA.Command.Stop && task.State == DA.TaskState.Aborted) {
task.Command = null;
} else if (taskState == TaskState.Paused && !task.Command.HasValue) {
// slave paused and uploaded the task (no user-command) -> set waiting.
- task = dao.UpdateTaskState(taskId, DataTransfer.Convert.ToEntity(TaskState.Waiting), slaveId, userId, exception);
- }
-
- dao.UpdateTaskAndPlugins(task);
- return task;
+ task = optimizedDao.UpdateTaskState(taskId, DA.TaskState.Waiting, slaveId, userId, exception);
+ }
+
+ return DT.Convert.ToDto(task);
});
}
@@ -463,5 +474,5 @@
authen.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client, HiveRoles.Slave);
return trans.UseTransaction(() => {
- return dao.GetPlugin(pluginId);
+ return DT.Convert.ToDto(optimizedDao.GetPluginById(pluginId));
});
}
Index: /trunk/sources/HeuristicLab.Services.Hive/3.3/Interfaces/IOptimizedHiveDao.cs
===================================================================
--- /trunk/sources/HeuristicLab.Services.Hive/3.3/Interfaces/IOptimizedHiveDao.cs (revision 9665)
+++ /trunk/sources/HeuristicLab.Services.Hive/3.3/Interfaces/IOptimizedHiveDao.cs (revision 9665)
@@ -0,0 +1,68 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2013 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.Linq;
+using HeuristicLab.Services.Hive.DataAccess;
+using DT = HeuristicLab.Services.Hive.DataTransfer;
+namespace HeuristicLab.Services.Hive {
+ public interface IOptimizedHiveDao {
+ #region Task Methods
+ Task GetTaskById(Guid task);
+ Task GetTaskByDto(DT.Task taskDto);
+ Tuple GetTaskByIdAndLastStateLogSlaveId(Guid taskId);
+
+ IEnumerable GetWaitingTasks(Slave slave);
+ IQueryable GetLightweightTasks(Guid jobId);
+
+ void UpdateTask(Task task);
+ Task UpdateTaskState(Guid taskId, TaskState taskState, Guid? slaveId, Guid? userId, string exception);
+
+ Guid AddTask(Task task);
+ void AssignJobToResource(Guid taskId, IEnumerable resourceIds);
+
+ bool TaskIsAllowedToBeCalculatedBySlave(Guid taskId, Guid slaveId);
+ #endregion
+
+ #region TaskData Methods
+ TaskData GetTaskDataByDto(DT.TaskData taskDataDto);
+ void UpdateTaskData(TaskData taskData);
+ #endregion
+
+ #region Plugin Methods
+ Plugin GetPluginById(Guid pluginId);
+ #endregion
+
+ #region Slave Methods
+ Slave GetSlaveById(Guid id);
+
+ void UpdateSlave(Slave slave);
+
+ bool SlaveHasToShutdownComputer(Guid slaveId);
+ bool SlaveIsAllowedToCalculate(Guid slaveId);
+ #endregion
+
+ #region Resource Methods
+ IEnumerable GetAssignedResourceIds(Guid jobId);
+ #endregion
+ }
+}
Index: /trunk/sources/HeuristicLab.Services.Hive/3.3/Interfaces/IServiceLocator.cs
===================================================================
--- /trunk/sources/HeuristicLab.Services.Hive/3.3/Interfaces/IServiceLocator.cs (revision 9664)
+++ /trunk/sources/HeuristicLab.Services.Hive/3.3/Interfaces/IServiceLocator.cs (revision 9665)
@@ -27,4 +27,5 @@
IAuthorizationManager AuthorizationManager { get; }
IHiveDao HiveDao { get; }
+ IOptimizedHiveDao OptimizedHiveDao { get; }
IEventManager EventManager { get; }
ITransactionManager TransactionManager { get; }
Index: /trunk/sources/HeuristicLab.Services.Hive/3.3/Manager/EventManager.cs
===================================================================
--- /trunk/sources/HeuristicLab.Services.Hive/3.3/Manager/EventManager.cs (revision 9664)
+++ /trunk/sources/HeuristicLab.Services.Hive/3.3/Manager/EventManager.cs (revision 9665)
@@ -78,5 +78,5 @@
//we have to find another way to deal with this.
//until then the next line is commented out...
- //stats.UserStatistics = dao.GetUserStatistics();
+ //stats.UserStatistics = dtoDao.GetUserStatistics();
dao.AddStatistics(stats);
}
Index: /trunk/sources/HeuristicLab.Services.Hive/3.3/Manager/HeartbeatManager.cs
===================================================================
--- /trunk/sources/HeuristicLab.Services.Hive/3.3/Manager/HeartbeatManager.cs (revision 9664)
+++ /trunk/sources/HeuristicLab.Services.Hive/3.3/Manager/HeartbeatManager.cs (revision 9665)
@@ -24,6 +24,6 @@
using System.Linq;
using System.Threading;
-using HeuristicLab.Services.Hive.DataTransfer;
-using DA = HeuristicLab.Services.Hive.DataAccess;
+using HeuristicLab.Services.Hive.DataAccess;
+using Heartbeat = HeuristicLab.Services.Hive.DataTransfer.Heartbeat;
namespace HeuristicLab.Services.Hive {
@@ -31,6 +31,6 @@
private const string MutexName = "HiveTaskSchedulingMutex";
- private IHiveDao dao {
- get { return ServiceLocator.Instance.HiveDao; }
+ private IOptimizedHiveDao dao {
+ get { return ServiceLocator.Instance.OptimizedHiveDao; }
}
private ITaskScheduler taskScheduler {
@@ -47,7 +47,9 @@
public List ProcessHeartbeat(Heartbeat heartbeat) {
List actions = new List();
+
Slave slave = null;
- slave = trans.UseTransaction(() => { return dao.GetSlave(heartbeat.SlaveId); });
-
+ trans.UseTransaction(() => {
+ slave = dao.GetSlaveById(heartbeat.SlaveId);
+ });
if (slave == null) {
actions.Add(new MessageContainer(MessageContainer.MessageType.SayHello));
@@ -56,5 +58,5 @@
actions.Add(new MessageContainer(MessageContainer.MessageType.NewHBInterval));
}
- if (ShutdownSlaveComputer(slave.Id)) {
+ if (dao.SlaveHasToShutdownComputer(slave.ResourceId)) {
actions.Add(new MessageContainer(MessageContainer.MessageType.ShutdownComputer));
}
@@ -64,9 +66,11 @@
slave.FreeMemory = heartbeat.FreeMemory;
slave.CpuUtilization = heartbeat.CpuUtilization;
- slave.IsAllowedToCalculate = SlaveIsAllowedToCalculate(slave.Id);
+ slave.IsAllowedToCalculate = dao.SlaveIsAllowedToCalculate(slave.ResourceId);
slave.SlaveState = (heartbeat.JobProgress != null && heartbeat.JobProgress.Count > 0) ? SlaveState.Calculating : SlaveState.Idle;
slave.LastHeartbeat = DateTime.Now;
- trans.UseTransaction(() => { dao.UpdateSlave(slave); });
+ trans.UseTransaction(() => {
+ dao.UpdateSlave(slave);
+ });
// update task data
@@ -78,22 +82,25 @@
var mutex = new Mutex(false, MutexName);
try {
+
mutexAquired = mutex.WaitOne(Properties.Settings.Default.SchedulingPatience);
if (!mutexAquired)
- DA.LogFactory.GetLogger(this.GetType().Namespace).Log("HeartbeatManager: The mutex used for scheduling could not be aquired.");
+ LogFactory.GetLogger(this.GetType().Namespace).Log("HeartbeatManager: The mutex used for scheduling could not be aquired.");
else {
- IEnumerable availableTasks = null;
- availableTasks = trans.UseTransaction(() => { return taskScheduler.Schedule(dao.GetWaitingTasks(slave)); });
- if (availableTasks.Any()) {
- var task = availableTasks.First();
- AssignJob(slave, task.TaskId);
- actions.Add(new MessageContainer(MessageContainer.MessageType.CalculateTask, task.TaskId));
- }
+ trans.UseTransaction(() => {
+ IEnumerable availableTasks = null;
+ availableTasks = taskScheduler.Schedule(dao.GetWaitingTasks(slave).ToArray());
+ if (availableTasks.Any()) {
+ var task = availableTasks.First();
+ AssignTask(slave, task.TaskId);
+ actions.Add(new MessageContainer(MessageContainer.MessageType.CalculateTask, task.TaskId));
+ }
+ });
}
}
catch (AbandonedMutexException) {
- DA.LogFactory.GetLogger(this.GetType().Namespace).Log("HeartbeatManager: The mutex used for scheduling has been abandoned.");
+ LogFactory.GetLogger(this.GetType().Namespace).Log("HeartbeatManager: The mutex used for scheduling has been abandoned.");
}
catch (Exception ex) {
- DA.LogFactory.GetLogger(this.GetType().Namespace).Log("HeartbeatManager threw an exception in ProcessHeartbeat: " + ex.ToString());
+ LogFactory.GetLogger(this.GetType().Namespace).Log("HeartbeatManager threw an exception in ProcessHeartbeat: " + ex.ToString());
}
finally {
@@ -105,12 +112,10 @@
}
- private void AssignJob(Slave slave, Guid taskId) {
- trans.UseTransaction(() => {
- var task = dao.UpdateTaskState(taskId, DataAccess.TaskState.Transferring, slave.Id, null, null);
+ private void AssignTask(Slave slave, Guid taskId) {
+ var task = dao.UpdateTaskState(taskId, TaskState.Transferring, slave.ResourceId, null, null);
- // from now on the task has some time to send the next heartbeat (ApplicationConstants.TransferringJobHeartbeatTimeout)
- task.LastHeartbeat = DateTime.Now;
- dao.UpdateTask(task);
- });
+ // from now on the task has some time to send the next heartbeat (ApplicationConstants.TransferringJobHeartbeatTimeout)
+ task.LastHeartbeat = DateTime.Now;
+ dao.UpdateTask(task);
}
@@ -130,35 +135,41 @@
// process the jobProgresses
foreach (var jobProgress in heartbeat.JobProgress) {
- Task curTask = null;
- curTask = trans.UseTransaction(() => { return dao.GetTask(jobProgress.Key); });
+ Tuple taskWithLastStateLogSlaveId = null;
+ trans.UseTransaction(() => {
+ taskWithLastStateLogSlaveId = dao.GetTaskByIdAndLastStateLogSlaveId(jobProgress.Key);
+ });
+ var curTask = taskWithLastStateLogSlaveId != null ? taskWithLastStateLogSlaveId.Item1 : null;
if (curTask == null) {
// task does not exist in db
actions.Add(new MessageContainer(MessageContainer.MessageType.AbortTask, jobProgress.Key));
- DA.LogFactory.GetLogger(this.GetType().Namespace).Log("Task on slave " + heartbeat.SlaveId + " does not exist in DB: " + jobProgress.Key);
+ LogFactory.GetLogger(this.GetType().Namespace).Log("Task on slave " + heartbeat.SlaveId + " does not exist in DB: " + jobProgress.Key);
} else {
- if (curTask.CurrentStateLog.SlaveId == Guid.Empty || curTask.CurrentStateLog.SlaveId != heartbeat.SlaveId) {
+ var slaveId = taskWithLastStateLogSlaveId.Item2;
+ if (slaveId == Guid.Empty || slaveId != heartbeat.SlaveId) {
// assigned slave does not match heartbeat
- actions.Add(new MessageContainer(MessageContainer.MessageType.AbortTask, curTask.Id));
- DA.LogFactory.GetLogger(this.GetType().Namespace).Log("The slave " + heartbeat.SlaveId + " is not supposed to calculate task: " + curTask);
- } else if (!TaskIsAllowedToBeCalculatedBySlave(heartbeat.SlaveId, curTask)) {
+ actions.Add(new MessageContainer(MessageContainer.MessageType.AbortTask, curTask.TaskId));
+ LogFactory.GetLogger(this.GetType().Namespace).Log("The slave " + heartbeat.SlaveId + " is not supposed to calculate task: " + curTask);
+ } else if (!dao.TaskIsAllowedToBeCalculatedBySlave(curTask.TaskId, heartbeat.SlaveId)) {
// assigned resources ids of task do not match with slaveId (and parent resourceGroupIds); this might happen when slave is moved to different group
- actions.Add(new MessageContainer(MessageContainer.MessageType.PauseTask, curTask.Id));
+ actions.Add(new MessageContainer(MessageContainer.MessageType.PauseTask, curTask.TaskId));
} else {
// save task execution time
- curTask.ExecutionTime = jobProgress.Value;
+ curTask.ExecutionTimeMs = jobProgress.Value.TotalMilliseconds;
curTask.LastHeartbeat = DateTime.Now;
switch (curTask.Command) {
case Command.Stop:
- actions.Add(new MessageContainer(MessageContainer.MessageType.StopTask, curTask.Id));
+ actions.Add(new MessageContainer(MessageContainer.MessageType.StopTask, curTask.TaskId));
break;
case Command.Pause:
- actions.Add(new MessageContainer(MessageContainer.MessageType.PauseTask, curTask.Id));
+ actions.Add(new MessageContainer(MessageContainer.MessageType.PauseTask, curTask.TaskId));
break;
case Command.Abort:
- actions.Add(new MessageContainer(MessageContainer.MessageType.AbortTask, curTask.Id));
+ actions.Add(new MessageContainer(MessageContainer.MessageType.AbortTask, curTask.TaskId));
break;
}
- trans.UseTransaction(() => { dao.UpdateTask(curTask); });
+ trans.UseTransaction(() => {
+ dao.UpdateTask(curTask);
+ });
}
}
@@ -167,21 +178,4 @@
return actions;
}
-
- private bool TaskIsAllowedToBeCalculatedBySlave(Guid slaveId, Task curTask) {
- return trans.UseTransaction(() => {
- var assignedResourceIds = dao.GetAssignedResources(curTask.Id).Select(x => x.Id);
- var slaveResourceIds = dao.GetParentResources(slaveId).Select(x => x.Id);
- return assignedResourceIds.Any(x => slaveResourceIds.Contains(x));
- });
- }
-
- private bool SlaveIsAllowedToCalculate(Guid slaveId) {
- // the slave may only calculate if there is no downtime right now. this needs to be checked for every parent resource also
- return trans.UseTransaction(() => { return dao.GetParentResources(slaveId).All(r => dao.GetDowntimes(x => x.ResourceId == r.Id && x.DowntimeType == DA.DowntimeType.Offline && (DateTime.Now >= x.StartDate) && (DateTime.Now <= x.EndDate)).Count() == 0); });
- }
-
- private bool ShutdownSlaveComputer(Guid slaveId) {
- return trans.UseTransaction(() => { return dao.GetParentResources(slaveId).Any(r => dao.GetDowntimes(x => x.ResourceId == r.Id && x.DowntimeType == DA.DowntimeType.Shutdown && (DateTime.Now >= x.StartDate) && (DateTime.Now <= x.EndDate)).Count() != 0); });
- }
}
}
Index: /trunk/sources/HeuristicLab.Services.Hive/3.3/OptimizedHiveDao.cs
===================================================================
--- /trunk/sources/HeuristicLab.Services.Hive/3.3/OptimizedHiveDao.cs (revision 9665)
+++ /trunk/sources/HeuristicLab.Services.Hive/3.3/OptimizedHiveDao.cs (revision 9665)
@@ -0,0 +1,248 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2013 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.Linq;
+using System.Linq;
+using DT = HeuristicLab.Services.Hive.DataTransfer;
+
+namespace HeuristicLab.Services.Hive.DataAccess {
+ public class OptimizedHiveDao : IOptimizedHiveDao {
+ private HiveDataContext Db { get; set; }
+
+ public OptimizedHiveDao(HiveDataContext db) {
+ Db = db;
+ }
+
+ #region Task Methods
+ public Task GetTaskById(Guid taskId) {
+ return GetTaskByIdQuery(Db, taskId).SingleOrDefault();
+ }
+
+ private static readonly Func> GetTaskByIdQuery = CompiledQuery.Compile((HiveDataContext db, Guid taskId) =>
+ from t in db.Tasks
+ where t.TaskId == taskId
+ select t
+ );
+
+ public Task GetTaskByDto(DT.Task taskDto) {
+ var task = GetTaskById(taskDto.Id);
+ DT.Convert.ToEntity(taskDto, task);
+ return task;
+ }
+
+ public Tuple GetTaskByIdAndLastStateLogSlaveId(Guid taskId) {
+ return GetTaskByIdAndLastStateLogSlaveIdQuery(Db, taskId).SingleOrDefault();
+ }
+
+ private static readonly Func>> GetTaskByIdAndLastStateLogSlaveIdQuery = CompiledQuery.Compile((HiveDataContext db, Guid taskId) =>
+ from t in db.Tasks
+ let lastStateLog = t.StateLogs.OrderByDescending(sl => sl.DateTime).FirstOrDefault()
+ where t.TaskId == taskId
+ select new Tuple(t, lastStateLog != null ? lastStateLog.SlaveId : null)
+ );
+
+ private const string GetWaitingTasksQueryString = @"
+ WITH pr AS (
+ SELECT ResourceId, ParentResourceId
+ FROM [Resource]
+ WHERE ResourceId = {0}
+ UNION ALL
+ SELECT r.ResourceId, r.ParentResourceId
+ FROM [Resource] r JOIN pr ON r.ResourceId = pr.ParentResourceId
+ )
+ SELECT DISTINCT t.TaskId, t.JobId, t.Priority
+ FROM pr JOIN AssignedResources ar ON ar.ResourceId = pr.ResourceId
+ JOIN Task t ON t.TaskId = ar.TaskId
+ WHERE NOT (t.IsParentTask = 1 AND t.FinishWhenChildJobsFinished = 1)
+ AND t.TaskState = {1}
+ AND t.CoresNeeded <= {2}
+ AND t.MemoryNeeded <= {3}
+ ";
+
+ public IEnumerable GetWaitingTasks(Slave slave) {
+ //Originally we checked here if there are parent tasks which should be calculated (with GetParentTasks(resourceIds, count, false);).
+ //Because there is at the moment no case where this makes sense (there don't exist parent tasks which need to be calculated),
+ //we skip this step because it's wasted runtime
+ return Db.ExecuteQuery(GetWaitingTasksQueryString, slave.ResourceId, Enum.GetName(typeof(TaskState), TaskState.Waiting), slave.FreeCores, slave.FreeMemory);
+ }
+
+ public IQueryable GetLightweightTasks(Guid jobId) {
+ return GetLightweightTasksQuery(Db, jobId);
+ }
+
+ private static readonly Func> GetLightweightTasksQuery = CompiledQuery.Compile((HiveDataContext db, Guid jobId) =>
+ from task in db.Tasks
+ where task.JobId == jobId
+ select new DT.LightweightTask {
+ Id = task.TaskId,
+ ExecutionTime = TimeSpan.FromMilliseconds(task.ExecutionTimeMs),
+ ParentTaskId = task.ParentTaskId,
+ StateLog = task.StateLogs.OrderBy(sl => sl.DateTime).Select(sl => ConvertStateLog(sl)).ToList(),
+ State = ConvertTaskState(task.State),
+ Command = ConvertCommand(task.Command),
+ LastTaskDataUpdate = task.JobData.LastUpdate
+ }
+ );
+
+ private static readonly Func ConvertStateLog = sl => DT.Convert.ToDto(sl);
+ private static readonly Func ConvertTaskState = ts => DT.Convert.ToDto(ts);
+ private static readonly Func ConvertCommand = c => DT.Convert.ToDto(c);
+
+ public void UpdateTask(Task task) {
+ Db.SubmitChanges();
+ }
+
+ public Task UpdateTaskState(Guid taskId, TaskState taskState, Guid? slaveId, Guid? userId, string exception) {
+ Db.StateLogs.InsertOnSubmit(new StateLog {
+ TaskId = taskId,
+ State = taskState,
+ SlaveId = slaveId,
+ UserId = userId,
+ Exception = exception,
+ DateTime = DateTime.Now
+ });
+
+ var task = GetTaskById(taskId);
+ task.State = taskState;
+
+ Db.SubmitChanges();
+
+ return task;
+ }
+
+ public Guid AddTask(Task task) {
+ Db.Tasks.InsertOnSubmit(task);
+ Db.SubmitChanges();
+ return task.TaskId;
+ }
+
+ public void AssignJobToResource(Guid taskId, IEnumerable resourceIds) {
+ Db.AssignedResources.InsertAllOnSubmit(resourceIds.Select(resourceId => new AssignedResource { TaskId = taskId, ResourceId = resourceId }));
+ Db.SubmitChanges();
+ }
+
+ private const string TaskIsAllowedToBeCalculatedBySlaveQueryString = @"
+ WITH pr AS (
+ SELECT ResourceId, ParentResourceId
+ FROM [Resource]
+ WHERE ResourceId = {0}
+ UNION ALL
+ SELECT r.ResourceId, r.ParentResourceId
+ FROM [Resource] r JOIN pr ON r.ResourceId = pr.ParentResourceId
+ )
+ SELECT COUNT(ar.TaskId)
+ FROM pr JOIN AssignedResources ar ON pr.ResourceId = ar.ResourceId
+ WHERE ar.TaskId = {1}
+ ";
+
+ public bool TaskIsAllowedToBeCalculatedBySlave(Guid taskId, Guid slaveId) {
+ return Db.ExecuteQuery(TaskIsAllowedToBeCalculatedBySlaveQueryString, slaveId, taskId).First() > 0;
+ }
+ #endregion
+
+ #region TaskData Methods
+ public TaskData GetTaskDataById(Guid id) {
+ return GetTaskDataByIdQuery(Db, id).SingleOrDefault();
+ }
+
+ private static readonly Func> GetTaskDataByIdQuery = CompiledQuery.Compile((HiveDataContext db, Guid id) =>
+ from t in db.TaskDatas
+ where t.TaskId == id
+ select t
+ );
+
+ public TaskData GetTaskDataByDto(DT.TaskData dto) {
+ var taskData = GetTaskDataById(dto.TaskId);
+ DT.Convert.ToEntity(dto, taskData);
+ return taskData;
+ }
+
+ public void UpdateTaskData(TaskData taskData) {
+ Db.SubmitChanges();
+ }
+ #endregion
+
+ #region Plugin Methods
+ public Plugin GetPluginById(Guid pluginId) {
+ return GetPluginByIdQuery(Db, pluginId).SingleOrDefault();
+ }
+
+ private static readonly Func> GetPluginByIdQuery = CompiledQuery.Compile((HiveDataContext db, Guid pluginId) =>
+ from p in db.Plugins
+ where p.PluginId == pluginId
+ select p
+ );
+ #endregion
+
+ #region Slave Methods
+ public Slave GetSlaveById(Guid id) {
+ return GetSlaveByIdQuery(Db, id).SingleOrDefault();
+ }
+
+ private static readonly Func> GetSlaveByIdQuery = CompiledQuery.Compile((HiveDataContext db, Guid slaveId) =>
+ from s in db.Resources.OfType()
+ where s.ResourceId == slaveId
+ select s
+ );
+
+ public void UpdateSlave(Slave slave) {
+ Db.SubmitChanges();
+ }
+
+ private const string DowntimeQueryString = @"
+ WITH pr AS (
+ SELECT ResourceId, ParentResourceId
+ FROM [Resource]
+ WHERE ResourceId = {0}
+ UNION ALL
+ SELECT r.ResourceId, r.ParentResourceId
+ FROM [Resource] r JOIN pr ON r.ResourceId = pr.ParentResourceId
+ )
+ SELECT COUNT(dt.DowntimeId)
+ FROM pr JOIN [Downtime] dt ON pr.ResourceId = dt.ResourceId
+ WHERE {1} BETWEEN dt.StartDate AND dt.EndDate
+ AND dt.DowntimeType = {2}
+ ";
+
+ public bool SlaveHasToShutdownComputer(Guid slaveId) {
+ return Db.ExecuteQuery(DowntimeQueryString, slaveId, DateTime.Now, DowntimeType.Shutdown.ToString()).FirstOrDefault() > 0;
+ }
+
+ public bool SlaveIsAllowedToCalculate(Guid slaveId) {
+ return Db.ExecuteQuery(DowntimeQueryString, slaveId, DateTime.Now, DowntimeType.Offline.ToString()).FirstOrDefault() == 0;
+ }
+ #endregion
+
+ #region Resource Methods
+ public IEnumerable GetAssignedResourceIds(Guid taskId) {
+ return GetAssignedResourceIdsQuery(Db, taskId);
+ }
+
+ private static readonly Func> GetAssignedResourceIdsQuery = CompiledQuery.Compile((HiveDataContext db, Guid taskId) =>
+ from ar in db.AssignedResources
+ where ar.TaskId == taskId
+ select ar.ResourceId
+ );
+ #endregion
+ }
+}
Index: /trunk/sources/HeuristicLab.Services.Hive/3.3/ServiceLocator.cs
===================================================================
--- /trunk/sources/HeuristicLab.Services.Hive/3.3/ServiceLocator.cs (revision 9664)
+++ /trunk/sources/HeuristicLab.Services.Hive/3.3/ServiceLocator.cs (revision 9665)
@@ -39,4 +39,13 @@
if (hiveDao == null) hiveDao = new HiveDao();
return hiveDao;
+ }
+ }
+
+ public IOptimizedHiveDao OptimizedHiveDao {
+ get {
+ var dataContext = HiveOperationContext.Current != null
+ ? HiveOperationContext.Current.DataContext
+ : new HiveDataContext(Settings.Default.HeuristicLab_Hive_LinqConnectionString);
+ return new OptimizedHiveDao(dataContext);
}
}