Free cookie consent management tool by TermsFeed Policy Generator

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

Last change on this file since 32 was 32, checked in by gkronber, 16 years ago

worked on #2

File size: 5.2 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 Queue<Guid> engineQueue;
32    private Dictionary<Guid, byte[]> waitingEngines;
33    private Dictionary<Guid, byte[]> runningEngines;
34    private Dictionary<Guid, byte[]> results;
35    private Dictionary<Guid, string> runningClients;
36    private object bigLock;
37    private ChannelFactory<IClient> clientChannelFactory;
38
39    private event EventHandler ResultRecieved;
40
41    public int WaitingJobs {
42      get {
43        return waitingEngines.Count;
44      }
45    }
46
47    public int RunningJobs {
48      get {
49        return runningEngines.Count;
50      }
51    }
52
53    public int WaitingResults {
54      get {
55        return results.Count;
56      }
57    }
58
59    public EngineStore() {
60      engineQueue = new Queue<Guid>();
61      waitingEngines = new Dictionary<Guid, byte[]>();
62      runningEngines = new Dictionary<Guid, byte[]>();
63      runningClients = new Dictionary<Guid, string>();
64      results = new Dictionary<Guid, byte[]>();
65      bigLock = new object();
66
67      NetTcpBinding binding = new NetTcpBinding();
68      binding.MaxReceivedMessageSize = 100000000; // 100Mbytes
69      binding.ReaderQuotas.MaxStringContentLength = 100000000; // also 100M chars
70      binding.ReaderQuotas.MaxArrayLength = 100000000; // also 100M elements;
71      binding.Security.Mode = SecurityMode.None;
72
73      clientChannelFactory = new ChannelFactory<IClient>(binding);
74    }
75
76    public bool TryTakeEngine(string clientUrl, out Guid guid, out byte[] engine) {
77      lock(bigLock) {
78        if(engineQueue.Count == 0) {
79          guid = Guid.Empty;
80          engine = null;
81          return false;
82        } else {
83          guid = engineQueue.Dequeue();
84          engine = waitingEngines[guid];
85          waitingEngines.Remove(guid);
86          runningEngines[guid] = engine;
87          runningClients[guid] = clientUrl;
88          return true;
89        }
90      }
91    }
92
93    public void StoreResult(Guid guid, byte[] result) {
94      lock(bigLock) {
95        if(!runningEngines.ContainsKey(guid)) return; // ignore result when the engine is not known to be running
96
97        runningEngines.Remove(guid);
98        runningClients.Remove(guid);
99        results[guid] = result;
100        OnResultRecieved(guid);
101      }
102    }
103
104    internal void AddEngine(Guid guid, byte[] engine) {
105      lock(bigLock) {
106        engineQueue.Enqueue(guid);
107        waitingEngines.Add(guid, engine);
108      }
109    }
110
111    internal byte[] RemoveResult(Guid guid) {
112      lock(bigLock) {
113        byte[] result = results[guid];
114        results.Remove(guid);
115        return result;
116      }
117    }
118
119    internal byte[] GetResult(Guid guid) {
120      ManualResetEvent waitHandle = new ManualResetEvent(false);
121      lock(bigLock) {
122        if(results.ContainsKey(guid)) {
123          byte[] result = results[guid];
124          results.Remove(guid);
125          return result;
126        } else {
127          ResultRecieved += delegate(object source, EventArgs args) {
128            ResultRecievedEventArgs resultArgs = (ResultRecievedEventArgs)args;
129            if(resultArgs.resultGuid == guid) {
130              waitHandle.Set();
131            }
132          };
133        }
134      }
135
136      waitHandle.WaitOne();
137      waitHandle.Close();
138
139      lock(bigLock) {
140        byte[] result = results[guid];
141        results.Remove(guid);
142        return result;
143      }
144    }
145
146    internal void AbortEngine(Guid guid) {
147      string clientUrl = "";
148      lock(bigLock) {
149        if(runningClients.ContainsKey(guid)) {
150          clientUrl = runningClients[guid];
151        }
152
153        if(clientUrl != "") {
154          IClient client = clientChannelFactory.CreateChannel(new EndpointAddress(clientUrl));
155          client.Abort(guid);
156        }
157      }
158    }
159
160    private void OnResultRecieved(Guid guid) {
161      ResultRecievedEventArgs args = new ResultRecievedEventArgs();
162      args.resultGuid = guid;
163      if(ResultRecieved != null) {
164        ResultRecieved(this, args);
165      }
166    }
167
168    private class ResultRecievedEventArgs : EventArgs {
169      public Guid resultGuid;
170    }
171  }
172}
Note: See TracBrowser for help on using the repository browser.