Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.Clients.Hive.Slave.Views/3.3/SlaveItem.cs @ 12749

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

#2212 merged r12008, r12009, r12010 back into trunk

File size: 8.3 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2015 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.ServiceModel;
24using HeuristicLab.Clients.Hive.SlaveCore.ServiceContracts;
25using HeuristicLab.Clients.Hive.SlaveCore.Views.Properties;
26using HeuristicLab.Common;
27using HeuristicLab.Core;
28
29namespace HeuristicLab.Clients.Hive.SlaveCore.Views {
30
31  public enum SlaveDisplayStat {
32    Offline,  // not connected to Hive
33    Idle,     // slave has no jobs to calculate
34    Busy,     // jobs are currently running on slave
35    Asleep,   // we are not accepting jobs at the moment
36    NoService // the slave windows service is currently not running
37  }
38
39  public enum CoreConnection {
40    Connected,
41    Offline
42  }
43
44  [CallbackBehavior(ConcurrencyMode = ConcurrencyMode.Reentrant, UseSynchronizationContext = false)]
45  [Item("SlaveItem", "Represents a slave which receives messages from the core")]
46  public class SlaveItem : Item, ISlaveCommunicationCallbacks, IDisposable {
47    private ISlaveCommunication pipeProxy;
48    private DuplexChannelFactory<ISlaveCommunication> pipeFactory;
49    private int lastJobsFetched = 0;
50
51    public SlaveItem() {
52    }
53
54    private void RegisterEvents() {
55      pipeFactory.Faulted += new EventHandler(pipeFactory_Faulted);
56      pipeFactory.Closed += new EventHandler(pipeFactory_Closed);
57      pipeFactory.Opened += new EventHandler(pipeFactory_Opened);
58    }
59
60    private void DeregisterEvents() {
61      pipeFactory.Faulted -= new EventHandler(pipeFactory_Faulted);
62      pipeFactory.Closed -= new EventHandler(pipeFactory_Closed);
63      pipeFactory.Opened -= new EventHandler(pipeFactory_Opened);
64    }
65
66    void pipeFactory_Opened(object sender, EventArgs e) {
67      OnMessageLogged("Connection to Slave core opened");
68      OnCoreConnectionChanged(CoreConnection.Connected);
69    }
70
71    void pipeFactory_Closed(object sender, EventArgs e) {
72      OnMessageLogged("Connection to Slave core closed");
73      OnCoreConnectionChanged(CoreConnection.Offline);
74    }
75
76    void pipeFactory_Faulted(object sender, EventArgs e) {
77      OnMessageLogged("Connection to Slave core faulted");
78      OnCoreConnectionChanged(CoreConnection.Offline);
79    }
80
81    public void Open() {
82      try {
83        pipeFactory = new DuplexChannelFactory<ISlaveCommunication>(this, Settings.Default.SlaveCommunicationServiceEndpoint);
84        RegisterEvents();
85      }
86      catch (Exception ex) {
87        OnMessageLogged("Error establishing connection to Core. Are you missing a configuration file?" + Environment.NewLine + ex.ToString());
88      }
89    }
90
91    public bool ReconnectToSlaveCore() {
92      try {
93        DeregisterEvents();
94        pipeProxy = pipeFactory.CreateChannel();
95        StatusCommons st = pipeProxy.Subscribe();
96        if (st != null) {
97          RegisterEvents();
98          OnStatusChanged(st);
99          return true;
100        } else {
101          return false;
102        }
103      }
104      catch (Exception) {
105        OnMessageLogged("Couldn't connect to Slave core. Is it possible that the core isn't running?");
106        return false;
107      }
108    }
109
110    public bool IsClosed() {
111      if (pipeFactory == null) return true;
112      return pipeFactory.State == CommunicationState.Closed || pipeFactory.State == CommunicationState.Faulted;
113    }
114
115    public void PauseAll() {
116      try {
117        if (pipeFactory.State != CommunicationState.Faulted && pipeFactory.State != CommunicationState.Closed)
118          pipeProxy.PauseAll();
119      }
120      catch (Exception e) {
121        OnMessageLogged("Error soft pausening core: " + e.ToString());
122      }
123    }
124
125    public void StopAll() {
126      try {
127        if (pipeFactory.State != CommunicationState.Faulted && pipeFactory.State != CommunicationState.Closed)
128          pipeProxy.StopAll();
129      }
130      catch (Exception e) {
131        OnMessageLogged("Error hard pausening core: " + e.ToString());
132      }
133    }
134
135    public void RestartCore() {
136      try {
137        if (pipeFactory.State != CommunicationState.Faulted && pipeFactory.State != CommunicationState.Closed)
138          pipeProxy.Restart();
139      }
140      catch (Exception e) {
141        OnMessageLogged("Error restarting core: " + e.ToString());
142      }
143    }
144
145    public void Sleep() {
146      try {
147        if (pipeFactory.State != CommunicationState.Faulted && pipeFactory.State != CommunicationState.Closed) {
148          pipeProxy.Sleep();
149        }
150      }
151      catch (Exception e) {
152        OnMessageLogged("Error sending core to sleep: " + e.ToString());
153      }
154    }
155
156    public void Close() {
157      if (pipeFactory.State != CommunicationState.Closed) {
158        pipeProxy.Unsubscribe();
159        pipeFactory.Close();
160      }
161    }
162
163    public event EventHandler<EventArgs<string>> UserVisibleMessageFired;
164    public void OnUserVisibleMessageFired(string msg) {
165      var handler = UserVisibleMessageFired;
166      if (handler != null) handler(this, new EventArgs<string>(msg));
167    }
168
169    public event EventHandler<EventArgs<SlaveDisplayStat>> SlaveDisplayStateChanged;
170    public void OnSlaveDisplayStateChanged(StatusCommons status) {
171      SlaveDisplayStat stat;
172
173      if (status.Jobs.Count > 0) {
174        stat = SlaveDisplayStat.Busy;
175      } else {
176        stat = SlaveDisplayStat.Idle;
177      }
178      if (status.Asleep) {
179        stat = SlaveDisplayStat.Asleep;
180      }
181      if (status.Status == NetworkEnum.WcfConnState.Disconnected || status.Status == NetworkEnum.WcfConnState.Failed) {
182        stat = SlaveDisplayStat.Offline;
183      }
184
185      var handler = SlaveDisplayStateChanged;
186      if (handler != null) handler(this, new EventArgs<SlaveDisplayStat>(stat));
187    }
188
189    public void OnSlaveDisplayStateChanged(SlaveDisplayStat stat) {
190      var handler = SlaveDisplayStateChanged;
191      if (handler != null) handler(this, new EventArgs<SlaveDisplayStat>(stat));
192    }
193
194    public event EventHandler<EventArgs<StatusCommons>> SlaveStatusChanged;
195    public void OnStatusChanged(StatusCommons status) {
196      var handler = SlaveStatusChanged;
197      if (handler != null) handler(this, new EventArgs<StatusCommons>(status));
198
199      OnSlaveDisplayStateChanged(status);
200
201      int diff = status.JobsFetched - lastJobsFetched;
202      lastJobsFetched = status.JobsFetched;
203      if (diff > 0) {
204        if (diff == 1) {
205          OnUserVisibleMessageFired("HeuristicLab Hive received 1 new task!");
206        } else {
207          OnUserVisibleMessageFired(string.Format("HeuristicLab Hive received {0} new jobs!", diff));
208        }
209      }
210    }
211
212    public event EventHandler<EventArgs<string>> SlaveMessageLogged;
213    public void OnMessageLogged(string message) {
214      var handler = SlaveMessageLogged;
215      if (handler != null) handler(this, new EventArgs<string>(message));
216    }
217
218    public event EventHandler SlaveShutdown;
219    public void OnShutdown() {
220      var handler = SlaveShutdown;
221      if (handler != null) handler(this, EventArgs.Empty);
222      OnSlaveDisplayStateChanged(SlaveDisplayStat.NoService);
223    }
224
225    public event EventHandler<EventArgs<CoreConnection>> CoreConnectionChanged;
226    public void OnCoreConnectionChanged(CoreConnection conn) {
227      var handler = CoreConnectionChanged;
228      if (handler != null) handler(this, new EventArgs<CoreConnection>(conn));
229    }
230
231    public void Dispose() {
232      DeregisterEvents();
233      Close();
234    }
235
236    public override Common.IDeepCloneable Clone(Common.Cloner cloner) {
237      throw new NotImplementedException("It's not allowed to clone a SlaveItem!");
238    }
239  }
240}
Note: See TracBrowser for help on using the repository browser.