Changeset 500
- Timestamp:
- 08/11/08 22:31:03 (17 years ago)
- Location:
- trunk/sources/HeuristicLab.Grid
- Files:
-
- 2 added
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
TabularUnified trunk/sources/HeuristicLab.Grid/EngineStore.cs ¶
r499 r500 23 23 using System.Collections.Generic; 24 24 using System.Text; 25 using System.Linq; 25 26 using System.Threading; 26 27 using System.ServiceModel; 28 using System.Data.Common; 27 29 28 30 namespace HeuristicLab.Grid { 29 31 [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode = ConcurrencyMode.Multiple, UseSynchronizationContext = false)] 30 32 public class EngineStore : IEngineStore { 31 private List<Guid> engineList;32 private Dictionary<Guid, byte[]> waitingEngines;33 private Dictionary<Guid, byte[]> runningEngines;34 33 private Dictionary<Guid, ManualResetEvent> waitHandles; 35 private D ictionary<Guid, byte[]> results;36 private Dictionary<Guid, DateTime> resultDate; 37 private Dictionary<Guid, DateTime> runningEngineDate;38 private const int RESULT_EXPIRY_TIME_MIN = 10;39 private const int RUNNING_JOB_EXPIRY_TIME_MIN = 10; 40 private object bigLock;34 private Database database; 35 36 private static readonly string dbFile = AppDomain.CurrentDomain.BaseDirectory + "/enginestore.db3"; 37 private static readonly string connectionString = "Data Source=\"" + dbFile + "\";Pooling=False"; 38 39 private int waitingJobs; 41 40 public int WaitingJobs { 42 41 get { 43 return waiting Engines.Count;42 return waitingJobs; 44 43 } 45 44 } 46 45 private int runningJobs; 47 46 public int RunningJobs { 48 47 get { 49 return running Engines.Count;48 return runningJobs; 50 49 } 51 50 } 52 51 private int results; 53 52 public int WaitingResults { 54 53 get { 55 return results .Count;54 return results; 56 55 } 57 56 } 58 57 59 58 public EngineStore() { 60 engineList = new List<Guid>();61 waitingEngines = new Dictionary<Guid, byte[]>();62 runningEngines = new Dictionary<Guid, byte[]>();63 59 waitHandles = new Dictionary<Guid, ManualResetEvent>(); 64 results = new Dictionary<Guid, byte[]>(); 65 resultDate = new Dictionary<Guid, DateTime>(); 66 runningEngineDate = new Dictionary<Guid, DateTime>(); 67 bigLock = new object(); 60 DbProviderFactory fact; 61 fact = DbProviderFactories.GetFactory("System.Data.SQLite"); 62 if(!System.IO.File.Exists(dbFile)) { 63 database = new Database(connectionString); 64 database.CreateNew(); 65 } else { 66 database = new Database(connectionString); 67 } 68 database = new Database(connectionString); 68 69 } 69 70 71 private object t = new object(); 70 72 public bool TryTakeEngine(out Guid guid, out byte[] engine) { 71 lock( bigLock) {72 if(engineList.Count == 0) {73 guid = Guid.Empty;74 engine = null;73 lock(t) { 74 List<JobEntry> waitingJobs = database.GetWaitingJobs(); 75 if(waitingJobs.Count == 0) { 76 guid = Guid.Empty; engine = null; 75 77 return false; 76 78 } else { 77 guid = engineList[0]; 78 engineList.RemoveAt(0); 79 engine = waitingEngines[guid]; 80 waitingEngines.Remove(guid); 81 runningEngines[guid] = engine; 82 runningEngineDate[guid] = DateTime.Now; 79 JobEntry oldestEntry = waitingJobs.OrderBy(a => a.CreationTime).First(); 80 guid = oldestEntry.Guid; 81 engine = oldestEntry.RawData; 82 database.UpdateJobState(guid, HeuristicLab.Grid.JobState.Busy); 83 83 return true; 84 84 } … … 87 87 88 88 public void StoreResult(Guid guid, byte[] result) { 89 lock(bigLock) { 90 // clear old results 91 List<Guid> expiredResults = FindExpiredResults(DateTime.Now.AddMinutes(-RESULT_EXPIRY_TIME_MIN)); 92 foreach(Guid expiredGuid in expiredResults) { 93 results.Remove(expiredGuid); 94 waitHandles.Remove(expiredGuid); 95 resultDate.Remove(expiredGuid); 96 } 97 // add the new result 98 runningEngines.Remove(guid); 99 runningEngineDate.Remove(guid); 100 results[guid] = result; 101 resultDate[guid] = DateTime.Now; 102 waitHandles[guid].Set(); 103 } 104 } 105 106 private List<Guid> FindExpiredResults(DateTime expirationDate) { 107 List<Guid> expiredResults = new List<Guid>(); 108 foreach(Guid guid in results.Keys) { 109 if(resultDate[guid] < expirationDate) { 110 expiredResults.Add(guid); 111 } 112 } 113 return expiredResults; 114 } 115 private List<Guid> FindExpiredJobs(DateTime expirationDate) { 116 List<Guid> expiredJobs = new List<Guid>(); 117 foreach(Guid guid in runningEngines.Keys) { 118 if(runningEngineDate[guid] < expirationDate) { 119 expiredJobs.Add(guid); 120 } 121 } 122 return expiredJobs; 89 database.DeleteExpiredResults(); 90 // add the new result 91 database.SetJobResult(guid, result); 92 waitHandles[guid].Set(); 123 93 } 124 94 125 95 internal void AddEngine(Guid guid, byte[] engine) { 126 lock(bigLock) { 127 engineList.Add(guid); 128 waitingEngines.Add(guid, engine); 129 waitHandles.Add(guid, new ManualResetEvent(false)); 130 } 96 database.InsertJob(guid, HeuristicLab.Grid.JobState.Waiting, engine); 97 waitHandles.Add(guid, new ManualResetEvent(false)); 131 98 } 132 99 … … 136 103 137 104 internal byte[] GetResult(Guid guid, int timeout) { 138 lock(bigLock) { 139 // result already available 140 if(results.ContainsKey(guid)) { 141 // if the wait-handle for this result is still alive then close and remove it 142 if(waitHandles.ContainsKey(guid)) { 143 ManualResetEvent waitHandle = waitHandles[guid]; 144 waitHandle.Close(); 145 waitHandles.Remove(guid); 146 } 147 byte[] result = results[guid]; 148 results.Remove(guid); 149 return result; 105 if(JobState(guid) == HeuristicLab.Grid.JobState.Finished) { 106 ManualResetEvent waitHandle = waitHandles[guid]; 107 waitHandle.Close(); 108 waitHandles.Remove(guid); 109 JobEntry entry = database.GetJob(guid); 110 return entry.RawData; 111 } else { 112 // result not yet available, if there is also no wait-handle for that result then we will never have a result and can return null 113 if(!waitHandles.ContainsKey(guid)) return null; 114 // otherwise we have a wait-handle and can wait for the result 115 ManualResetEvent waitHandle = waitHandles[guid]; 116 // wait 117 if(waitHandle.WaitOne(timeout, true)) { 118 // ok got the result in within the wait time => close and remove the wait-hande and return the result 119 waitHandle.Close(); 120 waitHandles.Remove(guid); 121 JobEntry entry = database.GetJob(guid); 122 return entry.RawData; 150 123 } else { 151 // result not yet available, if there is also no wait-handle for that result then we will never have a result and can return null 152 if(!waitHandles.ContainsKey(guid)) return null; 153 // otherwise we have a wait-handle and can wait for the result 154 ManualResetEvent waitHandle = waitHandles[guid]; 155 // wait 156 if(waitHandle.WaitOne(timeout, true)) { 157 // ok got the result in within the wait time => close and remove the wait-hande and return the result 158 waitHandle.Close(); 159 waitHandles.Remove(guid); 160 byte[] result = results[guid]; 161 return result; 162 } else { 163 // no result yet, check for which jobs we waited too long and requeue those jobs 164 List<Guid> expiredJobs = FindExpiredJobs(DateTime.Now.AddDays(-RUNNING_JOB_EXPIRY_TIME_MIN)); 165 foreach(Guid expiredGuid in expiredJobs) { 166 engineList.Insert(0, expiredGuid); 167 waitingEngines[expiredGuid] = runningEngines[expiredGuid]; 168 runningEngines.Remove(expiredGuid); 169 runningEngineDate.Remove(expiredGuid); 170 } 171 return null; 172 } 124 // no result yet, check for which jobs we waited too long and requeue those jobs 125 database.RestartExpiredActiveJobs(); 126 return null; 173 127 } 174 128 } 175 129 } 176 130 177 internal void AbortEngine(Guid guid) {178 throw new NotImplementedException();179 }180 181 131 internal JobState JobState(Guid guid) { 182 lock(bigLock) { 183 if(waitingEngines.ContainsKey(guid)) return HeuristicLab.Grid.JobState.Waiting; 184 else if(waitHandles.ContainsKey(guid)) return HeuristicLab.Grid.JobState.Busy; 185 else if(results.ContainsKey(guid)) return HeuristicLab.Grid.JobState.Finished; 186 else return HeuristicLab.Grid.JobState.Unknown; 187 } 132 return database.GetJob(guid).Status; 188 133 } 189 134 } -
TabularUnified trunk/sources/HeuristicLab.Grid/GridServer.cs ¶
r219 r500 51 51 return engineStore.GetResult(guid, timeout); 52 52 } 53 54 public void AbortEngine(Guid engine) {55 engineStore.AbortEngine(engine);56 }57 53 } 58 54 } -
TabularUnified trunk/sources/HeuristicLab.Grid/HeuristicLab.Grid.csproj ¶
r440 r500 39 39 <RequiredTargetFramework>3.5</RequiredTargetFramework> 40 40 </Reference> 41 <Reference Include="System.Data.SQLite, Version=1.0.51.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139, processorArchitecture=x86"> 42 <SpecificVersion>False</SpecificVersion> 43 <HintPath>..\HeuristicLab.SQLite\System.Data.SQLite.DLL</HintPath> 44 </Reference> 41 45 <Reference Include="System.Drawing" /> 42 46 <Reference Include="System.Runtime.Serialization"> … … 60 64 <DependentUpon>ClientForm.cs</DependentUpon> 61 65 </Compile> 66 <Compile Include="Database.cs" /> 62 67 <Compile Include="EngineRunner.cs" /> 63 68 <Compile Include="EngineStore.cs" /> … … 72 77 <Compile Include="ProcessingEngine.cs" /> 73 78 <Compile Include="Properties\AssemblyInfo.cs" /> 79 <Compile Include="JobEntry.cs" /> 74 80 <Compile Include="ServerForm.cs"> 75 81 <SubType>Form</SubType> -
TabularUnified trunk/sources/HeuristicLab.Grid/IGridServer.cs ¶
r391 r500 44 44 [OperationContract] 45 45 byte[] TryEndExecuteEngine(Guid engineGuid, int timeout); 46 [OperationContract]47 void AbortEngine(Guid engineGuid);48 46 } 49 47 }
Note: See TracChangeset
for help on using the changeset viewer.