Free cookie consent management tool by TermsFeed Policy Generator

source: branches/HeuristicLab.Hive-3.3/sources/HeuristicLab.Hive/HeuristicLab.Hive.Slave.Core/3.3/HeartbeatManager.cs @ 5219

Last change on this file since 5219 was 5181, checked in by cneumuel, 14 years ago

#1260

  • refined job-downloads for limited resources
  • fixed minor bugs
File size: 5.4 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2010 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.Diagnostics;
24using System.Threading;
25using HeuristicLab.Common;
26using HeuristicLab.Hive.Contracts;
27using HeuristicLab.Hive.Contracts.BusinessObjects;
28using HeuristicLab.Hive.Slave.Common;
29using HeuristicLab.Hive.Slave.Communication;
30using HeuristicLab.Hive.Slave.Communication.SlaveFacade;
31using HeuristicLab.Hive.Slave.Core.ConfigurationManager;
32
33namespace HeuristicLab.Hive.Slave.Core {
34  /// <summary>
35  /// Heartbeat class. It sends every x ms a heartbeat to the server and receives a Message
36  /// </summary>
37  public class HeartbeatManager {
38    private static object locker = new object();
39    public TimeSpan Interval { get; set; }
40    private Thread heartBeatThread;
41    private AutoResetEvent waitHandle;
42
43    public HeartbeatManager() {
44      Interval = new TimeSpan(0, 0, 10);
45    }
46
47    public HeartbeatManager(TimeSpan interval) {
48      Interval = interval;
49    }
50
51    private WcfService wcfService;
52
53    private bool abortThreadPending;
54
55    ReaderWriterLockSlim heartBeatThreadIsSleepingLock = new ReaderWriterLockSlim();
56    private bool heartBeatThreadIsSleeping = false;
57
58    /// <summary>
59    /// Starts the Heartbeat signal.
60    /// </summary>
61    public void StartHeartbeat() {
62      this.waitHandle = new AutoResetEvent(true);
63      wcfService = WcfService.Instance;
64      wcfService.ProcessHeartBeatCompleted += new EventHandler<ProcessHeartBeatCompletedEventArgs>(wcfService_ProcessHeartBeatCompleted);
65      abortThreadPending = false;
66      heartBeatThread = new Thread(RunHeartBeatThread);
67      heartBeatThread.Start();
68    }
69
70    /// <summary>
71    /// Stop the heartbeat
72    /// </summary>
73    public void StopHeartBeat() {
74      abortThreadPending = true;
75      waitHandle.Set();
76      heartBeatThread.Join();
77    }
78   
79    /// <summary>
80    /// use this method to singalize there is work to do (to avoid the waiting period if its clear that actions are required)
81    /// </summary>
82    public void AwakeHeartBeatThread() {
83      waitHandle.Set();
84    }
85
86    private void RunHeartBeatThread() {
87      while (!abortThreadPending) {
88        try {
89          lock (locker) {
90            if (wcfService.ConnState != NetworkEnum.WcfConnState.Connected) {
91              wcfService.Connect(ConfigManager.Instance.GetClientInfo()); // Login happens automatically upon successufl connection
92            }
93            if(wcfService.ConnState == NetworkEnum.WcfConnState.Connected) {
94              SlaveDto info = ConfigManager.Instance.GetClientInfo();
95
96              HeartBeatData heartBeatData = new HeartBeatData {
97                SlaveId = info.Id,
98                FreeCores = info.NrOfCores.HasValue ? info.NrOfCores.Value - ConfigManager.Instance.GetUsedCores() : 0,
99                FreeMemory = GetFreeMemory(),
100                JobProgress = ConfigManager.Instance.GetExecutionTimeOfRunningJobs(),
101                IsAllowedToCalculate = UptimeManager.Instance.IsAllowedToCalculate() && UptimeManager.Instance.CalendarAvailable
102              };
103
104              if (!heartBeatData.IsAllowedToCalculate) {
105                // stop all running jobs and send snapshots to server
106                MessageQueue.GetInstance().AddMessage(MessageContainer.MessageType.UptimeLimitDisconnect);
107              }
108
109              Logger.Debug("Sending Heartbeat: " + heartBeatData);
110              wcfService.ProcessHeartBeatSync(heartBeatData);
111            }
112          } // lock
113        }
114        catch (Exception e) {
115          Logger.Error("Heartbeat Thread failed badly: " + e.Message);
116          OnExceptionOccured(e);
117        }
118        waitHandle.WaitOne(this.Interval);
119      } // while
120      waitHandle.Close();
121      abortThreadPending = false;
122      Logger.Debug("Heartbeat thread stopped");
123    }
124
125    void wcfService_ProcessHeartBeatCompleted(object sender, ProcessHeartBeatCompletedEventArgs e) {
126      Logger.Debug("Heartbeat Response received");
127      e.Result.ActionRequest.ForEach(mc => MessageQueue.GetInstance().AddMessage(mc));
128    }
129
130    #region Eventhandler
131    public event EventHandler<EventArgs<Exception>> ExceptionOccured;
132    private void OnExceptionOccured(Exception e) {
133      var handler = ExceptionOccured;
134      if (handler != null) handler(this, new EventArgs<Exception>(e));
135    }
136    #endregion
137
138    #region Helpers
139    private int GetFreeMemory() {
140      PerformanceCounter counter = new PerformanceCounter("Memory", "Available Bytes", true);
141      int mb = (int)(counter.NextValue() / 1024 / 1024);
142      return mb;
143    }
144    #endregion
145  }
146}
Note: See TracBrowser for help on using the repository browser.