Free cookie consent management tool by TermsFeed Policy Generator

Changeset 279


Ignore:
Timestamp:
05/30/08 13:41:27 (16 years ago)
Author:
gkronber
Message:

merged changesets r219:r228, r240, r241:258, r263:265, r267,r268, r269 from trunk into the HL3 stable branch

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  
    8888    public static string BuildTypeString(Type type) {
    8989      string assembly = type.Assembly.FullName;
    90       assembly = assembly.Split(new string[] { ", " }, StringSplitOptions.None)[0];
     90      assembly = assembly.Substring(0, assembly.IndexOf(", "));
    9191
    9292      StringBuilder builder = new StringBuilder();
  • branches/3.0/sources/HeuristicLab.DistributedEngine/DistributedEngine.cs

    r36 r279  
    3030using System.IO;
    3131using System.IO.Compression;
     32using HeuristicLab.PluginInfrastructure;
     33using System.Windows.Forms;
     34using System.Diagnostics;
    3235
    3336namespace HeuristicLab.DistributedEngine {
    3437  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;
    3840    private string serverAddress;
    39     private bool cancelRequested;
    40     private CompositeOperation waitingOperations;
    4141    public string ServerAddress {
    4242      get { return serverAddress; }
     
    4747      }
    4848    }
    49     public override bool Terminated {
    50       get {
    51         return myExecutionStack.Count == 0 && runningEngines.Count == 0 && waitingOperations==null;
    52       }
    53     }
    5449    public override object Clone(IDictionary<Guid, object> clonedObjects) {
    5550      DistributedEngine clone = (DistributedEngine)base.Clone(clonedObjects);
     
    6661
    6762    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();
    7665      base.Execute();
    7766    }
     
    8170    }
    8271
    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 
    9872    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); });
    106139          }
    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);
    179204      }
    180205    }
  • branches/3.0/sources/HeuristicLab.DistributedEngine/HeuristicLab.DistributedEngine.csproj

    r30 r279  
    5050  <ItemGroup>
    5151    <Compile Include="HeuristicLabDistributedEnginePlugin.cs" />
     52    <Compile Include="JobManager.cs" />
    5253    <Compile Include="Properties\AssemblyInfo.cs" />
    5354    <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
     22using System;
    223using System.Collections.Generic;
    324using System.Linq;
     
    1536    private IGridServer server;
    1637    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>();
    1939    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
    2144    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
    2349    private ChannelFactory<IGridServer> factory;
    24     public Exception Exception {
    25       get { return exception; }
    26     }
    2750
    2851    public JobManager(string address) {
     
    3154
    3255    internal void Reset() {
    33       lock(locker) {
    34         ResetConnection();
     56      ResetConnection();
     57      lock(dictionaryLock) {
    3558        foreach(WaitHandle wh in waithandles.Values) wh.Close();
    3659        waithandles.Clear();
    37         engineOperations.Clear();
    38         runningEngines.Clear();
    39         exception = null;
     60        engines.Clear();
     61        results.Clear();
    4062      }
    4163    }
    4264
    4365    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) {
    56118      MemoryStream memStream = new MemoryStream();
    57119      GZipStream stream = new GZipStream(memStream, CompressionMode.Compress, true);
    58120      PersistenceManager.Save(engine, stream);
    59121      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      }     
    70138    }
    71139
     
    74142      int restartCounter = 0;
    75143      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);
    113186              }
    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++;
    117226          }
    118         } catch(Exception e) {
    119           // catch all exceptions set an exception flag, signal the wait-handle and exit the routine
    120           this.exception = new Exception("There was a problem with parallel execution", e);
    121           waithandles[engineGuid].Set();
    122           return;
    123227        }
    124228
    125229        // when we reach a maximum amount of restarts => signal the wait-handle and set a flag that there was a problem
    126230        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        }
    133233      } while(true);
    134234    }
  • branches/3.0/sources/HeuristicLab.Grid/ClientForm.cs

    r115 r279  
    3838namespace HeuristicLab.Grid {
    3939  [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode = ConcurrencyMode.Multiple, UseSynchronizationContext = false)]
    40   public partial class ClientForm : Form, IClient {
     40  public partial class ClientForm : Form {
    4141    private ChannelFactory<IEngineStore> factory;
    42     private ServiceHost clientHost;
    4342    private System.Timers.Timer fetchOperationTimer;
    4443    private IEngineStore engineStore;
    4544    private Guid currentGuid;
    4645    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;
    4950
    5051    public ClientForm() {
     
    5455      fetchOperationTimer.Elapsed += new System.Timers.ElapsedEventHandler(fetchOperationTimer_Elapsed);
    5556      statusTextBox.Text = "Stopped";
     57      stopped = true;
    5658      currentGuid = Guid.Empty;
    5759    }
    5860
    5961    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 2
    64       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));
    7162      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();
    8464        fetchOperationTimer.Start();
    8565        startButton.Enabled = false;
    8666        stopButton.Enabled = true;
    8767        statusTextBox.Text = "Waiting for engine";
     68        stopped = false;
    8869
    89       } catch (CommunicationException ex) {
     70      } catch(CommunicationException ex) {
    9071        MessageBox.Show("Exception while connecting to the server: " + ex.Message);
    91         clientHost.Abort();
    9272        startButton.Enabled = true;
    9373        stopButton.Enabled = false;
     
    9676    }
    9777
     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
    9888    private void stopButton_Click(object sender, EventArgs e) {
     89      stopped = true;
    9990      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      }
    10299      statusTextBox.Text = "Stopped";
    103100      stopButton.Enabled = false;
     
    106103
    107104    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) {
    124138          if(InvokeRequired) { Invoke((MethodInvoker)delegate() { statusTextBox.Text = "Waiting for engine"; }); } else statusTextBox.Text = "Waiting for engine";
     139          // start the timer again
    125140          fetchOperationTimer.Interval = 5000;
    126141          fetchOperationTimer.Start();
     
    128143      }
    129144    }
    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();
    135179    }
    136     public bool IsRunningEngine(Guid guid) {
    137       return currentGuid == guid;
    138     }
     180
    139181    private ProcessingEngine RestoreEngine(byte[] engine) {
    140182      GZipStream stream = new GZipStream(new MemoryStream(engine), CompressionMode.Decompress);
  • branches/3.0/sources/HeuristicLab.Grid/EngineStore.cs

    r35 r279  
    3434    private Dictionary<Guid, ManualResetEvent> waitHandles;
    3535    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;
    3740    private object bigLock;
    38     private ChannelFactory<IClient> clientChannelFactory;
    3941    public int WaitingJobs {
    4042      get {
     
    5961      waitingEngines = new Dictionary<Guid, byte[]>();
    6062      runningEngines = new Dictionary<Guid, byte[]>();
    61       runningClients = new Dictionary<Guid, string>();
    6263      waitHandles = new Dictionary<Guid, ManualResetEvent>();
    6364      results = new Dictionary<Guid, byte[]>();
     65      resultDate = new Dictionary<Guid, DateTime>();
     66      runningEngineDate = new Dictionary<Guid, DateTime>();
    6467      bigLock = new object();
    65 
    66       NetTcpBinding binding = new NetTcpBinding();
    67       binding.MaxReceivedMessageSize = 100000000; // 100Mbytes
    68       binding.ReaderQuotas.MaxStringContentLength = 100000000; // also 100M chars
    69       binding.ReaderQuotas.MaxArrayLength = 100000000; // also 100M elements;
    70       binding.Security.Mode = SecurityMode.None;
    71 
    72       clientChannelFactory = new ChannelFactory<IClient>(binding);
    7368    }
    7469
    75     public bool TryTakeEngine(string clientUrl, out Guid guid, out byte[] engine) {
     70    public bool TryTakeEngine(out Guid guid, out byte[] engine) {
    7671      lock(bigLock) {
    7772        if(engineList.Count == 0) {
     
    8580          waitingEngines.Remove(guid);
    8681          runningEngines[guid] = engine;
    87           runningClients[guid] = clientUrl;
     82          runningEngineDate[guid] = DateTime.Now;
    8883          return true;
    8984        }
     
    9388    public void StoreResult(Guid guid, byte[] result) {
    9489      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
    9798        runningEngines.Remove(guid);
    98         runningClients.Remove(guid);
     99        runningEngineDate.Remove(guid);
    99100        results[guid] = result;
     101        resultDate[guid] = DateTime.Now;
    100102        waitHandles[guid].Set();
    101103      }
     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;
    102123    }
    103124
     
    113134      return GetResult(guid, System.Threading.Timeout.Infinite);
    114135    }
     136
    115137    internal byte[] GetResult(Guid guid, int timeout) {
    116138      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
    118154          ManualResetEvent waitHandle = waitHandles[guid];
     155          // wait
    119156          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
    120158            waitHandle.Close();
    121159            waitHandles.Remove(guid);
    122160            byte[] result = results[guid];
    123             results.Remove(guid);
    124161            return result;
    125162          } 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            }
    126171            return null;
    127172          }
    128         } else {
    129           return null;
    130173        }
    131174      }
     
    133176
    134177    internal void AbortEngine(Guid guid) {
    135       string clientUrl = "";
     178      throw new NotImplementedException();
     179    }
     180
     181    internal JobState JobState(Guid guid) {
    136182      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;
    148187      }
    149188    }
  • branches/3.0/sources/HeuristicLab.Grid/GridClientApplication.cs

    r2 r279  
    2727
    2828namespace 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)]
    3030  class GridClientApplication : ApplicationBase {
    3131    public override void Run() {
  • branches/3.0/sources/HeuristicLab.Grid/GridServer.cs

    r33 r279  
    3535    }
    3636
     37    public JobState JobState(Guid guid) {
     38      return engineStore.JobState(guid);
     39    }
     40
    3741    public Guid BeginExecuteEngine(byte[] engine) {
    3842      Guid guid = Guid.NewGuid();
  • branches/3.0/sources/HeuristicLab.Grid/GridServerApplication.cs

    r2 r279  
    2727
    2828namespace 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)]
    3030  class GridServerApplication : ApplicationBase {
    3131    public override void Run() {
  • branches/3.0/sources/HeuristicLab.Grid/HeuristicLab.Grid.csproj

    r32 r279  
    6363    <Compile Include="GridServerApplication.cs" />
    6464    <Compile Include="HeuristicLabGridPlugin.cs" />
    65     <Compile Include="IClient.cs" />
    6665    <Compile Include="IEngineStore.cs" />
    6766    <Compile Include="IGridServer.cs" />
  • branches/3.0/sources/HeuristicLab.Grid/IEngineStore.cs

    r32 r279  
    3030  interface IEngineStore {
    3131    [OperationContract]
    32     bool TryTakeEngine(string clientUrl, out Guid guid, out byte[] engine);
     32    bool TryTakeEngine(out Guid guid, out byte[] engine);
    3333
    3434    [OperationContract]
  • branches/3.0/sources/HeuristicLab.Grid/IGridServer.cs

    r33 r279  
    2626
    2727namespace HeuristicLab.Grid {
     28  public enum JobState {
     29    Unkown,
     30    Waiting,
     31    Busy,
     32    Finished
     33  }
     34
     35
    2836  [ServiceContract(Namespace = "http://HeuristicLab.Grid")]
    2937  public interface IGridServer {
     38    [OperationContract]
     39    JobState JobState(Guid guid);
    3040    [OperationContract]
    3141    Guid BeginExecuteEngine(byte[] engine);
  • branches/3.0/sources/HeuristicLab.Grid/ProcessingEngine.cs

    r27 r279  
    3939    }
    4040
    41     public ProcessingEngine(IOperatorGraph graph, IScope globalScope, AtomicOperation initialOperation)
     41    public ProcessingEngine(IScope globalScope, AtomicOperation initialOperation)
    4242      : base() {
    4343      this.initialOperation = initialOperation;
    4444      myGlobalScope = globalScope;
    45       myOperatorGraph = graph;
    4645      myExecutionStack.Push(initialOperation);
    4746    }
     
    6867          myExecutionStack.Push(atomicOperation);
    6968          Abort();
    70           ThreadPool.QueueUserWorkItem(delegate(object state) { OnExceptionOccurred(ex); });
    7169        }
    7270        if(next != null)
    7371          myExecutionStack.Push(next);
    74         OnOperationExecuted(atomicOperation);
    7572        if(atomicOperation.Operator.Breakpoint) Abort();
    7673      } else if(operation is CompositeOperation) {
  • branches/3.0/sources/HeuristicLab.Grid/ServerForm.cs

    r115 r279  
    5252        internalAddressTextBox.Text = "net.tcp://" + Dns.GetHostAddresses(Dns.GetHostName())[0] + ":8001/Grid/JobStore";
    5353      }
    54 
    5554      jobStore = new EngineStore();
    5655      server = new GridServer(jobStore);
    57      
     56      Start();
    5857    }
    5958
    60     private void startButton_Click(object sender, EventArgs e) {
     59    private void Start() {
    6160      externalHost = new ServiceHost(server, new Uri(externalAddressTextBox.Text));
    6261      internalHost = new ServiceHost(jobStore, new Uri(internalAddressTextBox.Text));
     62      ServiceThrottlingBehavior throttlingBehavior = new ServiceThrottlingBehavior();
     63      throttlingBehavior.MaxConcurrentSessions = 20;
     64      internalHost.Description.Behaviors.Add(throttlingBehavior);
    6365      try {
    6466        NetTcpBinding binding = new NetTcpBinding();
     
    6769        binding.ReaderQuotas.MaxArrayLength = 100000000; // also 100M elements;
    6870        binding.Security.Mode = SecurityMode.None;
     71       
    6972
    7073        externalHost.AddServiceEndpoint(typeof(IGridServer), binding, externalAddressTextBox.Text);
     
    7376        internalHost.AddServiceEndpoint(typeof(IEngineStore), binding, internalAddressTextBox.Text);
    7477        internalHost.Open();
    75 
    76         startButton.Enabled = false;
    77         stopButton.Enabled = true;
    7878      } catch (CommunicationException ex) {
    7979        MessageBox.Show("An exception occurred: " + ex.Message);
     
    8282      }
    8383    }
    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 
    9284    private void statusUpdateTimer_Tick(object sender, EventArgs e) {
    9385      waitingJobsTextBox.Text = jobStore.WaitingJobs+"";
  • branches/3.0/sources/HeuristicLab.Grid/ServerForm.designer.cs

    r2 r279  
    4747      this.components = new System.ComponentModel.Container();
    4848      this.externalAddressTextBox = new System.Windows.Forms.TextBox();
    49       this.startButton = new System.Windows.Forms.Button();
    50       this.stopButton = new System.Windows.Forms.Button();
    5149      this.externalAddressLabel = new System.Windows.Forms.Label();
    5250      this.internalAddressLabel = new System.Windows.Forms.Label();
     
    6866      this.externalAddressTextBox.Size = new System.Drawing.Size(229, 20);
    6967      this.externalAddressTextBox.TabIndex = 0;
    70       //
    71       // startButton
    72       //
    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       // stopButton
    83       //
    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);
    9368      //
    9469      // externalAddressLabel
     
    185160      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
    186161      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
    187       this.ClientSize = new System.Drawing.Size(347, 195);
     162      this.ClientSize = new System.Drawing.Size(347, 150);
    188163      this.Controls.Add(this.waitingResultsLabel);
    189164      this.Controls.Add(this.waitingResultsTextBox);
     
    195170      this.Controls.Add(this.internalAddressTextBox);
    196171      this.Controls.Add(this.externalAddressLabel);
    197       this.Controls.Add(this.stopButton);
    198       this.Controls.Add(this.startButton);
    199172      this.Controls.Add(this.externalAddressTextBox);
    200173      this.Name = "ServerForm";
     
    208181
    209182    private System.Windows.Forms.TextBox externalAddressTextBox;
    210     private System.Windows.Forms.Button startButton;
    211     private System.Windows.Forms.Button stopButton;
    212183    private System.Windows.Forms.Label externalAddressLabel;
    213184    private System.Windows.Forms.Label internalAddressLabel;
  • branches/3.0/sources/HeuristicLab.PluginInfrastructure/ApplicationInfo.cs

    r2 r279  
    4646    }
    4747
     48    private bool autoRestart;
     49    public bool AutoRestart {
     50      get { return autoRestart; }
     51      set { autoRestart = value; }
     52    }
     53
    4854    private string pluginAssembly;
    4955    /// <summary>
    5056    /// Name of the assembly that contains the IApplication type.
    51     /// NEEDED?
    5257    /// </summary>
    5358    public string PluginAssembly {
     
    5964    /// <summary>
    6065    /// Name of the type that implements the interface IApplication.
    61     /// NEEDED?
    6266    /// </summary>
    6367    public string PluginType {
  • branches/3.0/sources/HeuristicLab.PluginInfrastructure/BaseClasses/ApplicationBase.cs

    r8 r279  
    3030    private Version version;
    3131    private string description;
    32    
     32    private bool autoRestart;
     33
    3334    public ApplicationBase() {
    3435      ReadAttributes();
     
    4546      // after the assertion we are sure that the array access will not fail
    4647      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        }
    4755
    48       // if the plugin name is not explicitly set in the attribute then the default plugin name is the FullName of the type
    49       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        }
    5462
    55       // if the version is not explicitly set in the attribute then the version of the assembly is used as default
    56       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        }
    6169
    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;
    6771      }
    6872    }
     
    8387    }
    8488
    85     public abstract void Run() ;
     89    public bool AutoRestart {
     90      get { return autoRestart; }
     91    }
     92
     93    public abstract void Run();
    8694
    8795    #endregion
  • branches/3.0/sources/HeuristicLab.PluginInfrastructure/ClassInfoAttribute.cs

    r91 r279  
    5252    }
    5353
     54    private bool autoRestart;
     55    public bool AutoRestart {
     56      get { return autoRestart; }
     57      set { autoRestart = value; }
     58    }
     59
    5460    public ClassInfoAttribute() {}
    5561  }
  • branches/3.0/sources/HeuristicLab.PluginInfrastructure/Interfaces/IApplication.cs

    r2 r279  
    2929    Version Version { get; }
    3030    string Description { get;}
     31    bool AutoRestart { get; }
    3132    void Run();
    3233  }
  • branches/3.0/sources/HeuristicLab.PluginInfrastructure/Loader.cs

    r91 r279  
    120120        info.Version = application.Version;
    121121        info.Description = application.Description;
     122        info.AutoRestart = application.AutoRestart;
    122123        info.PluginAssembly = application.GetType().Assembly.GetName().Name;
    123124        info.PluginType = application.GetType().Namespace + "." + application.GetType().Name;
  • branches/3.0/sources/HeuristicLab.PluginInfrastructure/PluginManager.cs

    r29 r279  
    103103      setup.PrivateBinPath = pluginDir;
    104104      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      }
    113118    }
    114119
  • branches/3.0/sources/HeuristicLab.Scheduling.JSSP/HeuristicLab.Scheduling.JSSP.csproj

    r30 r279  
    3737  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
    3838    <DebugSymbols>true</DebugSymbols>
    39     <DebugType>full</DebugType>
     39    <DebugType>pdbonly</DebugType>
    4040    <Optimize>false</Optimize>
    4141    <OutputPath>bin\Debug\</OutputPath>
  • branches/3.0/sources/HeuristicLab.Scheduling.JSSP/HeuristicLabJSSPPlugin.cs

    r2 r279  
    3232  [Dependency(Dependency = "HeuristicLab.Operators")]
    3333  [Dependency(Dependency = "HeuristicLab.Permutation")]
    34   public class HeuristicLabRoutingTSPPlugin : PluginBase {
     34  public class HeuristicLabSchedulingJSPPlugin : PluginBase {
    3535  }
    3636}
  • branches/3.0/sources/HeuristicLab.Scheduling.JSSP/OperationUpdater.cs

    r2 r279  
    5252            op.Predecessors.RemoveAt(index); // remove scheduled op from predecessor list
    5353            op.Start = scheduledOp.Start + scheduledOp.Duration; // new earliest start date
    54             return null;
    5554          }
    5655        }
  • branches/3.0/sources/HeuristicLab/MainForm.cs

    r278 r279  
    9494          PluginManager.Manager.Action += new PluginManagerActionEventHandler(splashScreen.Manager_Action);
    9595          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);
    97107          });
    98108          t.SetApartmentState(ApartmentState.STA); // needed for the AdvancedOptimizationFrontent
     
    122132    }
    123133
     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    }
    124150  }
    125151}
Note: See TracChangeset for help on using the changeset viewer.