Free cookie consent management tool by TermsFeed Policy Generator

source: branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.SolutionCaching/3.3/RunCollectionModifiers/RunCollectionModifierExecutable.cs @ 11193

Last change on this file since 11193 was 10128, checked in by ascheibe, 11 years ago

#1886 cleaned up Hive RunCollection Modifier Task classes

File size: 9.3 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2013 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;
23using System.Collections.Generic;
24using System.Linq;
25using System.Threading;
26using System.Threading.Tasks;
27using HeuristicLab.Common;
28using HeuristicLab.Core;
29using HeuristicLab.MainForm;
30using HeuristicLab.Optimization;
31using HeuristicLab.Parameters;
32using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
33
34namespace HeuristicLab.Analysis.SolutionCaching {
35  [Item("RunCollectionModifierExecutable", "An executable that runs RunCollectionModifiers on RunCollections.")]
36  [StorableClass]
37  public class RunCollectionModifierExecutable : ParameterizedNamedItem, IExecutable {
38    [Storable]
39    protected ExecutionState executionState;
40    public ExecutionState ExecutionState {
41      get { return executionState; }
42      set {
43        if (value != executionState) {
44          executionState = value;
45          OnExecutionStateChanged();
46        }
47      }
48    }
49
50    [Storable]
51    protected TimeSpan executionTime;
52    public TimeSpan ExecutionTime {
53      get { return executionTime; }
54      set {
55        if (value != executionTime) {
56          executionTime = value;
57          OnExecutionTimeChanged();
58        }
59      }
60    }
61
62    [Storable]
63    protected Stack<IRunCollectionModifier> executionStack;
64    protected Stack<IRunCollectionModifier> ExecutionStack {
65      get { return executionStack; }
66    }
67
68    [Storable]
69    protected ILog log;
70    public ILog Log {
71      get { return log; }
72    }
73
74    protected CancellationTokenSource cancellationTokenSource;
75    protected bool stopPending;
76    public IProgress Progress { get; set; }
77
78    public ValueParameter<ItemList<IRunCollectionModifier>> RunCollectionModifiersParameter {
79      get { return (ValueParameter<ItemList<IRunCollectionModifier>>)Parameters["RunCollectionModifiers"]; }
80    }
81    public RunCollection RunCollection {
82      get { return RunCollectionParameter.Value; }
83      protected set { RunCollectionParameter.Value = value; }
84    }
85    public ValueParameter<RunCollection> RunCollectionParameter {
86      get { return (ValueParameter<RunCollection>)Parameters["RunCollection"]; }
87    }
88    public ItemList<IRunCollectionModifier> RunCollectionModifiers {
89      get { return RunCollectionModifiersParameter.Value; }
90    }
91
92    #region Constructors and Cloning
93    public RunCollectionModifierExecutable() {
94      Parameters.Add(new ValueParameter<ItemList<IRunCollectionModifier>>("RunCollectionModifiers", "List of RunCollectionModifiers that are executed. ", new ItemList<IRunCollectionModifier>()));
95      Parameters.Add(new ValueParameter<RunCollection>("RunCollection", "RunCollection on which the modifiers are applied. ", new RunCollection()));
96      executionStack = new Stack<IRunCollectionModifier>();
97      log = new Log();
98      executionState = ExecutionState.Stopped;
99    }
100    [StorableConstructor]
101    protected RunCollectionModifierExecutable(bool deserializing) : base(deserializing) { }
102    protected RunCollectionModifierExecutable(RunCollectionModifierExecutable original, Cloner cloner)
103      : base(original, cloner) {
104      executionTime = original.executionTime;
105      executionState = original.executionState;
106      executionStack = new Stack<IRunCollectionModifier>();
107      foreach (var runCollectionModifier in original.executionStack) {
108        executionStack.Push(runCollectionModifier);
109      }
110      log = (ILog)original.log.Clone(cloner);
111    }
112    public override IDeepCloneable Clone(Cloner cloner) {
113      return new RunCollectionModifierExecutable(this, cloner);
114    }
115
116    //special cloning which ignores the RunCollection and the execution stack
117    public RunCollectionModifierExecutable CloneWithoutRuns() {
118      var clone = new RunCollectionModifierExecutable();
119      clone.executionTime = executionTime;
120      clone.executionState = executionState;
121      clone.log = (ILog)log.Clone(new Cloner());
122      clone.RunCollectionModifiersParameter.Value = (ItemList<IRunCollectionModifier>)RunCollectionModifiers.Clone(new Cloner());
123      return clone;
124    }
125    #endregion
126
127    protected virtual void ReportProgress(double progress) {
128      if (Progress != null) {
129        Progress.ProgressValue = progress;
130      }
131    }
132
133    protected virtual void FinishProgress() {
134      if (Progress != null) {
135        Progress.Finish();
136      }
137    }
138
139    public void Pause() {
140      cancellationTokenSource.Cancel();
141    }
142
143    public void Prepare() {
144      executionStack.Clear();
145      for (int i = RunCollectionModifiers.Count() - 1; i >= 0; i--) {
146        executionStack.Push(RunCollectionModifiers[i]);
147      }
148      OnPrepared();
149    }
150
151    public void Start() {
152      cancellationTokenSource = new CancellationTokenSource();
153
154      Task task = Task.Factory.StartNew(RunModifiers, cancellationTokenSource.Token, cancellationTokenSource.Token);
155      task.ContinueWith(t => {
156        try {
157          t.Wait();
158        }
159        catch (AggregateException ex) {
160          try {
161            ex.Flatten().Handle(x => x is OperationCanceledException);
162          }
163          catch (AggregateException remaining) {
164            if (remaining.InnerExceptions.Count == 1) OnExceptionOccuted(remaining.InnerExceptions[0]);
165            else OnExceptionOccuted(remaining);
166          }
167        }
168        FinishProgress();
169        cancellationTokenSource.Dispose();
170        cancellationTokenSource = null;
171        if (stopPending) executionStack.Clear();
172        if (executionStack.Count == 0) OnStopped();
173        else OnPaused();
174      });
175    }
176
177    public void Stop() {
178      if (ExecutionState == ExecutionState.Paused) {
179        OnStopped();
180      } else {
181        stopPending = true;
182        cancellationTokenSource.Cancel();
183      }
184    }
185
186    public virtual void AddRunCollectionModifiers(IRunCollectionModifier modifier) {
187      RunCollectionModifiers.Add(modifier);
188    }
189
190    protected virtual void RunModifiers(object state) {
191      CancellationToken ct = (CancellationToken)state;
192      OnStarted();
193      var runs = RunCollection.ToList();
194
195      IRunCollectionModifier next;
196      while (executionStack.Count > 0) {
197        next = executionStack.Pop();
198        try {
199          ct.ThrowIfCancellationRequested();
200          next.Modify(runs);
201          if (executionStack.Count > 0) {
202            ReportProgress(((double)RunCollectionModifiers.Count) / executionStack.Count());
203          } else {
204            ReportProgress(1.0);
205          }
206        }
207        catch (Exception ex) {
208          executionStack.Push(next);
209          if (ex is OperationCanceledException) throw ex;
210          else throw new Exception("IRunCollectionModifier " + next + " threw an exception.", ex);
211        }
212        finally {
213          RunCollection = new RunCollection(runs);
214        }
215      }
216    }
217
218    #region Events
219    public event EventHandler Prepared;
220    protected virtual void OnPrepared() {
221      ExecutionState = ExecutionState.Prepared;
222      EventHandler handler = Prepared;
223      if (handler != null) handler(this, EventArgs.Empty);
224    }
225    public event EventHandler Started;
226    protected virtual void OnStarted() {
227      executionState = ExecutionState.Started;
228      EventHandler handler = Started;
229      if (handler != null) handler(this, EventArgs.Empty);
230    }
231    public event EventHandler Stopped;
232    protected virtual void OnStopped() {
233      executionState = ExecutionState.Stopped;
234      EventHandler handler = Stopped;
235      if (handler != null) handler(this, EventArgs.Empty);
236    }
237    public event EventHandler Paused;
238    protected virtual void OnPaused() {
239      executionState = ExecutionState.Paused;
240      EventHandler handler = Paused;
241      if (handler != null) handler(this, EventArgs.Empty);
242    }
243    public event EventHandler<EventArgs<Exception>> ExceptionOccurred;
244    protected virtual void OnExceptionOccuted(Exception e) {
245      var eventArgs = new EventArgs<Exception>(e);
246      Log.LogException(e);
247      EventHandler<EventArgs<Exception>> handler = ExceptionOccurred;
248      if (handler != null) handler(this, eventArgs);
249    }
250    public event EventHandler ExecutionTimeChanged;
251    protected virtual void OnExecutionTimeChanged() {
252      EventHandler handler = ExecutionTimeChanged;
253      if (handler != null) handler(this, EventArgs.Empty);
254    }
255    public event EventHandler ExecutionStateChanged;
256    protected virtual void OnExecutionStateChanged() {
257      EventHandler handler = ExecutionStateChanged;
258      if (handler != null) handler(this, EventArgs.Empty);
259    }
260    #endregion
261  }
262}
Note: See TracBrowser for help on using the repository browser.