Free cookie consent management tool by TermsFeed Policy Generator

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

Last change on this file since 10115 was 10115, checked in by ascheibe, 10 years ago

#1886 some improvements in the RunCollectionModifierExecutable

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