Free cookie consent management tool by TermsFeed Policy Generator

source: branches/OptimizationNetworks/HeuristicLab.Networks.IntegratedOptimization/3.3/OrchestratedAlgorithmNode.cs @ 14598

Last change on this file since 14598 was 14598, checked in by jkarder, 7 years ago

#2205: worked on optimization networks

  • switched from IConfigurationPorts to IMessagePorts
  • removed option to clone algorithms in OrchestratedAlgorithmNodes
  • made properties of TourProfitProblem storable
  • fixed event handler registration
File size: 7.1 KB
Line 
1using System;
2using System.Collections.Generic;
3using System.Linq;
4using System.Threading;
5using HeuristicLab.Common;
6using HeuristicLab.Core;
7using HeuristicLab.Core.Networks;
8using HeuristicLab.Data;
9using HeuristicLab.Operators;
10using HeuristicLab.Optimization;
11using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
12
13namespace HeuristicLab.Networks.IntegratedOptimization {
14  [Item("OrchestratedAlgorithmNode", "A node of a network which contains a HeuristicLab algorithm and can be orchestrated by an orchestrator.")]
15  [StorableClass]
16  public class OrchestratedAlgorithmNode : AlgorithmNode {
17    #region Constants
18    private const string OrchestrationPortName = "OrchestrationPort";
19    private const string EvaluationPortName = "EvaluationPort";
20    #endregion
21
22    private bool sendResultMessage = true;
23
24    #region Ports
25    public IMessagePort OrchestrationPort {
26      get { return (IMessagePort)Ports[OrchestrationPortName]; }
27    }
28    public IMessagePort EvaluationPort {
29      get { return (IMessagePort)Ports[EvaluationPortName]; }
30    }
31    #endregion
32
33    [Storable]
34    private IHookOperator evalHook;
35    public IHookOperator EvalHook {
36      get { return evalHook; }
37      set {
38        if (evalHook == value) return;
39        evalHook = value;
40        evalHook.Port = EvaluationPort;
41      }
42    }
43
44    [StorableConstructor]
45    protected OrchestratedAlgorithmNode(bool deserializing) : base(deserializing) { }
46    protected OrchestratedAlgorithmNode(OrchestratedAlgorithmNode original, Cloner cloner) : base(original, cloner) {
47      EvalHook = cloner.Clone(original.EvalHook);
48      RegisterEvents();
49    }
50    public OrchestratedAlgorithmNode() : this("OrchestratedAlgorithmNode") { }
51    public OrchestratedAlgorithmNode(string name) : base(name) {
52      var orchestrationPort = new MessagePort(OrchestrationPortName);
53      Ports.Add(orchestrationPort);
54
55      var evaluationPort = new MessagePort(EvaluationPortName);
56      Ports.Add(evaluationPort);
57
58      RegisterEvents();
59    }
60
61    public override IDeepCloneable Clone(Cloner cloner) {
62      return new OrchestratedAlgorithmNode(this, cloner);
63    }
64
65    [StorableHook(HookType.AfterDeserialization)]
66    private void AfterDeserialization() {
67      RegisterEvents();
68    }
69
70    private void RegisterEvents() {
71      OrchestrationPort.MessageReceived += OrchestrationPort_MessageReceived;
72    }
73
74    #region Port Events
75    private void OrchestrationPort_MessageReceived(object sender, EventArgs<IMessage, CancellationToken> e) {
76      var message = ((EnumValue<OrchestrationMessage>)e.Value["OrchestrationMessage"]).Value;
77
78      #region Prepare
79      if (message.HasFlag(OrchestrationMessage.Prepare)) {
80        switch (Algorithm.ExecutionState) {
81          case ExecutionState.Prepared:
82          case ExecutionState.Paused:
83          case ExecutionState.Stopped:
84            IMessageValue problemMsgVal;
85            if (e.Value.Values.TryGetValue("Problem", out problemMsgVal)) {
86              var prob = (IHeuristicOptimizationProblem)problemMsgVal.Value.Clone();
87
88              if (message.HasFlag(OrchestrationMessage.QualityAdaption)) {
89                var instEval = prob.Evaluator as InstrumentedOperator;
90                if (instEval != null && EvalHook != null) instEval.AfterExecutionOperators.Add(EvalHook);
91              }
92
93              IParameter analyzerParameter = null;
94              IMultiAnalyzer multiAnalyzer = null;
95              var checkedStates = new Dictionary<Type, bool>();
96              if (Algorithm.Parameters.TryGetValue("Analyzer", out analyzerParameter)) {
97                multiAnalyzer = analyzerParameter.ActualValue as IMultiAnalyzer;
98                foreach (var item in multiAnalyzer.Operators)
99                  checkedStates.Add(item.GetType(), multiAnalyzer.Operators.ItemChecked(item));
100              }
101
102              Algorithm.Problem = prob;
103
104              if (multiAnalyzer != null) {
105                if (Algorithm.Parameters.TryGetValue("Analyzer", out analyzerParameter)) {
106                  multiAnalyzer = analyzerParameter.ActualValue as IMultiAnalyzer;
107                  if (multiAnalyzer != null && checkedStates.Any()) {
108                    foreach (var analyzer in multiAnalyzer.Operators) {
109                      bool checkedState;
110                      checkedStates.TryGetValue(analyzer.GetType(), out checkedState);
111                      multiAnalyzer.Operators.SetItemCheckedState(analyzer, checkedState);
112                    }
113                  }
114                }
115              }
116
117              Algorithm.Prepare();
118            }
119            break;
120        }
121      }
122      #endregion
123
124      #region Start
125      if (message.HasFlag(OrchestrationMessage.Start)) {
126        switch (Algorithm.ExecutionState) {
127          case ExecutionState.Prepared:
128          case ExecutionState.Paused:
129            var trigger = new ManualResetEvent(false);
130            Exception ex = null;
131
132            EventHandler onStopped = null;
133            EventHandler<EventArgs<Exception>> onExceptionOccurred = null;
134            Algorithm.Stopped += onStopped = (src, args) => {
135              Algorithm.Stopped -= onStopped;
136              Algorithm.ExceptionOccurred -= onExceptionOccurred;
137              trigger.Set();
138            };
139            Algorithm.ExceptionOccurred += onExceptionOccurred = (src, args) => {
140              Algorithm.Stopped -= onStopped;
141              Algorithm.ExceptionOccurred -= onExceptionOccurred;
142              ex = args.Value;
143              trigger.Set();
144            };
145
146            Algorithm.Start();
147            trigger.WaitOne();
148
149            if (ex != null) throw ex;
150
151            if (sendResultMessage) {
152              var msg = OrchestrationPort.PrepareMessage();
153              msg["Results"] = (ResultCollection)Algorithm.Results.Clone();
154              OrchestrationPort.SendMessage(msg);
155            } else sendResultMessage = true;
156            break;
157        }
158      }
159      #endregion
160
161      #region Pause
162      if (message.HasFlag(OrchestrationMessage.Pause)) {
163        if (Algorithm.ExecutionState == ExecutionState.Started) {
164          sendResultMessage = false;
165          try {
166            Algorithm.Pause();
167          } catch (InvalidOperationException) {
168            // ExecutionState might have changed since we accepted the message
169          }
170        }
171      }
172      #endregion
173
174      #region Stop
175      if (message.HasFlag(OrchestrationMessage.Stop)) {
176        switch (Algorithm.ExecutionState) {
177          case ExecutionState.Started:
178          case ExecutionState.Paused:
179            try {
180              Algorithm.Stop();
181            } catch (InvalidOperationException) {
182              // ExecutionState might have changed since we accepted the message
183            } catch (NullReferenceException) {
184              // BasicAlgorithm might have stopped since we accepted the message
185              // CancellationTokenSource is null in this case
186            }
187            break;
188        }
189      }
190      #endregion
191    }
192    #endregion
193  }
194}
Note: See TracBrowser for help on using the repository browser.