Changeset 279
- Timestamp:
- 05/30/08 13:41:27 (16 years ago)
- Location:
- branches/3.0/sources
- Files:
-
- 1 deleted
- 24 edited
- 1 copied
Legend:
- Unmodified
- Added
- Removed
-
branches/3.0/sources/HeuristicLab.Core/PersistenceManager.cs
r151 r279 88 88 public static string BuildTypeString(Type type) { 89 89 string assembly = type.Assembly.FullName; 90 assembly = assembly.S plit(new string[] { ", " }, StringSplitOptions.None)[0];90 assembly = assembly.Substring(0, assembly.IndexOf(", ")); 91 91 92 92 StringBuilder builder = new StringBuilder(); -
branches/3.0/sources/HeuristicLab.DistributedEngine/DistributedEngine.cs
r36 r279 30 30 using System.IO; 31 31 using System.IO.Compression; 32 using HeuristicLab.PluginInfrastructure; 33 using System.Windows.Forms; 34 using System.Diagnostics; 32 35 33 36 namespace HeuristicLab.DistributedEngine { 34 37 public class DistributedEngine : EngineBase, IEditable { 35 private IGridServer server; 36 private Dictionary<Guid, AtomicOperation> engineOperations = new Dictionary<Guid, AtomicOperation>(); 37 private List<Guid> runningEngines = new List<Guid>(); 38 private JobManager jobManager; 39 private CompositeOperation waitingOperations; 38 40 private string serverAddress; 39 private bool cancelRequested;40 private CompositeOperation waitingOperations;41 41 public string ServerAddress { 42 42 get { return serverAddress; } … … 47 47 } 48 48 } 49 public override bool Terminated {50 get {51 return myExecutionStack.Count == 0 && runningEngines.Count == 0 && waitingOperations==null;52 }53 }54 49 public override object Clone(IDictionary<Guid, object> clonedObjects) { 55 50 DistributedEngine clone = (DistributedEngine)base.Clone(clonedObjects); … … 66 61 67 62 public override void Execute() { 68 NetTcpBinding binding = new NetTcpBinding(); 69 binding.MaxReceivedMessageSize = 100000000; // 100Mbytes 70 binding.ReaderQuotas.MaxStringContentLength = 100000000; // also 100M chars 71 binding.ReaderQuotas.MaxArrayLength = 100000000; // also 100M elements; 72 binding.Security.Mode = SecurityMode.None; 73 ChannelFactory<IGridServer> factory = new ChannelFactory<IGridServer>(binding); 74 server = factory.CreateChannel(new EndpointAddress(serverAddress)); 75 63 if(jobManager == null) this.jobManager = new JobManager(serverAddress); 64 jobManager.Reset(); 76 65 base.Execute(); 77 66 } … … 81 70 } 82 71 83 public override void Abort() {84 lock(runningEngines) {85 cancelRequested = true;86 foreach(Guid engineGuid in runningEngines) {87 server.AbortEngine(engineGuid);88 }89 }90 }91 public override void Reset() {92 base.Reset();93 engineOperations.Clear();94 runningEngines.Clear();95 cancelRequested = false;96 }97 98 72 protected override void ProcessNextOperation() { 99 lock(runningEngines) { 100 if(runningEngines.Count == 0 && cancelRequested) { 101 base.Abort(); 102 cancelRequested = false; 103 if(waitingOperations != null && waitingOperations.Operations.Count != 0) { 104 myExecutionStack.Push(waitingOperations); 105 waitingOperations = null; 73 IOperation operation = myExecutionStack.Pop(); 74 if(operation is AtomicOperation) { 75 AtomicOperation atomicOperation = (AtomicOperation)operation; 76 IOperation next = null; 77 try { 78 next = atomicOperation.Operator.Execute(atomicOperation.Scope); 79 } catch(Exception ex) { 80 // push operation on stack again 81 myExecutionStack.Push(atomicOperation); 82 Abort(); 83 ThreadPool.QueueUserWorkItem(delegate(object state) { OnExceptionOccurred(ex); }); 84 } 85 if(next != null) 86 myExecutionStack.Push(next); 87 OnOperationExecuted(atomicOperation); 88 if(atomicOperation.Operator.Breakpoint) Abort(); 89 } else if(operation is CompositeOperation) { 90 CompositeOperation compositeOperation = (CompositeOperation)operation; 91 if(compositeOperation.ExecuteInParallel) { 92 try { 93 WaitHandle[] waithandles = new WaitHandle[compositeOperation.Operations.Count]; 94 int i = 0; 95 // HACK: assume that all atomicOperations have the same parent scope. 96 // 1) find that parent scope 97 // 2) remove all branches starting from the global scope that don't lead to the parentScope of the parallel operation 98 // 3) keep the branches to 'repair' the scope-tree later 99 // 4) for each parallel job attach only the sub-scope that this operation uses 100 // 5) after starting all parallel jobs restore the whole scope-tree 101 IScope parentScope = FindParentScope(GlobalScope, compositeOperation); 102 List<IList<IScope>> prunedScopes = new List<IList<IScope>>(); 103 PruneToParentScope(GlobalScope, parentScope, prunedScopes); 104 List<IScope> subScopes = new List<IScope>(parentScope.SubScopes); 105 foreach(IScope scope in subScopes) { 106 parentScope.RemoveSubScope(scope); 107 } 108 // start all parallel jobs 109 foreach(AtomicOperation parOperation in compositeOperation.Operations) { 110 parentScope.AddSubScope(parOperation.Scope); 111 waithandles[i++] = jobManager.BeginExecuteOperation(GlobalScope, parOperation); 112 parentScope.RemoveSubScope(parOperation.Scope); 113 } 114 foreach(IScope scope in subScopes) { 115 parentScope.AddSubScope(scope); 116 } 117 prunedScopes.Reverse(); 118 RestoreFullTree(GlobalScope, prunedScopes); 119 120 // wait until all jobs are finished 121 // WaitAll works only with maximally 64 waithandles 122 if(waithandles.Length <= 64) { 123 WaitHandle.WaitAll(waithandles); 124 } else { 125 for(i = 0; i < waithandles.Length; i++) { 126 waithandles[i].WaitOne(); 127 waithandles[i].Close(); 128 } 129 } 130 // retrieve results and merge into scope-tree 131 foreach(AtomicOperation parOperation in compositeOperation.Operations) { 132 IScope result = jobManager.EndExecuteOperation(parOperation); 133 MergeScope(parOperation.Scope, result); 134 } 135 } catch(Exception e) { 136 myExecutionStack.Push(compositeOperation); 137 Abort(); 138 ThreadPool.QueueUserWorkItem(delegate(object state) { OnExceptionOccurred(e); }); 106 139 } 107 return; 108 } 109 if(runningEngines.Count != 0) { 110 Guid engineGuid = runningEngines[0]; 111 byte[] resultXml = server.TryEndExecuteEngine(engineGuid, 100); 112 if(resultXml != null) { 113 GZipStream stream = new GZipStream(new MemoryStream(resultXml), CompressionMode.Decompress); 114 ProcessingEngine resultEngine = (ProcessingEngine)PersistenceManager.Load(stream); 115 IScope oldScope = engineOperations[engineGuid].Scope; 116 oldScope.Clear(); 117 foreach(IVariable variable in resultEngine.InitialOperation.Scope.Variables) { 118 oldScope.AddVariable(variable); 119 } 120 foreach(IScope subScope in resultEngine.InitialOperation.Scope.SubScopes) { 121 oldScope.AddSubScope(subScope); 122 } 123 OnOperationExecuted(engineOperations[engineGuid]); 124 125 if(cancelRequested & resultEngine.ExecutionStack.Count != 0) { 126 if(waitingOperations == null) { 127 waitingOperations = new CompositeOperation(); 128 waitingOperations.ExecuteInParallel = false; 129 } 130 CompositeOperation task = new CompositeOperation(); 131 while(resultEngine.ExecutionStack.Count > 0) { 132 AtomicOperation oldOperation = (AtomicOperation)resultEngine.ExecutionStack.Pop(); 133 if(oldOperation.Scope == resultEngine.InitialOperation.Scope) { 134 oldOperation = new AtomicOperation(oldOperation.Operator, oldScope); 135 } 136 task.AddOperation(oldOperation); 137 } 138 waitingOperations.AddOperation(task); 139 } 140 runningEngines.Remove(engineGuid); 141 engineOperations.Remove(engineGuid); 142 } 143 return; 144 } 145 IOperation operation = myExecutionStack.Pop(); 146 if(operation is AtomicOperation) { 147 AtomicOperation atomicOperation = (AtomicOperation)operation; 148 IOperation next = null; 149 try { 150 next = atomicOperation.Operator.Execute(atomicOperation.Scope); 151 } catch(Exception ex) { 152 // push operation on stack again 153 myExecutionStack.Push(atomicOperation); 154 Abort(); 155 ThreadPool.QueueUserWorkItem(delegate(object state) { OnExceptionOccurred(ex); }); 156 } 157 if(next != null) 158 myExecutionStack.Push(next); 159 OnOperationExecuted(atomicOperation); 160 if(atomicOperation.Operator.Breakpoint) Abort(); 161 } else if(operation is CompositeOperation) { 162 CompositeOperation compositeOperation = (CompositeOperation)operation; 163 if(compositeOperation.ExecuteInParallel) { 164 foreach(AtomicOperation parOperation in compositeOperation.Operations) { 165 ProcessingEngine engine = new ProcessingEngine(OperatorGraph, GlobalScope, parOperation); // OperatorGraph not needed? 166 MemoryStream memStream = new MemoryStream(); 167 GZipStream stream = new GZipStream(memStream, CompressionMode.Compress, true); 168 PersistenceManager.Save(engine, stream); 169 stream.Close(); 170 Guid currentEngineGuid = server.BeginExecuteEngine(memStream.ToArray()); 171 runningEngines.Add(currentEngineGuid); 172 engineOperations[currentEngineGuid] = parOperation; 173 } 174 } else { 175 for(int i = compositeOperation.Operations.Count - 1; i >= 0; i--) 176 myExecutionStack.Push(compositeOperation.Operations[i]); 177 } 178 } 140 } else { 141 for(int i = compositeOperation.Operations.Count - 1; i >= 0; i--) 142 myExecutionStack.Push(compositeOperation.Operations[i]); 143 } 144 } 145 } 146 147 private void RestoreFullTree(IScope currentScope, IList<IList<IScope>> savedScopes) { 148 if(savedScopes.Count == 0) return; 149 IScope remainingBranch = currentScope.SubScopes[0]; 150 currentScope.RemoveSubScope(remainingBranch); 151 IList<IScope> savedScopesForCurrent = savedScopes[0]; 152 foreach(IScope savedScope in savedScopesForCurrent) { 153 currentScope.AddSubScope(savedScope); 154 } 155 savedScopes.RemoveAt(0); 156 RestoreFullTree(remainingBranch, savedScopes); 157 } 158 159 private IScope PruneToParentScope(IScope currentScope, IScope scope, IList<IList<IScope>> prunedScopes) { 160 if(currentScope == scope) return currentScope; 161 if(currentScope.SubScopes.Count == 0) return null; 162 IScope foundScope = null; 163 // try to find the searched scope in all my sub-scopes 164 foreach(IScope subScope in currentScope.SubScopes) { 165 foundScope = PruneToParentScope(subScope, scope, prunedScopes); 166 if(foundScope != null) break; // we can stop as soon as we find the scope in a branch 167 } 168 if(foundScope != null) { // when we found the scopes in my sub-scopes 169 List<IScope> subScopes = new List<IScope>(currentScope.SubScopes); // store the list of sub-scopes 170 prunedScopes.Add(subScopes); 171 // remove all my sub-scopes 172 foreach(IScope subScope in subScopes) { 173 currentScope.RemoveSubScope(subScope); 174 } 175 // add only the branch that leads to the scope that I search for 176 currentScope.AddSubScope(foundScope); 177 return currentScope; // return that this scope contains the branch that leads to the searched scopes 178 } else { 179 return null; // otherwise we didn't find the searched scope and we can return null 180 } 181 } 182 183 private IScope FindParentScope(IScope currentScope, CompositeOperation compositeOperation) { 184 AtomicOperation currentOperation = (AtomicOperation)compositeOperation.Operations[0]; 185 if(currentScope.SubScopes.Contains(currentOperation.Scope)) return currentScope; 186 foreach(IScope subScope in currentScope.SubScopes) { 187 IScope result = FindParentScope(subScope, compositeOperation); 188 if(result != null) return result; 189 } 190 return null; 191 } 192 193 private void MergeScope(IScope original, IScope result) { 194 // merge the results 195 original.Clear(); 196 foreach(IVariable variable in result.Variables) { 197 original.AddVariable(variable); 198 } 199 foreach(IScope subScope in result.SubScopes) { 200 original.AddSubScope(subScope); 201 } 202 foreach(KeyValuePair<string, string> alias in result.Aliases) { 203 original.AddAlias(alias.Key, alias.Value); 179 204 } 180 205 } -
branches/3.0/sources/HeuristicLab.DistributedEngine/HeuristicLab.DistributedEngine.csproj
r30 r279 50 50 <ItemGroup> 51 51 <Compile Include="HeuristicLabDistributedEnginePlugin.cs" /> 52 <Compile Include="JobManager.cs" /> 52 53 <Compile Include="Properties\AssemblyInfo.cs" /> 53 54 <Compile Include="DistributedEngine.cs" /> -
branches/3.0/sources/HeuristicLab.DistributedEngine/JobManager.cs
r228 r279 1 using System; 1 #region License Information 2 /* HeuristicLab 3 * Copyright (C) 2002-2008 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 22 using System; 2 23 using System.Collections.Generic; 3 24 using System.Linq; … … 15 36 private IGridServer server; 16 37 private string address; 17 private Dictionary<Guid, AtomicOperation> engineOperations = new Dictionary<Guid, AtomicOperation>(); 18 private Dictionary<Guid, byte[]> runningEngines = new Dictionary<Guid, byte[]>(); 38 private Dictionary<Guid, ProcessingEngine> engines = new Dictionary<Guid, ProcessingEngine>(); 19 39 private Dictionary<Guid, ManualResetEvent> waithandles = new Dictionary<Guid, ManualResetEvent>(); 20 private object locker = new object(); 40 private Dictionary<AtomicOperation, byte[]> results = new Dictionary<AtomicOperation, byte[]>(); 41 private object connectionLock = new object(); 42 private object dictionaryLock = new object(); 43 21 44 private const int MAX_RESTARTS = 5; 22 private Exception exception; 45 private const int MAX_CONNECTION_RETRIES = 10; 46 private const int RETRY_TIMEOUT_SEC = 10; 47 private const int CHECK_RESULTS_TIMEOUT = 10; 48 23 49 private ChannelFactory<IGridServer> factory; 24 public Exception Exception {25 get { return exception; }26 }27 50 28 51 public JobManager(string address) { … … 31 54 32 55 internal void Reset() { 33 lock(locker) {34 ResetConnection();56 ResetConnection(); 57 lock(dictionaryLock) { 35 58 foreach(WaitHandle wh in waithandles.Values) wh.Close(); 36 59 waithandles.Clear(); 37 engineOperations.Clear(); 38 runningEngines.Clear(); 39 exception = null; 60 engines.Clear(); 61 results.Clear(); 40 62 } 41 63 } 42 64 43 65 private void ResetConnection() { 44 // open a new channel 45 NetTcpBinding binding = new NetTcpBinding(); 46 binding.MaxReceivedMessageSize = 100000000; // 100Mbytes 47 binding.ReaderQuotas.MaxStringContentLength = 100000000; // also 100M chars 48 binding.ReaderQuotas.MaxArrayLength = 100000000; // also 100M elements; 49 binding.Security.Mode = SecurityMode.None; 50 factory = new ChannelFactory<IGridServer>(binding); 51 server = factory.CreateChannel(new EndpointAddress(address)); 52 } 53 54 public WaitHandle BeginExecuteOperation(IOperatorGraph operatorGraph, IScope globalScope, AtomicOperation operation) { 55 ProcessingEngine engine = new ProcessingEngine(operatorGraph, globalScope, operation); // OperatorGraph not needed? 66 lock(connectionLock) { 67 // open a new channel 68 NetTcpBinding binding = new NetTcpBinding(); 69 binding.MaxReceivedMessageSize = 100000000; // 100Mbytes 70 binding.ReaderQuotas.MaxStringContentLength = 100000000; // also 100M chars 71 binding.ReaderQuotas.MaxArrayLength = 100000000; // also 100M elements; 72 binding.Security.Mode = SecurityMode.None; 73 74 factory = new ChannelFactory<IGridServer>(binding); 75 server = factory.CreateChannel(new EndpointAddress(address)); 76 } 77 } 78 79 public WaitHandle BeginExecuteOperation(IScope globalScope, AtomicOperation operation) { 80 ProcessingEngine engine = new ProcessingEngine(globalScope, operation); 81 byte[] zippedEngine = ZipEngine(engine); 82 Guid currentEngineGuid = Guid.Empty; 83 bool success = false; 84 int retryCount = 0; 85 do { 86 lock(connectionLock) { 87 try { 88 currentEngineGuid = server.BeginExecuteEngine(zippedEngine); 89 success = true; 90 } catch(TimeoutException timeoutException) { 91 if(retryCount < MAX_CONNECTION_RETRIES) { 92 Thread.Sleep(TimeSpan.FromSeconds(RETRY_TIMEOUT_SEC)); 93 retryCount++; 94 } else { 95 throw new ApplicationException("Max retries reached.", timeoutException); 96 } 97 } catch(CommunicationException communicationException) { 98 ResetConnection(); 99 // wait some time and try again (limit with maximal retries if retry count reached throw exception -> engine can decide to stop execution) 100 if(retryCount < MAX_CONNECTION_RETRIES) { 101 Thread.Sleep(TimeSpan.FromSeconds(RETRY_TIMEOUT_SEC)); 102 retryCount++; 103 } else { 104 throw new ApplicationException("Max retries reached.", communicationException); 105 } 106 } 107 } 108 } while(!success); 109 lock(dictionaryLock) { 110 engines[currentEngineGuid] = engine; 111 waithandles[currentEngineGuid] = new ManualResetEvent(false); 112 } 113 ThreadPool.QueueUserWorkItem(new WaitCallback(TryGetResult), currentEngineGuid); 114 return waithandles[currentEngineGuid]; 115 } 116 117 private byte[] ZipEngine(ProcessingEngine engine) { 56 118 MemoryStream memStream = new MemoryStream(); 57 119 GZipStream stream = new GZipStream(memStream, CompressionMode.Compress, true); 58 120 PersistenceManager.Save(engine, stream); 59 121 stream.Close(); 60 if(factory.State != CommunicationState.Opened) 61 ResetConnection(); 62 Guid currentEngineGuid = server.BeginExecuteEngine(memStream.ToArray()); 63 lock(locker) { 64 runningEngines[currentEngineGuid] = memStream.ToArray(); 65 engineOperations[currentEngineGuid] = operation; 66 waithandles[currentEngineGuid] = new ManualResetEvent(false); 67 ThreadPool.QueueUserWorkItem(new WaitCallback(TryGetResult), currentEngineGuid); 68 } 69 return waithandles[currentEngineGuid]; 122 byte[] zippedEngine = memStream.ToArray(); 123 memStream.Close(); 124 return zippedEngine; 125 } 126 127 public IScope EndExecuteOperation(AtomicOperation operation) { 128 byte[] zippedResult = null; 129 lock(dictionaryLock) { 130 zippedResult = results[operation]; 131 results.Remove(operation); 132 } 133 // restore the engine 134 using(GZipStream stream = new GZipStream(new MemoryStream(zippedResult), CompressionMode.Decompress)) { 135 ProcessingEngine resultEngine = (ProcessingEngine)PersistenceManager.Load(stream); 136 return resultEngine.InitialOperation.Scope; 137 } 70 138 } 71 139 … … 74 142 int restartCounter = 0; 75 143 do { 76 try { 77 if(factory.State != CommunicationState.Opened) ResetConnection(); 78 byte[] resultXml = server.TryEndExecuteEngine(engineGuid, 100); 79 if(resultXml != null) { 80 // restore the engine 81 GZipStream stream = new GZipStream(new MemoryStream(resultXml), CompressionMode.Decompress); 82 ProcessingEngine resultEngine = (ProcessingEngine)PersistenceManager.Load(stream); 83 84 // merge the results 85 IScope oldScope = engineOperations[engineGuid].Scope; 86 oldScope.Clear(); 87 foreach(IVariable variable in resultEngine.InitialOperation.Scope.Variables) { 88 oldScope.AddVariable(variable); 89 } 90 foreach(IScope subScope in resultEngine.InitialOperation.Scope.SubScopes) { 91 oldScope.AddSubScope(subScope); 92 } 93 foreach(KeyValuePair<string, string> alias in resultEngine.InitialOperation.Scope.Aliases) { 94 oldScope.AddAlias(alias.Key, alias.Value); 95 } 96 97 lock(locker) { 98 // signal the wait handle and clean up then return 99 waithandles[engineGuid].Set(); 100 engineOperations.Remove(engineGuid); 101 waithandles.Remove(engineGuid); 102 runningEngines.Remove(engineGuid); 103 } 104 return; 105 } else { 106 // check if the server is still working on the job 107 JobState jobState = server.JobState(engineGuid); 108 if(jobState == JobState.Unkown) { 109 // restart job 110 byte[] packedEngine; 111 lock(locker) { 112 packedEngine = runningEngines[engineGuid]; 144 Thread.Sleep(TimeSpan.FromSeconds(CHECK_RESULTS_TIMEOUT)); 145 byte[] zippedResult = null; 146 lock(connectionLock) { 147 bool success = false; 148 int retries = 0; 149 do { 150 try { 151 zippedResult = server.TryEndExecuteEngine(engineGuid, 100); 152 success = true; 153 } catch(TimeoutException timeoutException) { 154 success = false; 155 retries++; 156 Thread.Sleep(TimeSpan.FromSeconds(RETRY_TIMEOUT_SEC)); 157 } catch(CommunicationException communicationException) { 158 ResetConnection(); 159 success = false; 160 retries++; 161 Thread.Sleep(TimeSpan.FromSeconds(RETRY_TIMEOUT_SEC)); 162 } 163 164 } while(!success && retries < MAX_CONNECTION_RETRIES); 165 } 166 if(zippedResult != null) { 167 lock(dictionaryLock) { 168 // store result 169 results[engines[engineGuid].InitialOperation] = zippedResult; 170 171 // signal the wait handle and clean up then return 172 engines.Remove(engineGuid); 173 waithandles[engineGuid].Set(); 174 waithandles.Remove(engineGuid); 175 } 176 return; 177 } else { 178 // check if the server is still working on the job 179 bool success = false; 180 int retries = 0; 181 JobState jobState = JobState.Unkown; 182 do { 183 try { 184 lock(connectionLock) { 185 jobState = server.JobState(engineGuid); 113 186 } 114 server.BeginExecuteEngine(packedEngine); 115 restartCounter++; 116 } 187 success = true; 188 } catch(TimeoutException timeoutException) { 189 retries++; 190 success = false; 191 Thread.Sleep(TimeSpan.FromSeconds(RETRY_TIMEOUT_SEC)); 192 } catch(CommunicationException communicationException) { 193 ResetConnection(); 194 retries++; 195 success = false; 196 Thread.Sleep(TimeSpan.FromSeconds(RETRY_TIMEOUT_SEC)); 197 } 198 } while(!success && retries < MAX_CONNECTION_RETRIES); 199 if(jobState == JobState.Unkown) { 200 // restart job 201 ProcessingEngine engine; 202 lock(dictionaryLock) { 203 engine = engines[engineGuid]; 204 } 205 byte[] zippedEngine = ZipEngine(engine); 206 success = false; 207 retries = 0; 208 do { 209 try { 210 lock(connectionLock) { 211 server.BeginExecuteEngine(zippedEngine); 212 } 213 success = true; 214 } catch(TimeoutException timeoutException) { 215 success = false; 216 retries++; 217 Thread.Sleep(TimeSpan.FromSeconds(RETRY_TIMEOUT_SEC)); 218 } catch(CommunicationException communicationException) { 219 ResetConnection(); 220 success = false; 221 retries++; 222 Thread.Sleep(TimeSpan.FromSeconds(RETRY_TIMEOUT_SEC)); 223 } 224 } while(!success && retries < MAX_CONNECTION_RETRIES); 225 restartCounter++; 117 226 } 118 } catch(Exception e) {119 // catch all exceptions set an exception flag, signal the wait-handle and exit the routine120 this.exception = new Exception("There was a problem with parallel execution", e);121 waithandles[engineGuid].Set();122 return;123 227 } 124 228 125 229 // when we reach a maximum amount of restarts => signal the wait-handle and set a flag that there was a problem 126 230 if(restartCounter > MAX_RESTARTS) { 127 this.exception = new Exception("Maximal number of parallel job restarts reached"); 128 waithandles[engineGuid].Set(); 129 return; 130 } 131 132 Thread.Sleep(TimeSpan.FromSeconds(10.0)); 231 throw new ApplicationException("Maximum number of job restarts reached."); 232 } 133 233 } while(true); 134 234 } -
branches/3.0/sources/HeuristicLab.Grid/ClientForm.cs
r115 r279 38 38 namespace HeuristicLab.Grid { 39 39 [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode = ConcurrencyMode.Multiple, UseSynchronizationContext = false)] 40 public partial class ClientForm : Form , IClient{40 public partial class ClientForm : Form { 41 41 private ChannelFactory<IEngineStore> factory; 42 private ServiceHost clientHost;43 42 private System.Timers.Timer fetchOperationTimer; 44 43 private IEngineStore engineStore; 45 44 private Guid currentGuid; 46 45 private ProcessingEngine currentEngine; 47 private string clientUrl; 48 private object locker = new object(); 46 private object connectionLock = new object(); 47 private bool stopped; 48 private const int CONNECTION_RETRY_TIMEOUT_SEC = 10; 49 private const int MAX_RETRIES = 10; 49 50 50 51 public ClientForm() { … … 54 55 fetchOperationTimer.Elapsed += new System.Timers.ElapsedEventHandler(fetchOperationTimer_Elapsed); 55 56 statusTextBox.Text = "Stopped"; 57 stopped = true; 56 58 currentGuid = Guid.Empty; 57 59 } 58 60 59 61 private void startButton_Click(object sender, EventArgs e) { 60 string hostname = Dns.GetHostName();61 IPAddress[] addresses = Dns.GetHostAddresses(hostname);62 63 // windows XP returns the external ip on index 0 while windows vista returns the external ip on index 264 if (System.Environment.OSVersion.Version.Major >= 6) {65 clientUrl = "net.tcp://" + Dns.GetHostAddresses(Dns.GetHostName())[2] + ":" + clientPort.Text +"/Grid/Client";66 } else {67 clientUrl = "net.tcp://" + Dns.GetHostAddresses(Dns.GetHostName())[0] + ":" + clientPort.Text +"/Grid/Client";68 }69 70 clientHost = new ServiceHost(this, new Uri(clientUrl));71 62 try { 72 NetTcpBinding binding = new NetTcpBinding(); 73 binding.MaxReceivedMessageSize = 100000000; // 100Mbytes 74 binding.ReaderQuotas.MaxStringContentLength = 100000000; // also 100M chars 75 binding.ReaderQuotas.MaxArrayLength = 100000000; // also 100M elements; 76 binding.Security.Mode = SecurityMode.None; 77 78 clientHost.AddServiceEndpoint(typeof(IClient), binding, clientUrl); 79 clientHost.Open(); 80 81 factory = new ChannelFactory<IEngineStore>(binding); 82 engineStore = factory.CreateChannel(new EndpointAddress(addressTextBox.Text)); 83 63 ResetConnection(); 84 64 fetchOperationTimer.Start(); 85 65 startButton.Enabled = false; 86 66 stopButton.Enabled = true; 87 67 statusTextBox.Text = "Waiting for engine"; 68 stopped = false; 88 69 89 } catch 70 } catch(CommunicationException ex) { 90 71 MessageBox.Show("Exception while connecting to the server: " + ex.Message); 91 clientHost.Abort();92 72 startButton.Enabled = true; 93 73 stopButton.Enabled = false; … … 96 76 } 97 77 78 private void ResetConnection() { 79 NetTcpBinding binding = new NetTcpBinding(); 80 binding.MaxReceivedMessageSize = 100000000; // 100Mbytes 81 binding.ReaderQuotas.MaxStringContentLength = 100000000; // also 100M chars 82 binding.ReaderQuotas.MaxArrayLength = 100000000; // also 100M elements; 83 binding.Security.Mode = SecurityMode.None; 84 factory = new ChannelFactory<IEngineStore>(binding); 85 engineStore = factory.CreateChannel(new EndpointAddress(addressTextBox.Text)); 86 } 87 98 88 private void stopButton_Click(object sender, EventArgs e) { 89 stopped = true; 99 90 fetchOperationTimer.Stop(); 100 factory.Abort(); 101 clientHost.Close(); 91 if(currentEngine != null) 92 currentEngine.Abort(); 93 lock(connectionLock) { 94 if(factory.State == CommunicationState.Opened || factory.State == CommunicationState.Opening) { 95 IAsyncResult closeResult = factory.BeginClose(null, null); 96 factory.EndClose(closeResult); 97 } 98 } 102 99 statusTextBox.Text = "Stopped"; 103 100 stopButton.Enabled = false; … … 106 103 107 104 private void fetchOperationTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) { 108 lock(locker) { 109 byte[] engineXml; 110 fetchOperationTimer.Stop(); 111 if(engineStore.TryTakeEngine(clientUrl, out currentGuid, out engineXml)) { 112 currentEngine = RestoreEngine(engineXml); 113 if(InvokeRequired) { Invoke((MethodInvoker)delegate() { statusTextBox.Text = "Executing engine"; }); } else statusTextBox.Text = "Executing engine"; 114 currentEngine.Finished += delegate(object src, EventArgs args) { 115 byte[] resultXml = SaveEngine(currentEngine); 116 engineStore.StoreResult(currentGuid, resultXml); 117 currentGuid = Guid.Empty; 118 currentEngine = null; 119 fetchOperationTimer.Interval = 100; 120 fetchOperationTimer.Start(); 121 }; 122 currentEngine.Execute(); 123 } else { 105 byte[] engineXml = null; 106 // first stop the timer! 107 fetchOperationTimer.Stop(); 108 bool gotEngine = false; 109 lock(connectionLock) { 110 if(stopped) return; 111 try { 112 gotEngine = engineStore.TryTakeEngine(out currentGuid, out engineXml); 113 } catch(TimeoutException timeoutException) { 114 currentEngine = null; 115 currentGuid = Guid.Empty; 116 // timeout -> just start the timer again 117 fetchOperationTimer.Interval = 5000; 118 fetchOperationTimer.Start(); 119 } catch(CommunicationException communicationException) { 120 // connection problem -> reset connection and start the timer again 121 ResetConnection(); 122 currentEngine = null; 123 currentGuid = Guid.Empty; 124 fetchOperationTimer.Interval = 5000; 125 fetchOperationTimer.Start(); 126 } 127 } 128 // got engine from server and user didn't press stop -> execute the engine 129 if(gotEngine && !stopped) { 130 currentEngine = RestoreEngine(engineXml); 131 if(InvokeRequired) { Invoke((MethodInvoker)delegate() { statusTextBox.Text = "Executing engine"; }); } else statusTextBox.Text = "Executing engine"; 132 currentEngine.Finished += new EventHandler(currentEngine_Finished); // register event-handler that sends result back to server and restarts timer 133 currentEngine.Execute(); 134 } else { 135 // ok we didn't get engine -> if the user didn't press stop this means that the server doesn't have engines for us 136 // if the user pressed stop we must not start the timer 137 if(!stopped) { 124 138 if(InvokeRequired) { Invoke((MethodInvoker)delegate() { statusTextBox.Text = "Waiting for engine"; }); } else statusTextBox.Text = "Waiting for engine"; 139 // start the timer again 125 140 fetchOperationTimer.Interval = 5000; 126 141 fetchOperationTimer.Start(); … … 128 143 } 129 144 } 130 public void Abort(Guid guid) { 131 lock(locker) { 132 if(!IsRunningEngine(guid)) return; 133 currentEngine.Abort(); 134 } 145 146 void currentEngine_Finished(object sender, EventArgs e) { 147 IEngine engine = (IEngine)sender; 148 byte[] resultXml = SaveEngine(engine); 149 bool success = false; 150 int retries = 0; 151 do { 152 lock(connectionLock) { 153 if(!stopped) { 154 try { 155 engineStore.StoreResult(currentGuid, resultXml); 156 success = true; 157 } catch(TimeoutException timeoutException) { 158 success = false; 159 retries++; 160 Thread.Sleep(TimeSpan.FromSeconds(CONNECTION_RETRY_TIMEOUT_SEC)); 161 } catch(CommunicationException communicationException) { 162 ResetConnection(); 163 success = false; 164 retries++; 165 Thread.Sleep(TimeSpan.FromSeconds(CONNECTION_RETRY_TIMEOUT_SEC)); 166 } 167 } 168 } 169 } while(!stopped && !success && retries < MAX_RETRIES); 170 // ok if we could store the result it's probable that the server can send us another engine use a small time-interval 171 if(success) 172 fetchOperationTimer.Interval = 100; 173 else fetchOperationTimer.Interval = CONNECTION_RETRY_TIMEOUT_SEC; // if there were problems -> sleep for a longer time 174 // clear state 175 currentEngine = null; 176 currentGuid = Guid.Empty; 177 // start the timer 178 fetchOperationTimer.Start(); 135 179 } 136 public bool IsRunningEngine(Guid guid) { 137 return currentGuid == guid; 138 } 180 139 181 private ProcessingEngine RestoreEngine(byte[] engine) { 140 182 GZipStream stream = new GZipStream(new MemoryStream(engine), CompressionMode.Decompress); -
branches/3.0/sources/HeuristicLab.Grid/EngineStore.cs
r35 r279 34 34 private Dictionary<Guid, ManualResetEvent> waitHandles; 35 35 private Dictionary<Guid, byte[]> results; 36 private Dictionary<Guid, string> runningClients; 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; 37 40 private object bigLock; 38 private ChannelFactory<IClient> clientChannelFactory;39 41 public int WaitingJobs { 40 42 get { … … 59 61 waitingEngines = new Dictionary<Guid, byte[]>(); 60 62 runningEngines = new Dictionary<Guid, byte[]>(); 61 runningClients = new Dictionary<Guid, string>();62 63 waitHandles = new Dictionary<Guid, ManualResetEvent>(); 63 64 results = new Dictionary<Guid, byte[]>(); 65 resultDate = new Dictionary<Guid, DateTime>(); 66 runningEngineDate = new Dictionary<Guid, DateTime>(); 64 67 bigLock = new object(); 65 66 NetTcpBinding binding = new NetTcpBinding();67 binding.MaxReceivedMessageSize = 100000000; // 100Mbytes68 binding.ReaderQuotas.MaxStringContentLength = 100000000; // also 100M chars69 binding.ReaderQuotas.MaxArrayLength = 100000000; // also 100M elements;70 binding.Security.Mode = SecurityMode.None;71 72 clientChannelFactory = new ChannelFactory<IClient>(binding);73 68 } 74 69 75 public bool TryTakeEngine( string clientUrl,out Guid guid, out byte[] engine) {70 public bool TryTakeEngine(out Guid guid, out byte[] engine) { 76 71 lock(bigLock) { 77 72 if(engineList.Count == 0) { … … 85 80 waitingEngines.Remove(guid); 86 81 runningEngines[guid] = engine; 87 running Clients[guid] = clientUrl;82 runningEngineDate[guid] = DateTime.Now; 88 83 return true; 89 84 } … … 93 88 public void StoreResult(Guid guid, byte[] result) { 94 89 lock(bigLock) { 95 if(!runningEngines.ContainsKey(guid)) return; // ignore result when the engine is not known to be running 96 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 97 98 runningEngines.Remove(guid); 98 running Clients.Remove(guid);99 runningEngineDate.Remove(guid); 99 100 results[guid] = result; 101 resultDate[guid] = DateTime.Now; 100 102 waitHandles[guid].Set(); 101 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; 102 123 } 103 124 … … 113 134 return GetResult(guid, System.Threading.Timeout.Infinite); 114 135 } 136 115 137 internal byte[] GetResult(Guid guid, int timeout) { 116 138 lock(bigLock) { 117 if(waitHandles.ContainsKey(guid)) { 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; 150 } 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 118 154 ManualResetEvent waitHandle = waitHandles[guid]; 155 // wait 119 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 120 158 waitHandle.Close(); 121 159 waitHandles.Remove(guid); 122 160 byte[] result = results[guid]; 123 results.Remove(guid);124 161 return result; 125 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.AddMinutes(-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 } 126 171 return null; 127 172 } 128 } else {129 return null;130 173 } 131 174 } … … 133 176 134 177 internal void AbortEngine(Guid guid) { 135 string clientUrl = ""; 178 throw new NotImplementedException(); 179 } 180 181 internal JobState JobState(Guid guid) { 136 182 lock(bigLock) { 137 if(runningClients.ContainsKey(guid)) { 138 clientUrl = runningClients[guid]; 139 IClient client = clientChannelFactory.CreateChannel(new EndpointAddress(clientUrl)); 140 client.Abort(guid); 141 } else if(waitingEngines.ContainsKey(guid)) { 142 byte[] engine = waitingEngines[guid]; 143 waitingEngines.Remove(guid); 144 engineList.Remove(guid); 145 waitHandles[guid].Set(); 146 results.Add(guid, engine); 147 } 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.Unkown; 148 187 } 149 188 } -
branches/3.0/sources/HeuristicLab.Grid/GridClientApplication.cs
r2 r279 27 27 28 28 namespace HeuristicLab.Grid { 29 [ClassInfo(Name = "Grid Client", Description="Client application for the distributed engine grid." )]29 [ClassInfo(Name = "Grid Client", Description="Client application for the distributed engine grid.", AutoRestart = true)] 30 30 class GridClientApplication : ApplicationBase { 31 31 public override void Run() { -
branches/3.0/sources/HeuristicLab.Grid/GridServer.cs
r33 r279 35 35 } 36 36 37 public JobState JobState(Guid guid) { 38 return engineStore.JobState(guid); 39 } 40 37 41 public Guid BeginExecuteEngine(byte[] engine) { 38 42 Guid guid = Guid.NewGuid(); -
branches/3.0/sources/HeuristicLab.Grid/GridServerApplication.cs
r2 r279 27 27 28 28 namespace HeuristicLab.Grid { 29 [ClassInfo(Name = "Grid Server", Description ="Server application for the distributed engine grid.")]29 [ClassInfo(Name = "Grid Server", Description = "Server application for the distributed engine grid.", AutoRestart=true)] 30 30 class GridServerApplication : ApplicationBase { 31 31 public override void Run() { -
branches/3.0/sources/HeuristicLab.Grid/HeuristicLab.Grid.csproj
r32 r279 63 63 <Compile Include="GridServerApplication.cs" /> 64 64 <Compile Include="HeuristicLabGridPlugin.cs" /> 65 <Compile Include="IClient.cs" />66 65 <Compile Include="IEngineStore.cs" /> 67 66 <Compile Include="IGridServer.cs" /> -
branches/3.0/sources/HeuristicLab.Grid/IEngineStore.cs
r32 r279 30 30 interface IEngineStore { 31 31 [OperationContract] 32 bool TryTakeEngine( string clientUrl,out Guid guid, out byte[] engine);32 bool TryTakeEngine(out Guid guid, out byte[] engine); 33 33 34 34 [OperationContract] -
branches/3.0/sources/HeuristicLab.Grid/IGridServer.cs
r33 r279 26 26 27 27 namespace HeuristicLab.Grid { 28 public enum JobState { 29 Unkown, 30 Waiting, 31 Busy, 32 Finished 33 } 34 35 28 36 [ServiceContract(Namespace = "http://HeuristicLab.Grid")] 29 37 public interface IGridServer { 38 [OperationContract] 39 JobState JobState(Guid guid); 30 40 [OperationContract] 31 41 Guid BeginExecuteEngine(byte[] engine); -
branches/3.0/sources/HeuristicLab.Grid/ProcessingEngine.cs
r27 r279 39 39 } 40 40 41 public ProcessingEngine(I OperatorGraph graph, IScope globalScope, AtomicOperation initialOperation)41 public ProcessingEngine(IScope globalScope, AtomicOperation initialOperation) 42 42 : base() { 43 43 this.initialOperation = initialOperation; 44 44 myGlobalScope = globalScope; 45 myOperatorGraph = graph;46 45 myExecutionStack.Push(initialOperation); 47 46 } … … 68 67 myExecutionStack.Push(atomicOperation); 69 68 Abort(); 70 ThreadPool.QueueUserWorkItem(delegate(object state) { OnExceptionOccurred(ex); });71 69 } 72 70 if(next != null) 73 71 myExecutionStack.Push(next); 74 OnOperationExecuted(atomicOperation);75 72 if(atomicOperation.Operator.Breakpoint) Abort(); 76 73 } else if(operation is CompositeOperation) { -
branches/3.0/sources/HeuristicLab.Grid/ServerForm.cs
r115 r279 52 52 internalAddressTextBox.Text = "net.tcp://" + Dns.GetHostAddresses(Dns.GetHostName())[0] + ":8001/Grid/JobStore"; 53 53 } 54 55 54 jobStore = new EngineStore(); 56 55 server = new GridServer(jobStore); 57 56 Start(); 58 57 } 59 58 60 private void startButton_Click(object sender, EventArgs e) {59 private void Start() { 61 60 externalHost = new ServiceHost(server, new Uri(externalAddressTextBox.Text)); 62 61 internalHost = new ServiceHost(jobStore, new Uri(internalAddressTextBox.Text)); 62 ServiceThrottlingBehavior throttlingBehavior = new ServiceThrottlingBehavior(); 63 throttlingBehavior.MaxConcurrentSessions = 20; 64 internalHost.Description.Behaviors.Add(throttlingBehavior); 63 65 try { 64 66 NetTcpBinding binding = new NetTcpBinding(); … … 67 69 binding.ReaderQuotas.MaxArrayLength = 100000000; // also 100M elements; 68 70 binding.Security.Mode = SecurityMode.None; 71 69 72 70 73 externalHost.AddServiceEndpoint(typeof(IGridServer), binding, externalAddressTextBox.Text); … … 73 76 internalHost.AddServiceEndpoint(typeof(IEngineStore), binding, internalAddressTextBox.Text); 74 77 internalHost.Open(); 75 76 startButton.Enabled = false;77 stopButton.Enabled = true;78 78 } catch (CommunicationException ex) { 79 79 MessageBox.Show("An exception occurred: " + ex.Message); … … 82 82 } 83 83 } 84 85 private void stopButton_Click(object sender, EventArgs e) {86 externalHost.Close();87 internalHost.Close();88 stopButton.Enabled = false;89 startButton.Enabled = true;90 }91 92 84 private void statusUpdateTimer_Tick(object sender, EventArgs e) { 93 85 waitingJobsTextBox.Text = jobStore.WaitingJobs+""; -
branches/3.0/sources/HeuristicLab.Grid/ServerForm.designer.cs
r2 r279 47 47 this.components = new System.ComponentModel.Container(); 48 48 this.externalAddressTextBox = new System.Windows.Forms.TextBox(); 49 this.startButton = new System.Windows.Forms.Button();50 this.stopButton = new System.Windows.Forms.Button();51 49 this.externalAddressLabel = new System.Windows.Forms.Label(); 52 50 this.internalAddressLabel = new System.Windows.Forms.Label(); … … 68 66 this.externalAddressTextBox.Size = new System.Drawing.Size(229, 20); 69 67 this.externalAddressTextBox.TabIndex = 0; 70 //71 // startButton72 //73 this.startButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));74 this.startButton.Location = new System.Drawing.Point(12, 160);75 this.startButton.Name = "startButton";76 this.startButton.Size = new System.Drawing.Size(75, 23);77 this.startButton.TabIndex = 1;78 this.startButton.Text = "St&art";79 this.startButton.UseVisualStyleBackColor = true;80 this.startButton.Click += new System.EventHandler(this.startButton_Click);81 //82 // stopButton83 //84 this.stopButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));85 this.stopButton.Enabled = false;86 this.stopButton.Location = new System.Drawing.Point(99, 160);87 this.stopButton.Name = "stopButton";88 this.stopButton.Size = new System.Drawing.Size(75, 23);89 this.stopButton.TabIndex = 2;90 this.stopButton.Text = "St&op";91 this.stopButton.UseVisualStyleBackColor = true;92 this.stopButton.Click += new System.EventHandler(this.stopButton_Click);93 68 // 94 69 // externalAddressLabel … … 185 160 this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); 186 161 this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 187 this.ClientSize = new System.Drawing.Size(347, 1 95);162 this.ClientSize = new System.Drawing.Size(347, 150); 188 163 this.Controls.Add(this.waitingResultsLabel); 189 164 this.Controls.Add(this.waitingResultsTextBox); … … 195 170 this.Controls.Add(this.internalAddressTextBox); 196 171 this.Controls.Add(this.externalAddressLabel); 197 this.Controls.Add(this.stopButton);198 this.Controls.Add(this.startButton);199 172 this.Controls.Add(this.externalAddressTextBox); 200 173 this.Name = "ServerForm"; … … 208 181 209 182 private System.Windows.Forms.TextBox externalAddressTextBox; 210 private System.Windows.Forms.Button startButton;211 private System.Windows.Forms.Button stopButton;212 183 private System.Windows.Forms.Label externalAddressLabel; 213 184 private System.Windows.Forms.Label internalAddressLabel; -
branches/3.0/sources/HeuristicLab.PluginInfrastructure/ApplicationInfo.cs
r2 r279 46 46 } 47 47 48 private bool autoRestart; 49 public bool AutoRestart { 50 get { return autoRestart; } 51 set { autoRestart = value; } 52 } 53 48 54 private string pluginAssembly; 49 55 /// <summary> 50 56 /// Name of the assembly that contains the IApplication type. 51 /// NEEDED?52 57 /// </summary> 53 58 public string PluginAssembly { … … 59 64 /// <summary> 60 65 /// Name of the type that implements the interface IApplication. 61 /// NEEDED?62 66 /// </summary> 63 67 public string PluginType { -
branches/3.0/sources/HeuristicLab.PluginInfrastructure/BaseClasses/ApplicationBase.cs
r8 r279 30 30 private Version version; 31 31 private string description; 32 32 private bool autoRestart; 33 33 34 public ApplicationBase() { 34 35 ReadAttributes(); … … 45 46 // after the assertion we are sure that the array access will not fail 46 47 ClassInfoAttribute pluginAttribute = (ClassInfoAttribute)pluginAttributes[0]; 48 if(pluginAttribute != null) { 49 // if the plugin name is not explicitly set in the attribute then the default plugin name is the FullName of the type 50 if(pluginAttribute.Name != null) { 51 this.name = pluginAttribute.Name; 52 } else { 53 this.name = this.GetType().FullName; 54 } 47 55 48 // if the plugin name is not explicitly set in the attribute then the default plugin name is the FullName of the type49 if(pluginAttribute != null && pluginAttribute.Name!= null) {50 this.name = pluginAttribute.Name;51 } else {52 this.name = this.GetType().FullName;53 }56 // if the version is not explicitly set in the attribute then the version of the assembly is used as default 57 if(pluginAttribute.Version != null) { 58 this.version = new Version(pluginAttribute.Version); 59 } else { 60 this.version = this.GetType().Assembly.GetName().Version; 61 } 54 62 55 // if the version is not explicitly set in the attribute then the version of the assemblyis used as default56 if(pluginAttribute != null && pluginAttribute.Version != null) {57 this.version = new Version(pluginAttribute.Version);58 } else {59 this.version = this.GetType().Assembly.GetName().Version;60 }63 // if the description is not explicitly set in the attribute then the name of name of the application is used as default 64 if(pluginAttribute.Description != null) { 65 this.description = pluginAttribute.Description; 66 } else { 67 this.description = name; 68 } 61 69 62 // if the description is not explicitly set in the attribute then the name of name of the application is used as default 63 if(pluginAttribute != null && pluginAttribute.Description != null) { 64 this.description = pluginAttribute.Description; 65 } else { 66 this.description = name; 70 this.autoRestart = pluginAttribute.AutoRestart; 67 71 } 68 72 } … … 83 87 } 84 88 85 public abstract void Run() ; 89 public bool AutoRestart { 90 get { return autoRestart; } 91 } 92 93 public abstract void Run(); 86 94 87 95 #endregion -
branches/3.0/sources/HeuristicLab.PluginInfrastructure/ClassInfoAttribute.cs
r91 r279 52 52 } 53 53 54 private bool autoRestart; 55 public bool AutoRestart { 56 get { return autoRestart; } 57 set { autoRestart = value; } 58 } 59 54 60 public ClassInfoAttribute() {} 55 61 } -
branches/3.0/sources/HeuristicLab.PluginInfrastructure/Interfaces/IApplication.cs
r2 r279 29 29 Version Version { get; } 30 30 string Description { get;} 31 bool AutoRestart { get; } 31 32 void Run(); 32 33 } -
branches/3.0/sources/HeuristicLab.PluginInfrastructure/Loader.cs
r91 r279 120 120 info.Version = application.Version; 121 121 info.Description = application.Description; 122 info.AutoRestart = application.AutoRestart; 122 123 info.PluginAssembly = application.GetType().Assembly.GetName().Name; 123 124 info.PluginType = application.GetType().Namespace + "." + application.GetType().Name; -
branches/3.0/sources/HeuristicLab.PluginInfrastructure/PluginManager.cs
r29 r279 103 103 setup.PrivateBinPath = pluginDir; 104 104 AppDomain applicationDomain = AppDomain.CreateDomain(appInfo.Name + " AppDomain", null, setup); 105 106 Runner remoteRunner = (Runner)applicationDomain.CreateInstanceAndUnwrap("HeuristicLab.PluginInfrastructure", "HeuristicLab.PluginInfrastructure.Runner"); 107 NotifyListeners(PluginManagerAction.Initializing, "All plugins"); 108 remoteRunner.LoadPlugins(remoteLoader.ActivePlugins); 109 NotifyListeners(PluginManagerAction.Initialized, "All plugins"); 110 remoteRunner.Run(appInfo); 111 112 AppDomain.Unload(applicationDomain); 105 try { 106 Runner remoteRunner = (Runner)applicationDomain.CreateInstanceAndUnwrap("HeuristicLab.PluginInfrastructure", "HeuristicLab.PluginInfrastructure.Runner"); 107 NotifyListeners(PluginManagerAction.Initializing, "All plugins"); 108 remoteRunner.LoadPlugins(remoteLoader.ActivePlugins); 109 NotifyListeners(PluginManagerAction.Initialized, "All plugins"); 110 remoteRunner.Run(appInfo); 111 } catch(Exception ex) { 112 // can't handle exception here -> rethrow 113 throw new ApplicationException("Exception in "+appInfo.Name, ex); 114 } finally { 115 // make sure domain is unloaded in all cases 116 AppDomain.Unload(applicationDomain); 117 } 113 118 } 114 119 -
branches/3.0/sources/HeuristicLab.Scheduling.JSSP/HeuristicLab.Scheduling.JSSP.csproj
r30 r279 37 37 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> 38 38 <DebugSymbols>true</DebugSymbols> 39 <DebugType> full</DebugType>39 <DebugType>pdbonly</DebugType> 40 40 <Optimize>false</Optimize> 41 41 <OutputPath>bin\Debug\</OutputPath> -
branches/3.0/sources/HeuristicLab.Scheduling.JSSP/HeuristicLabJSSPPlugin.cs
r2 r279 32 32 [Dependency(Dependency = "HeuristicLab.Operators")] 33 33 [Dependency(Dependency = "HeuristicLab.Permutation")] 34 public class HeuristicLab RoutingTSPPlugin : PluginBase {34 public class HeuristicLabSchedulingJSPPlugin : PluginBase { 35 35 } 36 36 } -
branches/3.0/sources/HeuristicLab.Scheduling.JSSP/OperationUpdater.cs
r2 r279 52 52 op.Predecessors.RemoveAt(index); // remove scheduled op from predecessor list 53 53 op.Start = scheduledOp.Start + scheduledOp.Duration; // new earliest start date 54 return null;55 54 } 56 55 } -
branches/3.0/sources/HeuristicLab/MainForm.cs
r278 r279 94 94 PluginManager.Manager.Action += new PluginManagerActionEventHandler(splashScreen.Manager_Action); 95 95 Thread t = new Thread(delegate() { 96 PluginManager.Manager.Run(app); 96 bool stopped = false; 97 do { 98 try { 99 PluginManager.Manager.Run(app); 100 stopped = true; 101 } catch(Exception ex) { 102 stopped = false; 103 ThreadPool.QueueUserWorkItem(delegate(object exception) { ShowErrorMessageBox((Exception)exception); }, ex); 104 Thread.Sleep(5000); // sleep 5 seconds before autorestart 105 } 106 } while(!stopped && app.AutoRestart); 97 107 }); 98 108 t.SetApartmentState(ApartmentState.STA); // needed for the AdvancedOptimizationFrontent … … 122 132 } 123 133 134 public void ShowErrorMessageBox(Exception ex) { 135 MessageBox.Show(BuildErrorMessage(ex), 136 "Error - " + ex.GetType().Name, 137 MessageBoxButtons.OK, 138 MessageBoxIcon.Error); 139 } 140 private string BuildErrorMessage(Exception ex) { 141 StringBuilder sb = new StringBuilder(); 142 sb.Append("Sorry, but something went wrong!\n\n" + ex.Message + "\n\n" + ex.StackTrace); 143 144 while(ex.InnerException != null) { 145 ex = ex.InnerException; 146 sb.Append("\n\n-----\n\n" + ex.Message + "\n\n" + ex.StackTrace); 147 } 148 return sb.ToString(); 149 } 124 150 } 125 151 }
Note: See TracChangeset
for help on using the changeset viewer.