Free cookie consent management tool by TermsFeed Policy Generator

source: branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Clients.Hive.Slave.Views/3.4/SlaveView.cs @ 6371

Last change on this file since 6371 was 6371, checked in by ascheibe, 13 years ago

#1233

  • code cleanups for slave review
  • added switch between privileged and unprivileged sandbox
  • removed childjob management because it's not used
File size: 12.1 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2011 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.Runtime.InteropServices;
25using System.Security.Principal;
26using System.ServiceProcess;
27using System.Threading;
28using System.Threading.Tasks;
29using System.Windows.Forms;
30using System.Windows.Forms.DataVisualization.Charting;
31using HeuristicLab.Common;
32using HeuristicLab.Core.Views;
33using HeuristicLab.MainForm;
34
35
36namespace HeuristicLab.Clients.Hive.SlaveCore.Views {
37
38  [View("HeuristicLab Slave View")]
39  [Content(typeof(SlaveItem), IsDefaultView = true)]
40  public partial class SlaveView : ItemView {
41    private SlaveDisplayStat lastSlaveDisplayStat;
42    private const string serviceName = "HeuristicLab.Clients.Hive.SlaveCore.SlaveWindowsService";
43
44    private const UInt32 BCM_SETSHIELD = 0x160C;
45    [DllImport("user32", CharSet = CharSet.Auto, SetLastError = true)]
46    static extern int SendMessage(IntPtr hWnd, UInt32 Msg, int wParam, IntPtr lParam);
47
48    public new SlaveItem Content {
49      get { return (SlaveItem)base.Content; }
50      set {
51        if (base.Content != value) {
52          base.Content = value;
53        }
54      }
55    }
56
57    public SlaveView() {
58      InitializeComponent();
59
60      if (CheckRunAsAdmin()) {
61        btnKill.ImageAlign = System.Drawing.ContentAlignment.MiddleLeft;
62        btnKill.Image = HeuristicLab.Common.Resources.VSImageLibrary.BreakpointActive;
63      } else {
64        this.btnKill.FlatStyle = FlatStyle.System;
65        SendMessage(btnKill.Handle, BCM_SETSHIELD, 0, (IntPtr)1);
66      }
67
68      lblSlaveState.Text = SlaveDisplayStat.NoService.ToString();
69      lastSlaveDisplayStat = SlaveDisplayStat.NoService;
70      Content_SlaveDisplayStateChanged(this, new EventArgs<SlaveDisplayStat>(lastSlaveDisplayStat));
71    }
72
73    #region Register Content Events
74    protected override void DeregisterContentEvents() {
75      Content.SlaveShutdown -= new System.EventHandler(Content_SlaveShutdown);
76      Content.SlaveStatusChanged -= new System.EventHandler<EventArgs<StatusCommons>>(Content_SlaveStatusChanged);
77      Content.SlaveDisplayStateChanged -= new EventHandler<EventArgs<SlaveDisplayStat>>(Content_SlaveDisplayStateChanged);
78      Content.CoreConnectionChanged -= new EventHandler<EventArgs<CoreConnection>>(Content_CoreConnectionChanged);
79
80      base.DeregisterContentEvents();
81    }
82
83    protected override void RegisterContentEvents() {
84      base.RegisterContentEvents();
85
86      Content.SlaveShutdown += new System.EventHandler(Content_SlaveShutdown);
87      Content.SlaveStatusChanged += new System.EventHandler<EventArgs<StatusCommons>>(Content_SlaveStatusChanged);
88      Content.SlaveDisplayStateChanged += new EventHandler<EventArgs<SlaveDisplayStat>>(Content_SlaveDisplayStateChanged);
89      Content.CoreConnectionChanged += new EventHandler<EventArgs<CoreConnection>>(Content_CoreConnectionChanged);
90    }
91    #endregion
92
93    protected override void OnContentChanged() {
94      base.OnContentChanged();
95      btnKill.Enabled = false;
96      btnStart.Enabled = false;
97      btnStop.Enabled = false;
98
99      if (Content == null) {
100        //nothing to do...         
101      } else {
102        //try to establish a connection to the slave service
103        if (base.Content != null) {
104          ((SlaveItem)base.Content).Open();
105          Task.Factory.StartNew(Connector);
106        }
107      }
108    }
109
110    private void Connector() {
111      Content_SlaveDisplayStateChanged(this, new EventArgs<SlaveDisplayStat>(SlaveDisplayStat.NoService));
112      bool connected = false;
113      while (!connected) {
114        this.Invoke(new Func<bool>(() => connected = ((SlaveItem)base.Content).ReconnectToSlaveCore()));
115
116        if (!connected) {
117          Thread.Sleep(1000);
118        }
119      }
120      this.Invoke(new Action(SetEnabledStateOfControls));
121    }
122
123    protected override void SetEnabledStateOfControls() {
124      base.SetEnabledStateOfControls();
125      //do nothing at the moment, we have nothing editable
126    }
127
128    #region Event Handlers
129    void Content_SlaveStatusChanged(object sender, EventArgs<StatusCommons> e) {
130      RenderJobChart(e.Value);
131      RenderCoreChart(e.Value);
132    }
133
134    void Content_SlaveShutdown(object sender, System.EventArgs e) {
135      Task.Factory.StartNew(Connector);
136    }
137
138    void Content_SlaveDisplayStateChanged(object sender, EventArgs<SlaveDisplayStat> e) {
139      lblSlaveState.Text = e.Value.ToString();
140      lastSlaveDisplayStat = e.Value;
141
142      if (e.Value == SlaveDisplayStat.Asleep || e.Value == SlaveDisplayStat.NoService) {
143        btnKill.Enabled = false;
144        btnStart.Enabled = true;
145        btnStop.Enabled = false;
146      }
147
148      if (e.Value == SlaveDisplayStat.Busy || e.Value == SlaveDisplayStat.Idle || e.Value == SlaveDisplayStat.Offline) {
149        btnKill.Enabled = true;
150        btnStart.Enabled = false;
151        btnStop.Enabled = true;
152      }
153    }
154
155    void Content_CoreConnectionChanged(object sender, EventArgs<CoreConnection> e) {
156      if (e.Value == CoreConnection.Offline) {
157        btnKill.Enabled = false;
158        btnStart.Enabled = false;
159        btnStop.Enabled = false;
160      }
161    }
162    #endregion
163
164    private void RenderJobChart(StatusCommons status) {
165      jobChart.Series[0].Points.Clear();
166      jobChart.Series[1].Points.Clear();
167      jobChart.Series[2].Points.Clear();
168      jobChart.Series[3].Points.Clear();
169      jobChart.Series[4].Points.Clear();
170
171
172      DataPoint pJobs = new DataPoint(1, status.Jobs.Count);
173      DataPoint pJobsAborted = new DataPoint(2, status.JobsAborted);
174      DataPoint pJobsDone = new DataPoint(3, status.JobsFinished);
175      DataPoint pJobsFetched = new DataPoint(4, status.JobsFetched);
176      DataPoint pJobsFailed = new DataPoint(5, status.JobsFailed);
177
178      pJobs.LegendText = "Current jobs: " + status.Jobs.Count;
179      pJobs.Color = System.Drawing.Color.Yellow;
180      pJobs.ToolTip = pJobs.LegendText;
181      jobChart.Series[0].Color = System.Drawing.Color.Yellow;
182      jobChart.Series[0].LegendText = pJobs.LegendText;
183      jobChart.Series[0].Points.Add(pJobs);
184
185      pJobsAborted.LegendText = "Aborted jobs: " + status.JobsAborted;
186      pJobsAborted.Color = System.Drawing.Color.Orange;
187      pJobsAborted.ToolTip = pJobsAborted.LegendText;
188      jobChart.Series[1].Color = System.Drawing.Color.Orange;
189      jobChart.Series[1].LegendText = pJobsAborted.LegendText;
190      jobChart.Series[1].Points.Add(pJobsAborted);
191
192      pJobsDone.LegendText = "Finished jobs: " + status.JobsFinished;
193      pJobsDone.Color = System.Drawing.Color.Green;
194      pJobsDone.ToolTip = pJobsDone.LegendText;
195      jobChart.Series[2].Color = System.Drawing.Color.Green;
196      jobChart.Series[2].LegendText = pJobsDone.LegendText;
197      jobChart.Series[2].Points.Add(pJobsDone);
198
199      pJobsFetched.LegendText = "Fetched jobs: " + status.JobsFetched;
200      pJobsFetched.ToolTip = pJobsFetched.LegendText;
201      pJobsFetched.Color = System.Drawing.Color.Blue;
202      jobChart.Series[3].Color = System.Drawing.Color.Blue;
203      jobChart.Series[3].LegendText = pJobsFetched.LegendText;
204      jobChart.Series[3].Points.Add(pJobsFetched);
205
206      pJobsFailed.LegendText = "Failed jobs: " + status.JobsFailed;
207      pJobsFailed.ToolTip = pJobsFailed.LegendText;
208      pJobsFailed.Color = System.Drawing.Color.Red;
209      jobChart.Series[4].Color = System.Drawing.Color.Red;
210      jobChart.Series[4].LegendText = pJobsFailed.LegendText;
211      jobChart.Series[4].Points.Add(pJobsFailed);
212    }
213
214    private void RenderCoreChart(StatusCommons statusCommons) {
215      int usedCores = statusCommons.TotalCores - statusCommons.FreeCores;
216      DataPoint pFreeCores = new DataPoint(statusCommons.FreeCores, statusCommons.FreeCores);
217      DataPoint pUsedCores = new DataPoint(usedCores, usedCores);
218
219      coresChart.Series[0].Points.Clear();
220
221      pFreeCores.LegendText = "Free cores: " + statusCommons.FreeCores;
222      pFreeCores.Color = System.Drawing.Color.Green;
223      pUsedCores.LegendText = "Used cores: " + usedCores;
224      pUsedCores.Color = System.Drawing.Color.Red;
225
226      coresChart.Series[0].Points.Add(pFreeCores);
227      coresChart.Series[0].Points.Add(pUsedCores);
228    }
229
230    private bool CheckRunAsAdmin() {
231      bool isRunAsAdmin = false;
232      WindowsIdentity user = WindowsIdentity.GetCurrent();
233      WindowsPrincipal principal = new WindowsPrincipal(user);
234
235      try {
236        isRunAsAdmin = principal.IsInRole(WindowsBuiltInRole.Administrator);
237      }
238      catch { }
239      return isRunAsAdmin;
240    }
241
242    /// <summary>
243    /// Shows the windows UAC dialog and restarts tray icon app
244    /// </summary>
245    private void ElevateApplication() {
246      // launch itself as administrator
247      ProcessStartInfo proc = new ProcessStartInfo(Application.ExecutablePath, "showui");
248      proc.UseShellExecute = true;
249      proc.WorkingDirectory = Environment.CurrentDirectory;
250      proc.FileName = Application.ExecutablePath;
251      proc.Verb = "runas";
252
253      try {
254        Process.Start(proc);
255      }
256      catch {
257        // user refused to allow privileges elevation       
258        return;
259      }
260      Application.Exit();
261    }
262
263    private void StartService() {
264      TimeSpan timeout = TimeSpan.FromMilliseconds(5000);
265
266      ServiceController service = new ServiceController(serviceName);
267      try {
268        if (service.Status == ServiceControllerStatus.Running) {
269          service.Stop();
270          service.WaitForStatus(ServiceControllerStatus.Stopped, timeout);
271        }
272
273        service.Start();
274        service.WaitForStatus(ServiceControllerStatus.Running, timeout);
275      }
276      catch (InvalidOperationException ex) {
277        MessageBox.Show("Error starting service: Hive Slave Service not found!" + Environment.NewLine + ex.ToString());
278      }
279      catch (Exception ex) {
280        MessageBox.Show("Error starting service, exception is: " + Environment.NewLine + ex.ToString());
281      }
282    }
283
284    private void StopService() {
285      TimeSpan timeout = TimeSpan.FromMilliseconds(7000);
286
287      ServiceController service = new ServiceController(serviceName);
288      try {
289        if (service.Status == ServiceControllerStatus.Running) {
290          service.Stop();
291          service.WaitForStatus(ServiceControllerStatus.Stopped, timeout);
292        }
293      }
294      catch (InvalidOperationException ex) {
295        MessageBox.Show("Error starting service: Hive Slave Service not found!" + Environment.NewLine + ex.ToString());
296      }
297      catch (Exception ex) {
298        MessageBox.Show("Error starting service, exception is: " + Environment.NewLine + ex.ToString());
299      }
300    }
301
302    private void btnKill_Click(object sender, EventArgs e) {
303      if (CheckRunAsAdmin()) {
304        StopService();
305      } else {
306        ElevateApplication();
307      }
308    }
309
310    private void btnStop_Click(object sender, EventArgs e) {
311      if (Content != null) {
312        Content.Sleep();
313      }
314    }
315
316    private void btnStart_Click(object sender, EventArgs e) {
317      if (Content != null) {
318        if (lastSlaveDisplayStat == SlaveDisplayStat.Asleep) {
319          Content.RestartCore();
320        } else if (lastSlaveDisplayStat == SlaveDisplayStat.NoService) {
321          if (CheckRunAsAdmin()) {
322            StartService();
323          } else {
324            ElevateApplication();
325          }
326        }
327      }
328    }
329  }
330}
Note: See TracBrowser for help on using the repository browser.