Free cookie consent management tool by TermsFeed Policy Generator

Changeset 9123


Ignore:
Timestamp:
01/07/13 22:00:04 (11 years ago)
Author:
ascheibe
Message:

#1712 reintegrated Hive Scheduler branch and made further performance improvements

Location:
trunk/sources
Files:
2 added
19 edited
3 copied

Legend:

Unmodified
Added
Removed
  • trunk/sources/HeuristicLab.Services.Hive

  • trunk/sources/HeuristicLab.Services.Hive.DataAccess

  • trunk/sources/HeuristicLab.Services.Hive.DataAccess/3.3/HiveDataContext.dbml

    r8957 r9123  
    4242      <Association Name="Resource_Downtime" Member="Downtimes" Storage="_UptimeCalendars" ThisKey="ResourceId" OtherKey="ResourceId" Type="Downtime" />
    4343      <Association Name="Resource_StateLog" Member="StateLogs" ThisKey="ResourceId" OtherKey="SlaveId" Type="StateLog" />
    44       <Association Name="Resource_SlavePermission" Member="ResourcePermissions" ThisKey="ResourceId" OtherKey="ResourceId" Type="ResourcePermission" />
     44      <Association Name="Resource_ResourcePermission" Member="ResourcePermissions" ThisKey="ResourceId" OtherKey="ResourceId" Type="ResourcePermission" />
    4545      <Association Name="Resource_Resource" Member="ParentResource" ThisKey="ParentResourceId" OtherKey="ResourceId" Type="Resource" IsForeignKey="true" />
    4646      <Type Name="Slave" InheritanceCode="Slave" IsInheritanceDefault="true">
     
    201201      <Column Name="GrantedUserId" Type="System.Guid" DbType="UniqueIdentifier NOT NULL" IsPrimaryKey="true" CanBeNull="false" />
    202202      <Column Name="GrantedByUserId" Type="System.Guid" DbType="UniqueIdentifier NOT NULL" CanBeNull="false" />
    203       <Association Name="Resource_SlavePermission" Member="Resource" ThisKey="ResourceId" OtherKey="ResourceId" Type="Resource" IsForeignKey="true" />
     203      <Association Name="Resource_ResourcePermission" Member="Resource" ThisKey="ResourceId" OtherKey="ResourceId" Type="Resource" IsForeignKey="true" />
     204    </Type>
     205  </Table>
     206  <Table Name="" Member="UserPriorities">
     207    <Type Name="UserPriority">
     208      <Column Name="UserId" Type="System.Guid" DbType="UniqueIdentifier NOT NULL" IsPrimaryKey="true" CanBeNull="false" />
     209      <Column Name="DateEnqueued" Type="System.DateTime" DbType="DateTime NOT NULL" CanBeNull="false" />
    204210    </Type>
    205211  </Table>
  • trunk/sources/HeuristicLab.Services.Hive.DataAccess/3.3/HiveDataContext.dbml.layout

    r7916 r9123  
    3333      </nestedChildShapes>
    3434    </classShape>
    35     <classShape Id="8d5712f7-7a1a-4a89-bd4d-fd60200d3306" absoluteBounds="13.5, 2.5, 2, 2.1554996744791666">
     35    <classShape Id="8d5712f7-7a1a-4a89-bd4d-fd60200d3306" absoluteBounds="13.5, 2.5, 2, 2.3478011067708326">
    3636      <DataClassMoniker Name="/HiveDataContext/Downtime" />
    3737      <nestedChildShapes>
    38         <elementListCompartment Id="7d8f121b-35bb-4753-a25f-3fac1562e68e" absoluteBounds="13.515, 2.9600000000000009, 1.9700000000000002, 1.5954996744791665" name="DataPropertiesCompartment" titleTextColor="Black" itemTextColor="Black" />
     38        <elementListCompartment Id="7d8f121b-35bb-4753-a25f-3fac1562e68e" absoluteBounds="13.515, 2.9600000000000009, 1.9700000000000002, 1.7878011067708333" name="DataPropertiesCompartment" titleTextColor="Black" itemTextColor="Black" />
    3939      </nestedChildShapes>
    4040    </classShape>
     
    5757      </nestedChildShapes>
    5858    </classShape>
    59     <inheritanceConnector edgePoints="[(11.25 : 1.98159912109375); (10.875 : 1.98159912109375)]" fixedFrom="Algorithm" fixedTo="Algorithm" TargetRelationshipDomainClassId="7a7fe09e-e9ef-4b01-9ff3-bde95e827b62">
     59    <inheritanceConnector edgePoints="[(11.25 : 1.98159912109375); (10.875 : 1.98159912109375)]" fixedFrom="NotFixed" fixedTo="NotFixed" TargetRelationshipDomainClassId="7a7fe09e-e9ef-4b01-9ff3-bde95e827b62">
    6060      <nodes>
    6161        <classShapeMoniker Id="706a4581-6daf-4e71-ae2a-87d50b27a051" />
     
    6363      </nodes>
    6464    </inheritanceConnector>
    65     <inheritanceConnector edgePoints="[(13.25 : 1.40469482421875); (13.5 : 1.40469482421875)]" fixedFrom="Algorithm" fixedTo="Algorithm" TargetRelationshipDomainClassId="7a7fe09e-e9ef-4b01-9ff3-bde95e827b62">
     65    <inheritanceConnector edgePoints="[(13.25 : 1.40469482421875); (13.5 : 1.40469482421875)]" fixedFrom="NotFixed" fixedTo="NotFixed" TargetRelationshipDomainClassId="7a7fe09e-e9ef-4b01-9ff3-bde95e827b62">
    6666      <nodes>
    6767        <classShapeMoniker Id="706a4581-6daf-4e71-ae2a-87d50b27a051" />
     
    121121      </nestedChildShapes>
    122122    </classShape>
    123     <associationConnector edgePoints="[(11.25 : 1.45954756054688); (10.9375 : 1.45954756054688); (10.9375 : 0.6875); (2.75 : 0.6875); (2.75 : 1)]" fixedFrom="Algorithm" fixedTo="Algorithm">
     123    <associationConnector edgePoints="[(11.25 : 1.98159912109375); (10.9375 : 1.98159912109375); (10.9375 : 0.6875); (2.75 : 0.6875); (2.75 : 1)]" fixedFrom="NotFixed" fixedTo="NotFixed">
    124124      <AssociationMoniker Name="/HiveDataContext/Resource/Resource_StateLog" />
    125125      <nodes>
     
    172172      </nodes>
    173173    </associationConnector>
    174     <associationConnector edgePoints="[(13.25 : 2.73159912109375); (13.5 : 2.73159912109375)]" fixedFrom="Algorithm" fixedTo="Algorithm">
     174    <associationConnector edgePoints="[(13.25 : 2.73159912109375); (13.5 : 2.73159912109375)]" fixedFrom="NotFixed" fixedTo="NotFixed">
    175175      <AssociationMoniker Name="/HiveDataContext/Resource/Resource_Downtime" />
    176176      <nodes>
     
    234234      </nestedChildShapes>
    235235    </classShape>
    236     <associationConnector edgePoints="[(12.5942481820367 : 2.9631982421875); (12.5942481820367 : 3.875)]" fixedFrom="Algorithm" fixedTo="Algorithm">
    237       <AssociationMoniker Name="/HiveDataContext/Resource/Resource_SlavePermission" />
     236    <associationConnector edgePoints="[(12.5942481820367 : 2.9631982421875); (12.5942481820367 : 3.875)]" fixedFrom="NotFixed" fixedTo="NotFixed">
     237      <AssociationMoniker Name="/HiveDataContext/Resource/Resource_ResourcePermission" />
    238238      <nodes>
    239239        <classShapeMoniker Id="706a4581-6daf-4e71-ae2a-87d50b27a051" />
     
    241241      </nodes>
    242242    </associationConnector>
     243    <classShape Id="f9e8867f-fd15-4a72-8ca4-4f02cd3f141f" absoluteBounds="4.125, 5.5, 2, 1.1939925130208327">
     244      <DataClassMoniker Name="/HiveDataContext/UserPriority" />
     245      <nestedChildShapes>
     246        <elementListCompartment Id="ee41f516-7d9c-4a1d-a1b8-bbe00a6ffea8" absoluteBounds="4.14, 5.96, 1.9700000000000002, 0.63399251302083326" name="DataPropertiesCompartment" titleTextColor="Black" itemTextColor="Black" />
     247      </nestedChildShapes>
     248    </classShape>
    243249  </nestedChildShapes>
    244250</ordesignerObjectsDiagram>
  • trunk/sources/HeuristicLab.Services.Hive.DataAccess/3.3/HiveDataContext.designer.cs

    r8957 r9123  
    8282    partial void UpdateResourcePermission(ResourcePermission instance);
    8383    partial void DeleteResourcePermission(ResourcePermission instance);
     84    partial void InsertUserPriority(UserPriority instance);
     85    partial void UpdateUserPriority(UserPriority instance);
     86    partial void DeleteUserPriority(UserPriority instance);
    8487    #endregion
    8588   
     
    247250      {
    248251        return this.GetTable<ResourcePermission>();
     252      }
     253    }
     254   
     255    public System.Data.Linq.Table<UserPriority> UserPriorities
     256    {
     257      get
     258      {
     259        return this.GetTable<UserPriority>();
    249260      }
    250261    }
     
    10871098    }
    10881099   
    1089     [global::System.Data.Linq.Mapping.AssociationAttribute(Name="Resource_SlavePermission", Storage="_ResourcePermissions", ThisKey="ResourceId", OtherKey="ResourceId")]
     1100    [global::System.Data.Linq.Mapping.AssociationAttribute(Name="Resource_ResourcePermission", Storage="_ResourcePermissions", ThisKey="ResourceId", OtherKey="ResourceId")]
    10901101    public EntitySet<ResourcePermission> ResourcePermissions
    10911102    {
     
    43834394    }
    43844395   
    4385     [global::System.Data.Linq.Mapping.AssociationAttribute(Name="Resource_SlavePermission", Storage="_Resource", ThisKey="ResourceId", OtherKey="ResourceId", IsForeignKey=true)]
     4396    [global::System.Data.Linq.Mapping.AssociationAttribute(Name="Resource_ResourcePermission", Storage="_Resource", ThisKey="ResourceId", OtherKey="ResourceId", IsForeignKey=true)]
    43864397    public Resource Resource
    43874398    {
     
    44374448    }
    44384449  }
     4450 
     4451  [global::System.Data.Linq.Mapping.TableAttribute(Name="")]
     4452  public partial class UserPriority : INotifyPropertyChanging, INotifyPropertyChanged
     4453  {
     4454   
     4455    private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(String.Empty);
     4456   
     4457    private System.Guid _UserId;
     4458   
     4459    private System.DateTime _DateEnqueued;
     4460   
     4461    #region Extensibility Method Definitions
     4462    partial void OnLoaded();
     4463    partial void OnValidate(System.Data.Linq.ChangeAction action);
     4464    partial void OnCreated();
     4465    partial void OnUserIdChanging(System.Guid value);
     4466    partial void OnUserIdChanged();
     4467    partial void OnDateEnqueuedChanging(System.DateTime value);
     4468    partial void OnDateEnqueuedChanged();
     4469    #endregion
     4470   
     4471    public UserPriority()
     4472    {
     4473      OnCreated();
     4474    }
     4475   
     4476    [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_UserId", DbType="UniqueIdentifier NOT NULL", IsPrimaryKey=true)]
     4477    public System.Guid UserId
     4478    {
     4479      get
     4480      {
     4481        return this._UserId;
     4482      }
     4483      set
     4484      {
     4485        if ((this._UserId != value))
     4486        {
     4487          this.OnUserIdChanging(value);
     4488          this.SendPropertyChanging();
     4489          this._UserId = value;
     4490          this.SendPropertyChanged("UserId");
     4491          this.OnUserIdChanged();
     4492        }
     4493      }
     4494    }
     4495   
     4496    [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_DateEnqueued", DbType="DateTime NOT NULL")]
     4497    public System.DateTime DateEnqueued
     4498    {
     4499      get
     4500      {
     4501        return this._DateEnqueued;
     4502      }
     4503      set
     4504      {
     4505        if ((this._DateEnqueued != value))
     4506        {
     4507          this.OnDateEnqueuedChanging(value);
     4508          this.SendPropertyChanging();
     4509          this._DateEnqueued = value;
     4510          this.SendPropertyChanged("DateEnqueued");
     4511          this.OnDateEnqueuedChanged();
     4512        }
     4513      }
     4514    }
     4515   
     4516    public event PropertyChangingEventHandler PropertyChanging;
     4517   
     4518    public event PropertyChangedEventHandler PropertyChanged;
     4519   
     4520    protected virtual void SendPropertyChanging()
     4521    {
     4522      if ((this.PropertyChanging != null))
     4523      {
     4524        this.PropertyChanging(this, emptyChangingEventArgs);
     4525      }
     4526    }
     4527   
     4528    protected virtual void SendPropertyChanged(String propertyName)
     4529    {
     4530      if ((this.PropertyChanged != null))
     4531      {
     4532        this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
     4533      }
     4534    }
     4535  }
    44394536}
    44404537#pragma warning restore 1591
  • trunk/sources/HeuristicLab.Services.Hive.DataAccess/3.3/SQL Scripts/Initialize Hive Database.sql

    r8957 r9123  
    122122  CONSTRAINT [PK_Lifecycle] PRIMARY KEY ([LifecycleId])
    123123  )
     124CREATE TABLE [UserPriority](
     125  [UserId] UniqueIdentifier NOT NULL,
     126  [DateEnqueued] DateTime NOT NULL,
     127  CONSTRAINT [PK_UserPriority] PRIMARY KEY ([UserId])
     128  )
    124129CREATE TABLE [DeletedJobStatistics](
    125130  [UserId] UniqueIdentifier NOT NULL,
  • trunk/sources/HeuristicLab.Services.Hive/3.3/Convert.cs

    r8957 r9123  
    527527    }
    528528    #endregion
     529
     530    #region UserPriority
     531    public static DT.UserPriority ToDto(DB.UserPriority source) {
     532      if (source == null) return null;
     533      return new DT.UserPriority() { Id = source.UserId, DateEnqueued = source.DateEnqueued };
     534    }
     535    public static DB.UserPriority ToEntity(DT.UserPriority source) {
     536      if (source == null) return null;
     537      var entity = new DB.UserPriority(); ToEntity(source, entity);
     538      return entity;
     539    }
     540    public static void ToEntity(DT.UserPriority source, DB.UserPriority target) {
     541      if ((source != null) && (target != null)) {
     542        target.UserId = source.Id;
     543        target.DateEnqueued = source.DateEnqueued;
     544      }
     545    }
     546    #endregion
    529547  }
    530548}
  • trunk/sources/HeuristicLab.Services.Hive/3.3/HeuristicLab.Services.Hive-3.3.csproj

    r8600 r9123  
    114114    <Compile Include="Convert.cs" />
    115115    <Compile Include="DataTransfer\Command.cs" />
     116    <Compile Include="DataTransfer\UserPriority.cs" />
    116117    <Compile Include="DataTransfer\ResourcePermission.cs" />
    117118    <Compile Include="DataTransfer\Downtime.cs" />
     
    139140    <Compile Include="HiveJanitor.cs" />
    140141    <Compile Include="Interfaces\IHiveDao.cs" />
     142    <Compile Include="Interfaces\ITaskScheduler.cs" />
     143    <Compile Include="Scheduler\TaskInfoForScheduler.cs" />
     144    <Compile Include="Scheduler\JobInfoForScheduler.cs" />
     145    <Compile Include="Scheduler\RoundRobinTaskScheduler.cs" />
    141146    <Compile Include="Settings.cs" />
    142147    <None Include="app.config" />
     
    196201  </PropertyGroup>
    197202  <PropertyGroup>
    198    <PreBuildEvent Condition=" '$(OS)' == 'Windows_NT' ">set Path=%25Path%25;$(ProjectDir);$(SolutionDir)
     203    <PreBuildEvent Condition=" '$(OS)' == 'Windows_NT' ">set Path=%25Path%25;$(ProjectDir);$(SolutionDir)
    199204set ProjectDir=$(ProjectDir)
    200205set SolutionDir=$(SolutionDir)
     
    202207
    203208call PreBuildEvent.cmd</PreBuildEvent>
    204 <PreBuildEvent Condition=" '$(OS)' != 'Windows_NT' ">
     209    <PreBuildEvent Condition=" '$(OS)' != 'Windows_NT' ">
    205210export ProjectDir=$(ProjectDir)
    206211export SolutionDir=$(SolutionDir)
  • trunk/sources/HeuristicLab.Services.Hive/3.3/HiveDao.cs

    r9035 r9123  
    8484    }
    8585
    86     public void UpdateTask(DT.Task dto) {
     86    public void UpdateTaskAndPlugins(DT.Task dto) {
    8787      using (var db = CreateContext()) {
    8888        var entity = db.Tasks.FirstOrDefault(x => x.TaskId == dto.Id);
     
    9494          }
    9595        }
     96        db.SubmitChanges();
     97      }
     98    }
     99
     100    public void UpdateTask(DT.Task dto) {
     101      using (var db = CreateContext()) {
     102        var entity = db.Tasks.FirstOrDefault(x => x.TaskId == dto.Id);
     103        if (entity == null) db.Tasks.InsertOnSubmit(DT.Convert.ToEntity(dto));
     104        else DT.Convert.ToEntity(dto, entity);
    96105        db.SubmitChanges();
    97106      }
     
    134143    }
    135144
    136     public IEnumerable<DT.Task> GetWaitingTasks(DT.Slave slave, int count) {
     145    public IEnumerable<TaskInfoForScheduler> GetWaitingTasks(DT.Slave slave) {
    137146      using (var db = CreateContext()) {
    138147        var resourceIds = GetParentResources(slave.Id).Select(r => r.Id);
     
    147156                       && ar.Task.CoresNeeded <= slave.FreeCores
    148157                       && ar.Task.MemoryNeeded <= slave.FreeMemory
    149                     orderby ar.Task.Priority descending, db.Random() // take random task to avoid the race condition that occurs when this method is called concurrently (the same task would be returned)
    150                     select DT.Convert.ToDto(ar.Task);
    151         var waitingTasks = (count == 0 ? query : query.Take(count)).ToArray();
     158                    select new TaskInfoForScheduler() { TaskId = ar.Task.TaskId, JobId = ar.Task.JobId, Priority = ar.Task.Priority };
     159        var waitingTasks = query.ToArray();
    152160        return waitingTasks;
    153161      }
     
    277285    }
    278286
     287    public IEnumerable<JobInfoForScheduler> GetJobInfoForScheduler(Expression<Func<Job, bool>> predicate) {
     288      using (var db = CreateContext()) {
     289        return db.Jobs.Where(predicate).Select(x => new JobInfoForScheduler() { Id = x.JobId, DateCreated = x.DateCreated, OwnerUserId = x.OwnerUserId }).ToArray();
     290      }
     291    }
     292
    279293    public Guid AddJob(DT.Job dto) {
    280294      using (var db = CreateContext()) {
    281295        var entity = DT.Convert.ToEntity(dto);
    282296        db.Jobs.InsertOnSubmit(entity);
     297        if (!db.UserPriorities.Any(x => x.UserId == dto.OwnerUserId))
     298          EnqueueUserPriority(new DT.UserPriority { Id = dto.OwnerUserId, DateEnqueued = dto.DateCreated });
    283299        db.SubmitChanges();
    284300        return entity.JobId;
     
    923939    #endregion
    924940
     941    #region UserPriority Methods
     942    public IEnumerable<DT.UserPriority> GetUserPriorities(Expression<Func<UserPriority, bool>> predicate) {
     943      using (var db = CreateContext()) {
     944        return db.UserPriorities.Where(predicate).Select(x => DT.Convert.ToDto(x)).ToArray();
     945      }
     946    }
     947
     948    public void EnqueueUserPriority(DT.UserPriority dto) {
     949      using (var db = CreateContext()) {
     950        var entity = db.UserPriorities.FirstOrDefault(x => x.UserId == dto.Id);
     951        if (entity == null) db.UserPriorities.InsertOnSubmit(DT.Convert.ToEntity(dto));
     952        else DT.Convert.ToEntity(dto, entity);
     953        db.SubmitChanges();
     954      }
     955    }
     956    #endregion
     957
    925958    #region Helpers
    926959    private void CollectChildTasks(HiveDataContext db, Guid parentTaskId, List<Task> collection) {
  • trunk/sources/HeuristicLab.Services.Hive/3.3/HiveService.cs

    r9035 r9123  
    142142      author.AuthorizeForTask(taskDto.Id, Permission.Full);
    143143      trans.UseTransaction(() => {
    144         dao.UpdateTask(taskDto);
     144        dao.UpdateTaskAndPlugins(taskDto);
    145145      });
    146146    }
     
    152152      //trans.UseTransaction(() => { // cneumuel: try without transaction
    153153      taskData.LastUpdate = DateTime.Now;
    154       dao.UpdateTask(task);
     154      dao.UpdateTaskAndPlugins(task);
    155155      dao.UpdateTaskData(taskData);
    156156      //}, false, true);
     
    194194        }
    195195
    196         dao.UpdateTask(task);
     196        dao.UpdateTaskAndPlugins(task);
    197197        return task;
    198198      });
     
    499499    #endregion
    500500
     501    #region Resource Methods
     502    public IEnumerable<Resource> GetChildResources(Guid resourceId) {
     503      return dao.GetChildResources(resourceId);
     504    }
     505    #endregion
     506
    501507    #region Slave Methods
    502508    public int GetNewHeartbeatInterval(Guid slaveId) {
     
    671677    #endregion
    672678
     679    #region UserPriority Methods
     680    public IEnumerable<UserPriority> GetUserPriorities() {
     681      return trans.UseTransaction(() => dao.GetUserPriorities(x => true));
     682    }
     683    #endregion
     684
    673685    #region Helper Methods
    674686    private IEnumerable<Task> GetChildTasks(Guid? parentTaskId, bool recursive, bool includeParent) {
     
    687699    }
    688700    #endregion
     701
     702    #region Statistics Methods
     703    public IEnumerable<Statistics> GetStatistics() {
     704      return dao.GetStatistics(x => true);
     705    }
     706    public IEnumerable<Statistics> GetStatisticsForTimePeriod(DateTime from, DateTime to) {
     707      return dao.GetStatistics(x => x.Timestamp >= from && x.Timestamp <= to);
     708    }
     709    #endregion
    689710  }
    690711}
  • trunk/sources/HeuristicLab.Services.Hive/3.3/Interfaces/IHiveDao.cs

    r9035 r9123  
    3333    IEnumerable<DT.LightweightTask> GetLightweightTasks(Expression<Func<Task, bool>> predicate);
    3434    Guid AddTask(DT.Task dto);
     35    void UpdateTaskAndPlugins(DT.Task dto);
    3536    void UpdateTask(DT.Task dto);
    3637    void DeleteTask(Guid id);
    37     IEnumerable<DT.Task> GetWaitingTasks(DT.Slave slave, int count);
     38    IEnumerable<TaskInfoForScheduler> GetWaitingTasks(DT.Slave slave);
    3839    IEnumerable<DT.Task> GetParentTasks(IEnumerable<Guid> resourceIds, int count, bool finished);
    3940    DT.Task UpdateTaskState(Guid taskId, TaskState taskState, Guid? slaveId, Guid? userId, string exception);
     
    5960    DT.Job GetJob(Guid id);
    6061    IEnumerable<DT.Job> GetJobs(Expression<Func<Job, bool>> predicate);
     62    IEnumerable<JobInfoForScheduler> GetJobInfoForScheduler(Expression<Func<Job, bool>> predicate);
    6163    Guid AddJob(DT.Job dto);
    6264    void UpdateJob(DT.Job dto);
     
    156158    List<DT.UserStatistics> GetUserStatistics();
    157159    #endregion
     160
     161    #region UserPriority Methods
     162    IEnumerable<DT.UserPriority> GetUserPriorities(Expression<Func<UserPriority, bool>> predicate);
     163    void EnqueueUserPriority(DT.UserPriority userPriority);
     164    #endregion
    158165  }
    159166}
  • trunk/sources/HeuristicLab.Services.Hive/3.3/Interfaces/IServiceLocator.cs

    r8051 r9123  
    3131    Access.IUserManager UserManager { get; }
    3232    HeartbeatManager HeartbeatManager { get; }
     33    ITaskScheduler TaskScheduler { get; }
    3334  }
    3435}
  • trunk/sources/HeuristicLab.Services.Hive/3.3/Interfaces/ITaskScheduler.cs

    r9106 r9123  
    2525namespace HeuristicLab.Services.Hive {
    2626  public interface ITaskScheduler {
    27     IEnumerable<Task> Schedule(IEnumerable<Task> tasks, int count = 1);
     27    IEnumerable<TaskInfoForScheduler> Schedule(IEnumerable<TaskInfoForScheduler> tasks, int count = 1);
    2828  }
    2929}
  • trunk/sources/HeuristicLab.Services.Hive/3.3/Manager/HeartbeatManager.cs

    r8957 r9123  
    2323using System.Collections.Generic;
    2424using System.Linq;
     25using System.Threading;
    2526using HeuristicLab.Services.Hive.DataTransfer;
    2627using DA = HeuristicLab.Services.Hive.DataAccess;
     
    2829namespace HeuristicLab.Services.Hive {
    2930  public class HeartbeatManager {
     31    private const string MutexName = "HiveTaskSchedulingMutex";
     32
    3033    private IHiveDao dao {
    3134      get { return ServiceLocator.Instance.HiveDao; }
    3235    }
    33     private IAuthorizationManager auth {
    34       get { return ServiceLocator.Instance.AuthorizationManager; }
     36    private ITaskScheduler taskScheduler {
     37      get { return ServiceLocator.Instance.TaskScheduler; }
    3538    }
    3639
     
    6669        // assign new task
    6770        if (heartbeat.AssignJob && slave.IsAllowedToCalculate && heartbeat.FreeCores > 0) {
    68           var availableJobs = dao.GetWaitingTasks(slave, 1);
    69           if (availableJobs.Count() > 0) {
    70             var job = availableJobs.First();
    71             if (AssignJob(slave, job))
    72               actions.Add(new MessageContainer(MessageContainer.MessageType.CalculateTask, job.Id));
     71          bool mutexAquired = false;
     72          var mutex = new Mutex(false, MutexName);
     73          try {
     74            mutexAquired = mutex.WaitOne(Properties.Settings.Default.SchedulingPatience);
     75            if (!mutexAquired)
     76              DA.LogFactory.GetLogger(this.GetType().Namespace).Log("HeartbeatManager: The mutex used for scheduling could not be aquired.");
     77            else {
     78              var availableTasks = taskScheduler.Schedule(dao.GetWaitingTasks(slave));
     79              if (availableTasks.Any()) {
     80                var task = availableTasks.First();
     81                AssignJob(slave, task.TaskId);
     82                actions.Add(new MessageContainer(MessageContainer.MessageType.CalculateTask, task.TaskId));
     83              }
     84            }
     85          }
     86          catch (AbandonedMutexException) {
     87            DA.LogFactory.GetLogger(this.GetType().Namespace).Log("HeartbeatManager: The mutex used for scheduling has been abandoned.");
     88          }
     89          catch (Exception ex) {
     90            DA.LogFactory.GetLogger(this.GetType().Namespace).Log("HeartbeatManager threw an exception in ProcessHeartbeat: " + ex.ToString());
     91          }
     92          finally {
     93            if (mutexAquired) mutex.ReleaseMutex();
    7394          }
    7495        }
     
    7798    }
    7899
    79     // returns true if assignment was successful
    80     private bool AssignJob(Slave slave, Task task) {
    81       // load task again and check if it is still available (this is an attempt to reduce the race condition which causes multiple heartbeats to get the same task assigned)
    82       if (dao.GetTask(task.Id).State != TaskState.Waiting) return false;
    83 
    84       task = dao.UpdateTaskState(task.Id, DataAccess.TaskState.Transferring, slave.Id, null, null);
     100    private void AssignJob(Slave slave, Guid taskId) {
     101      var task = dao.UpdateTaskState(taskId, DataAccess.TaskState.Transferring, slave.Id, null, null);
    85102
    86103      // from now on the task has some time to send the next heartbeat (ApplicationConstants.TransferringJobHeartbeatTimeout)
    87104      task.LastHeartbeat = DateTime.Now;
    88105      dao.UpdateTask(task);
    89       return true;
    90106    }
    91107
  • trunk/sources/HeuristicLab.Services.Hive/3.3/Properties/Settings.Designer.cs

    r7857 r9123  
    22// <auto-generated>
    33//     This code was generated by a tool.
    4 //     Runtime Version:4.0.30319.269
     4//     Runtime Version:4.0.30319.17929
    55//
    66//     Changes to this file may cause incorrect behavior and will be lost if
     
    1313   
    1414    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
    15     [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "10.0.0.0")]
     15    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")]
    1616    public sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
    1717       
     
    7777            }
    7878        }
     79       
     80        [global::System.Configuration.ApplicationScopedSettingAttribute()]
     81        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
     82        [global::System.Configuration.DefaultSettingValueAttribute("00:00:20")]
     83        public global::System.TimeSpan SchedulingPatience {
     84            get {
     85                return ((global::System.TimeSpan)(this["SchedulingPatience"]));
     86            }
     87        }
    7988    }
    8089}
  • trunk/sources/HeuristicLab.Services.Hive/3.3/Properties/Settings.settings

    r7857 r9123  
    2121      <Value Profile="(Default)">3.00:00:00</Value>
    2222    </Setting>
     23    <Setting Name="SchedulingPatience" Type="System.TimeSpan" Scope="Application">
     24      <Value Profile="(Default)">00:00:20</Value>
     25    </Setting>
    2326  </Settings>
    2427</SettingsFile>
  • trunk/sources/HeuristicLab.Services.Hive/3.3/Scheduler/RoundRobinTaskScheduler.cs

    r8998 r9123  
    3131    }
    3232
    33     public IEnumerable<Task> Schedule(IEnumerable<Task> tasks, int count = 1) {
    34       if (!tasks.Any()) return Enumerable.Empty<Task>();
     33    public IEnumerable<TaskInfoForScheduler> Schedule(IEnumerable<TaskInfoForScheduler> tasks, int count = 1) {
     34      if (!tasks.Any()) return Enumerable.Empty<TaskInfoForScheduler>();
    3535
    3636      var userPriorities = dao.GetUserPriorities(x => true).OrderBy(x => x.DateEnqueued).ToArray();
    3737
    38       var jobs = new List<Job>();
     38      var jobs = new List<JobInfoForScheduler>();
    3939      foreach (var userPriority in userPriorities) {
    40         jobs.AddRange(dao.GetJobs(x => x.OwnerUserId == userPriority.Id));
     40        jobs.AddRange(dao.GetJobInfoForScheduler(x => x.OwnerUserId == userPriority.Id));
    4141      }
    4242
     
    4444        task => task.JobId,
    4545        job => job.Id,
    46         (task, job) => new { Task = task, Job = job })
     46        (task, job) => new { Task = task, JobInfo = job })
    4747        .OrderByDescending(x => x.Task.Priority)
    4848        .ToList();
    4949
    50       var scheduledTasks = new List<Task>();
     50      var scheduledTasks = new List<TaskInfoForScheduler>();
    5151      int priorityIndex = 0;
    5252
     
    5555      for (int i = 0; i < count; i++) {
    5656        var defaultEntry = taskJobRelations.First(); // search first task which is not included yet
    57         var priorityEntries = taskJobRelations.Where(x => x.Job.OwnerUserId == userPriorities[priorityIndex].Id).ToArray(); // search for tasks with desired user priority
    58         while (!priorityEntries.Any() && ++priorityIndex < userPriorities.Length)
    59           priorityEntries = taskJobRelations.Where(x => x.Job.OwnerUserId == userPriorities[priorityIndex].Id).ToArray();
     57        var priorityEntries = taskJobRelations.Where(x => x.JobInfo.OwnerUserId == userPriorities[priorityIndex].Id).ToArray(); // search for tasks with desired user priority
     58        while (!priorityEntries.Any() && priorityIndex < userPriorities.Length - 1) {
     59          priorityIndex++;
     60          priorityEntries = taskJobRelations.Where(x => x.JobInfo.OwnerUserId == userPriorities[priorityIndex].Id).ToArray();
     61        }
    6062        if (priorityEntries.Any()) { // tasks with desired user priority found
    61           var priorityEntry = priorityEntries.OrderByDescending(x => x.Task.Priority).ThenBy(x => x.Job.DateCreated).First();
     63          var priorityEntry = priorityEntries.OrderByDescending(x => x.Task.Priority).ThenBy(x => x.JobInfo.DateCreated).First();
    6264          if (defaultEntry.Task.Priority <= priorityEntry.Task.Priority) {
    6365            taskJobRelations.Remove(priorityEntry);
    6466            scheduledTasks.Add(priorityEntry.Task);
     67            UpdateUserPriority(userPriorities[priorityIndex]);
    6568            priorityIndex++;
    6669          } else { // there are other tasks with higher priorities
     
    7275          scheduledTasks.Add(defaultEntry.Task);
    7376        }
     77
     78        if (priorityIndex >= (userPriorities.Length - 1)) priorityIndex = 0;
    7479      }
    75 
    76       // requeue user priorities
    77       if (priorityIndex < userPriorities.Length)
    78         for (int i = 0; i < priorityIndex; i++) {
    79           userPriorities[i].DateEnqueued = DateTime.Now;
    80           dao.EnqueueUserPriority(userPriorities[i]);
    81         }
    8280
    8381      return scheduledTasks;
    8482    }
     83
     84    private void UpdateUserPriority(UserPriority up) {
     85      up.DateEnqueued = DateTime.Now;
     86      dao.EnqueueUserPriority(up);
     87    }
    8588  }
    8689}
  • trunk/sources/HeuristicLab.Services.Hive/3.3/ServiceContracts/IHiveService.cs

    r8071 r9123  
    168168    #endregion
    169169
     170    #region Resource Methods
     171    [OperationContract]
     172    IEnumerable<Resource> GetChildResources(Guid resourceId);
     173    #endregion
     174
    170175    #region Slave Methods
    171176    [OperationContract]
     
    238243    [OperationContract]
    239244    Guid GetUserIdByUsername(string username);
     245    #endregion
     246
     247    #region UserPriorities Methods
     248    [OperationContract]
     249    IEnumerable<UserPriority> GetUserPriorities();
     250    #endregion
     251
     252    #region Statistics Methods
     253    [OperationContract]
     254    IEnumerable<Statistics> GetStatistics();
     255    [OperationContract]
     256    IEnumerable<Statistics> GetStatisticsForTimePeriod(DateTime from, DateTime to);
    240257    #endregion
    241258  }
  • trunk/sources/HeuristicLab.Services.Hive/3.3/ServiceLocator.cs

    r8051 r9123  
    8989      }
    9090    }
     91
     92    private ITaskScheduler taskScheduler;
     93    public ITaskScheduler TaskScheduler {
     94      get {
     95        if (taskScheduler == null) taskScheduler = new RoundRobinTaskScheduler();
     96        return taskScheduler;
     97      }
     98    }
    9199  }
    92100}
  • trunk/sources/HeuristicLab.Services.Hive/3.3/app.config

    r7857 r9123  
    2626                <value>3.00:00:00</value>
    2727            </setting>
     28            <setting name="SchedulingPatience" serializeAs="String">
     29                <value>00:00:20</value>
     30            </setting>
    2831        </HeuristicLab.Services.Hive.Properties.Settings>
    2932    </applicationSettings>
Note: See TracChangeset for help on using the changeset viewer.