Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.Grid/EngineStore.cs @ 232

Last change on this file since 232 was 221, checked in by gkronber, 17 years ago

made the expiration time shorter to decrease probability to raise OutOfMemoryExceptions (quick fix for pspitzli meta-gp engines)

File size: 6.1 KB
Line 
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;
23using System.Collections.Generic;
24using System.Text;
25using System.Threading;
26using System.ServiceModel;
27
28namespace HeuristicLab.Grid {
29  [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode = ConcurrencyMode.Multiple, UseSynchronizationContext = false)]
30  public class EngineStore : IEngineStore {
31    private List<Guid> engineList;
32    private Dictionary<Guid, byte[]> waitingEngines;
33    private Dictionary<Guid, ManualResetEvent> waitHandles;
34    private Dictionary<Guid, byte[]> results;
35    private Dictionary<Guid, DateTime> resultDate;
36    private object bigLock;
37    private ChannelFactory<IClient> clientChannelFactory;
38    public int WaitingJobs {
39      get {
40        return waitingEngines.Count;
41      }
42    }
43
44    public int RunningJobs {
45      get {
46        return waitHandles.Count;
47      }
48    }
49
50    public int WaitingResults {
51      get {
52        return results.Count;
53      }
54    }
55
56    public EngineStore() {
57      engineList = new List<Guid>();
58      waitingEngines = new Dictionary<Guid, byte[]>();
59      waitHandles = new Dictionary<Guid, ManualResetEvent>();
60      results = new Dictionary<Guid, byte[]>();
61      resultDate = new Dictionary<Guid, DateTime>();
62      bigLock = new object();
63
64      NetTcpBinding binding = new NetTcpBinding();
65      binding.MaxReceivedMessageSize = 100000000; // 100Mbytes
66      binding.ReaderQuotas.MaxStringContentLength = 100000000; // also 100M chars
67      binding.ReaderQuotas.MaxArrayLength = 100000000; // also 100M elements;
68      binding.Security.Mode = SecurityMode.None;
69
70      clientChannelFactory = new ChannelFactory<IClient>(binding);
71    }
72
73    public bool TryTakeEngine(out Guid guid, out byte[] engine) {
74      lock(bigLock) {
75        if(engineList.Count == 0) {
76          guid = Guid.Empty;
77          engine = null;
78          return false;
79        } else {
80          guid = engineList[0];
81          engineList.RemoveAt(0);
82          engine = waitingEngines[guid];
83          waitingEngines.Remove(guid);
84          return true;
85        }
86      }
87    }
88
89    public void StoreResult(Guid guid, byte[] result) {
90      lock(bigLock) {
91        // clear old results
92        List<Guid> expiredResults = FindExpiredResults(DateTime.Now.AddMinutes(-10.0));
93        foreach(Guid expiredGuid in expiredResults) {
94          results.Remove(expiredGuid);
95          waitHandles.Remove(expiredGuid);
96          resultDate.Remove(expiredGuid);
97        }
98        // add the new result
99        results[guid] = result;
100        resultDate[guid] = DateTime.Now;
101        waitHandles[guid].Set();
102      }
103    }
104
105    private List<Guid> FindExpiredResults(DateTime expirationDate) {
106      List<Guid> expiredResults = new List<Guid>();
107      foreach(Guid guid in results.Keys) {
108        if(resultDate[guid] < expirationDate) {
109          expiredResults.Add(guid);
110        }
111      }
112      return expiredResults;
113    }
114
115    internal void AddEngine(Guid guid, byte[] engine) {
116      lock(bigLock) {
117        engineList.Add(guid);
118        waitingEngines.Add(guid, engine);
119        waitHandles.Add(guid, new ManualResetEvent(false));
120      }
121    }
122
123    internal byte[] GetResult(Guid guid) {
124      return GetResult(guid, System.Threading.Timeout.Infinite);
125    }
126
127    internal byte[] GetResult(Guid guid, int timeout) {
128      lock(bigLock) {
129        // result already available
130        if(results.ContainsKey(guid)) {
131          // if the wait-handle for this result is still alive then close and remove it
132          if(waitHandles.ContainsKey(guid)) {
133            ManualResetEvent waitHandle = waitHandles[guid];
134            waitHandle.Close();
135            waitHandles.Remove(guid);
136          }
137          return results[guid];
138        } else {
139          // 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
140          if(!waitHandles.ContainsKey(guid)) return null;
141
142          // otherwise we have a wait-handle and can wait for the result
143          ManualResetEvent waitHandle = waitHandles[guid];
144          // wait
145          if(waitHandle.WaitOne(timeout, true)) {
146            // ok got the result in within the wait time => close and remove the wait-hande and return the result
147            waitHandle.Close();
148            waitHandles.Remove(guid);
149            byte[] result = results[guid];
150            return result;
151          } else {
152            // no result yet return without result
153            return null;
154          }
155        }
156      }
157    }
158
159    internal void AbortEngine(Guid guid) {
160      lock(bigLock) {
161        if(waitingEngines.ContainsKey(guid)) {
162          byte[] engine = waitingEngines[guid];
163          waitingEngines.Remove(guid);
164          engineList.Remove(guid);
165          waitHandles[guid].Set();
166          results.Add(guid, engine);
167        }
168      }
169    }
170
171    internal JobState JobState(Guid guid) {
172      lock(bigLock) {
173        if(waitingEngines.ContainsKey(guid)) return HeuristicLab.Grid.JobState.Waiting;
174        else if(waitHandles.ContainsKey(guid)) return HeuristicLab.Grid.JobState.Busy;
175        else if(results.ContainsKey(guid)) return HeuristicLab.Grid.JobState.Finished;
176        else return HeuristicLab.Grid.JobState.Unkown;
177      }
178    }
179  }
180}
Note: See TracBrowser for help on using the repository browser.