Free cookie consent management tool by TermsFeed Policy Generator

source: branches/HeuristicLab.Hive/sources/HeuristicLab.Hive/HeuristicLab.Hive.Slave.Console/3.3/HiveSlaveConsole.cs @ 4772

Last change on this file since 4772 was 4772, checked in by cneumuel, 13 years ago

#1260

  • added LogServiceReader to display log for slave without writing to local files
  • aborted jobs with childjobs now got back to state WaitForChildJob (instead of Offline)
  • lifecyclemanager now knows about available plugins (does not yet work perfectly)
File size: 20.5 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.Collections.Generic;
24using System.Drawing;
25using System.Linq;
26using System.Net;
27using System.Windows.Forms;
28using System.Xml.Serialization;
29using HeuristicLab.Calendar;
30using HeuristicLab.Hive.Slave.Console.SlaveConsoleService;
31using ZedGraph;
32
33namespace HeuristicLab.Hive.Slave.Console {
34
35  #region Delegates
36
37  //delegate to write text in the textbox from another process
38  public delegate void AppendTextDelegate(String message);
39
40  //delegate to remove text in the textbox from another process
41  public delegate void RemoveTextDelegate(int newLength, int maxChars);
42
43  //delegate fired, if a dialog is being closed
44  public delegate void OnDialogClosedDelegate(RecurrentEvent e);
45
46  #endregion
47
48  public partial class HiveSlaveConsole : Form {
49
50    #region Declarations
51    private static bool isfired = false;
52    //the logfilereader
53    private ILogReader logFileReader;
54
55    //communication with the slave
56    private SlaveConsoleCommunicatorClient slaveCommunicator;
57
58    //the timer for refreshing the gui
59    private System.Windows.Forms.Timer refreshTimer;
60
61    //the list of appointments in the calender
62    [XmlArray("Appointments")]
63    [XmlArrayItem("Appointment", typeof(Appointment))]
64    public List<Appointment> onlineTimes = new List<Appointment>();
65
66    public OnDialogClosedDelegate dialogClosedDelegate;
67
68    #endregion
69
70    #region Constructor
71
72    public HiveSlaveConsole() {
73      InitializeComponent();
74      InitTimer();
75      ConnectToSlave();
76      RefreshGui();
77      InitCalender();
78      InitLogFileReader();
79    }
80
81    #endregion
82
83    #region Methods
84
85    #region Client connection
86
87    private void ConnectToSlave() {
88      try {
89        slaveCommunicator = new SlaveConsoleCommunicatorClient();
90
91        slaveCommunicator.GetStatusInfosCompleted += new EventHandler<GetStatusInfosCompletedEventArgs>(slaveCommunicator_GetStatusInfosCompleted);
92        slaveCommunicator.GetCurrentConnectionCompleted += new EventHandler<GetCurrentConnectionCompletedEventArgs>(slaveCommunicator_GetCurrentConnectionCompleted);
93        slaveCommunicator.GetUptimeCalendarCompleted += new EventHandler<GetUptimeCalendarCompletedEventArgs>(slaveCommunicator_GetUptimeCalendarCompleted);
94        slaveCommunicator.SetUptimeCalendarCompleted += new EventHandler<System.ComponentModel.AsyncCompletedEventArgs>(slaveCommunicator_SetUptimeCalendarCompleted);
95      } catch (Exception ex) {
96        ManageFatalException("Connection Error, check if Hive Slave is running!", "Connection Error", ex);
97      }
98    }
99
100    #endregion
101
102    #region Logging
103
104    private void InitLogFileReader() {
105      //logFileReader = new LogFileReader(AppDomain.CurrentDomain.BaseDirectory + @"/Hive.Slave.log");
106      logFileReader = new LogServiceReader(slaveCommunicator);
107      logFileReader.MoreData += new MoreDataHandler(logFileReader_MoreData);
108      logFileReader.Start();
109    }
110
111    private void logFileReader_MoreData(object sender, string newData) {
112      int maxChars = txtLog.MaxLength;
113      if (newData.Length > maxChars) {
114        newData = newData.Remove(0, newData.Length - maxChars);
115      }
116      int newLength = this.txtLog.Text.Length + newData.Length;
117      if (newLength > maxChars) {
118        RemoveText(newLength, maxChars);
119      }
120      AppendText(newData);
121    }
122
123    private void RemoveText(int newLength, int maxChars) {
124      if (this.txtLog.InvokeRequired) {
125        this.txtLog.Invoke(new
126          RemoveTextDelegate(RemoveText), new object[] { newLength, maxChars });
127      } else {
128        this.txtLog.Text = this.txtLog.Text.Remove(0, newLength - (int)maxChars);
129      }
130    }
131
132    private void AppendText(string message) {
133      if (this.txtLog.InvokeRequired) {
134        this.txtLog.Invoke(new
135          AppendTextDelegate(AppendText), new object[] { message });
136      } else {
137        this.txtLog.AppendText(message);
138      }
139    }
140
141    #endregion
142
143    #region Gui Refresh
144
145    private void InitTimer() {
146      refreshTimer = new System.Windows.Forms.Timer();
147      refreshTimer.Interval = 1000;
148      refreshTimer.Tick += new EventHandler(refreshTimer_Tick);
149      refreshTimer.Start();
150    }
151
152    private void RefreshGui() {
153      try {
154        slaveCommunicator.GetStatusInfosAsync();
155      } catch (Exception ex) {
156        ManageFatalException("Connection Error, check if Hive Slave is running!", "Connection Error", ex);
157      }
158    }
159
160    private void UpdateGraph(StatusCommons sc) {
161      ZedGraphControl zgc = new ZedGraphControl();
162      GraphPane myPane = zgc.GraphPane;
163      myPane.GraphObjList.Clear();
164
165      myPane.Title.IsVisible = false;  // no title
166      myPane.Border.IsVisible = false; // no border
167      myPane.Chart.Border.IsVisible = false; // no border around the chart
168      myPane.XAxis.IsVisible = false;  // no x-axis
169      myPane.YAxis.IsVisible = false;  // no y-axis
170      myPane.Legend.IsVisible = false; // no legend
171
172      myPane.Fill.Color = this.BackColor;
173
174      myPane.Chart.Fill.Type = FillType.None;
175      myPane.Fill.Type = FillType.Solid;
176
177      double allProgress = 0;
178      double done = 0;
179
180
181      /*if (jobs.Length == 0)
182      {
183        myPane.AddPieSlice(100, Color.Green, 0.1, "");
184      }
185      else
186      {
187        for (int i = 0; i < jobs.Length; i++)
188        {
189          allProgress += jobs[i].Progress;
190        } */
191
192      //done = allProgress / jobs.Length;
193
194      myPane.AddPieSlice((sc.FreeCores / (double)sc.TotalCores), Color.Red, 0, "");
195      myPane.AddPieSlice(((sc.TotalCores - sc.FreeCores) / (double)sc.TotalCores), Color.Green, 0, "");
196      // }
197      //Hides the slice labels
198      PieItem.Default.LabelType = PieLabelType.None;
199
200      myPane.AxisChange();
201
202      pbGraph.Image = zgc.GetImage();
203    }
204
205    #region Events
206
207    private void refreshTimer_Tick(object sender, EventArgs e) {
208      RefreshGui();
209    }
210
211    #endregion
212
213
214    #endregion
215
216    #region Calendar stuff
217
218    private void InitCalender() {
219      dvOnline.StartDate = DateTime.Now;
220      dvOnline.OnNewAppointment += new EventHandler<NewAppointmentEventArgs>(dvOnline_OnNewAppointment);
221      dvOnline.OnResolveAppointments += new EventHandler<ResolveAppointmentsEventArgs>(dvOnline_OnResolveAppointments);
222
223      //get calender from slave
224      slaveCommunicator.GetUptimeCalendarAsync();
225    }
226
227    private bool CreateAppointment() {
228      DateTime from, to;
229
230      if (!string.IsNullOrEmpty(dtpFrom.Text) && !string.IsNullOrEmpty(dtpTo.Text)) {
231        if (chbade.Checked) {
232          //whole day appointment, only dates are visible
233          if (DateTime.TryParse(dtpFrom.Text, out from) && DateTime.TryParse(dtpTo.Text, out to) && from <= to)
234            onlineTimes.Add(CreateAppointment(from, to.AddDays(1), true));
235          else
236            MessageBox.Show("Incorrect date format", "Schedule Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
237        } else if (!string.IsNullOrEmpty(txttimeFrom.Text) && !string.IsNullOrEmpty(txttimeTo.Text)) {
238          //Timeframe appointment
239          if (DateTime.TryParse(dtpFrom.Text + " " + txttimeFrom.Text, out from) && DateTime.TryParse(dtpTo.Text + " " + txttimeTo.Text, out to) && from < to) {
240            if (from.Date == to.Date)
241              onlineTimes.Add(CreateAppointment(from, to, false));
242            else {
243              //more than 1 day selected
244              while (from.Date != to.Date) {
245                onlineTimes.Add(CreateAppointment(from, new DateTime(from.Year, from.Month, from.Day, to.Hour, to.Minute, 0, 0), false));
246                from = from.AddDays(1);
247              }
248              onlineTimes.Add(CreateAppointment(from, new DateTime(from.Year, from.Month, from.Day, to.Hour, to.Minute, 0, 0), false));
249            }
250          } else
251            MessageBox.Show("Incorrect date format", "Schedule Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
252        }
253        dvOnline.Invalidate();
254        return true;
255      } else {
256        MessageBox.Show("Error in create appointment, please fill out all textboxes!", "Schedule Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
257        return false;
258      }
259    }
260
261    private Appointment CreateAppointment(DateTime startDate, DateTime endDate, bool allDay) {
262      Appointment App = new Appointment();
263      App.StartDate = startDate;
264      App.EndDate = endDate;
265      App.AllDayEvent = allDay;
266      App.BorderColor = Color.Red;
267      App.Locked = true;
268      App.Subject = "Online";
269      App.Recurring = false;
270      return App;
271    }
272
273    private Appointment CreateAppointment(DateTime startDate, DateTime endDate, bool allDay, bool recurring, Guid recurringId) {
274      Appointment App = new Appointment();
275      App.StartDate = startDate;
276      App.EndDate = endDate;
277      App.AllDayEvent = allDay;
278      App.BorderColor = Color.Red;
279      App.Locked = true;
280      App.Subject = "Online";
281      App.Recurring = recurring;
282      App.RecurringId = recurringId;
283      return App;
284    }
285
286    private void DeleteAppointment() {
287      onlineTimes.Remove(dvOnline.SelectedAppointment);
288    }
289
290    private void DeleteRecurringAppointment(Guid recurringId) {
291      onlineTimes.RemoveAll(a => a.RecurringId.ToString() == dvOnline.SelectedAppointment.RecurringId.ToString());
292    }
293
294    private void ChangeRecurrenceAppointment(Guid recurringId) {
295      int hourfrom = int.Parse(txttimeFrom.Text.Substring(0, txttimeFrom.Text.IndexOf(':')));
296      int hourTo = int.Parse(txttimeTo.Text.Substring(0, txttimeTo.Text.IndexOf(':')));
297      List<Appointment> recurringAppointments = onlineTimes.Where(appointment => appointment.RecurringId == recurringId).ToList();
298      recurringAppointments.ForEach(appointment => appointment.StartDate = new DateTime(appointment.StartDate.Year, appointment.StartDate.Month, appointment.StartDate.Day, hourfrom, 0, 0));
299      recurringAppointments.ForEach(appointment => appointment.EndDate = new DateTime(appointment.EndDate.Year, appointment.EndDate.Month, appointment.EndDate.Day, hourTo, 0, 0));
300
301      DeleteRecurringAppointment(recurringId);
302      onlineTimes.AddRange(recurringAppointments);
303    }
304
305    public void DialogClosed(RecurrentEvent e) {
306      CreateDailyRecurrenceAppointments(e.DateFrom, e.DateTo, e.AllDay, e.IncWeeks, e.WeekDays);
307    }
308
309    private void CreateDailyRecurrenceAppointments(DateTime dateFrom, DateTime dateTo, bool allDay, int incWeek, HashSet<DayOfWeek> daysOfWeek) {
310      DateTime incDate = dateFrom;
311      Guid guid = Guid.NewGuid();
312
313      while (incDate.Date <= dateTo.Date) {
314        if (daysOfWeek.Contains(incDate.Date.DayOfWeek))
315          onlineTimes.Add(CreateAppointment(incDate, new DateTime(incDate.Year, incDate.Month, incDate.Day, dateTo.Hour, dateTo.Minute, 0), allDay, true, guid));
316        incDate = incDate.AddDays(1);
317      }
318
319      dvOnline.Invalidate();
320    }
321
322    #region Calendar Events
323
324    private void btbDelete_Click(object sender, EventArgs e) {
325      Appointment selectedAppointment = dvOnline.SelectedAppointment;
326      if (dvOnline.SelectedAppointment != null) {
327        if (!selectedAppointment.Recurring)
328          DeleteAppointment();
329        else {
330          DialogResult res = MessageBox.Show("Delete all events in this series?", "Delete recurrences", MessageBoxButtons.YesNo);
331          if (res != DialogResult.Yes)
332            DeleteAppointment();
333          else
334            DeleteRecurringAppointment(selectedAppointment.RecurringId);
335        }
336      }
337      dvOnline.Invalidate();
338    }
339
340    private void chbade_CheckedChanged(object sender, EventArgs e) {
341      txttimeFrom.Visible = !chbade.Checked;
342      txttimeTo.Visible = !chbade.Checked;
343    }
344
345    private void dvOnline_OnSelectionChanged(object sender, EventArgs e) {
346      //btCreate.Enabled = true;
347      if (dvOnline.Selection == SelectionType.DateRange) {
348        dtpFrom.Text = dvOnline.SelectionStart.ToShortDateString();
349        dtpTo.Text = dvOnline.SelectionEnd.Date.ToShortDateString();
350        txttimeFrom.Text = dvOnline.SelectionStart.ToShortTimeString();
351        txttimeTo.Text = dvOnline.SelectionEnd.ToShortTimeString();
352
353        btCreate.Text = "Save";
354      }
355
356      if (dvOnline.Selection == SelectionType.Appointment) {
357
358        dtpFrom.Text = dvOnline.SelectedAppointment.StartDate.ToShortDateString();
359        dtpTo.Text = dvOnline.SelectedAppointment.EndDate.ToShortDateString();
360        txttimeFrom.Text = dvOnline.SelectedAppointment.StartDate.ToShortTimeString();
361        txttimeTo.Text = dvOnline.SelectedAppointment.EndDate.ToShortTimeString();
362
363        if (dvOnline.SelectedAppointment.Recurring)
364          //btCreate.Enabled = false;
365          //also change the caption of the save button
366          btCreate.Text = "Save changes";
367      }
368
369      if (dvOnline.Selection == SelectionType.None) {
370        //also change the caption of the save button
371        btCreate.Text = "Save";
372      }
373
374    }
375
376    private void mcOnline_DateChanged(object sender, DateRangeEventArgs e) {
377      dvOnline.StartDate = mcOnline.SelectionStart;
378    }
379
380    private void btCreate_Click(object sender, EventArgs e) {
381      if (dvOnline.Selection != SelectionType.Appointment) {
382        CreateAppointment();
383      } else {
384        //now we want to change an existing appointment
385        if (!dvOnline.SelectedAppointment.Recurring) {
386          if (CreateAppointment())
387            DeleteAppointment();
388        } else {
389          //change recurring appointment
390          //check, if only selected appointment has to change or whole recurrence
391          DialogResult res = MessageBox.Show("Change all events in this series?", "Change recurrences", MessageBoxButtons.YesNo);
392          if (res != DialogResult.Yes) {
393            if (CreateAppointment())
394              DeleteAppointment();
395          } else
396            ChangeRecurrenceAppointment(dvOnline.SelectedAppointment.RecurringId);
397        }
398      }
399      dvOnline.Invalidate();
400    }
401
402    private void btnRecurrence_Click(object sender, EventArgs e) {
403      Recurrence recurrence = new Recurrence();
404      recurrence.dialogClosedDelegate = new OnDialogClosedDelegate(this.DialogClosed);
405      recurrence.Show();
406    }
407
408    private void btnSaveCal_Click(object sender, EventArgs e) {
409      slaveCommunicator.SetUptimeCalendarAsync(onlineTimes);
410    }
411
412    private void dvOnline_OnResolveAppointments(object sender, ResolveAppointmentsEventArgs e) {
413      List<Appointment> Apps = new List<Appointment>();
414
415      foreach (Appointment m_App in onlineTimes)
416        if ((m_App.StartDate >= e.StartDate) &&
417            (m_App.StartDate <= e.EndDate))
418          Apps.Add(m_App);
419      e.Appointments = Apps;
420    }
421
422    private void btnUpdateCalender_Click(object sender, EventArgs e) {
423      slaveCommunicator.GetUptimeCalendarAsync();
424    }
425
426    private void dvOnline_OnNewAppointment(object sender, NewAppointmentEventArgs e) {
427      Appointment Appointment = new Appointment();
428
429      Appointment.StartDate = e.StartDate;
430      Appointment.EndDate = e.EndDate;
431
432      onlineTimes.Add(Appointment);
433    }
434
435    #endregion
436
437    #endregion
438
439    #region Slave communicator events
440
441    void slaveCommunicator_SetUptimeCalendarCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e) {
442      if (e.Error == null) {
443        MessageBox.Show("Calendar successfully saved!", "Calender", MessageBoxButtons.OK, MessageBoxIcon.Information);
444      } else {
445        MessageBox.Show("Error saving calender \n" + e.Error.ToString(), "Calender", MessageBoxButtons.OK, MessageBoxIcon.Error);
446      }
447    }
448
449    void slaveCommunicator_GetUptimeCalendarCompleted(object sender, GetUptimeCalendarCompletedEventArgs e) {
450      if (e.Error == null) {
451        if (e.Result != null) {
452          onlineTimes = e.Result.ToList<Appointment>();
453          onlineTimes.ForEach(a => a.BorderColor = Color.Red);
454          dvOnline.Invalidate();
455
456        } else {
457          onlineTimes = new List<Appointment>();
458        }
459      }
460    }
461
462    private void slaveCommunicator_GetCurrentConnectionCompleted(object sender, GetCurrentConnectionCompletedEventArgs e) {
463      if (e.Error == null) {
464        ConnectionContainer curConnection = e.Result;
465        tbIPAdress.Text = curConnection.IPAdress;
466      } else {
467        ManageFatalException("Connection Error, check if Hive Slave is running!", "Connection Error", null);
468      }
469    }
470
471    private void slaveCommunicator_GetStatusInfosCompleted(object sender, GetStatusInfosCompletedEventArgs e) {
472      if (e.Error == null) {
473        StatusCommons sc = e.Result;
474
475        lbGuid.Text = sc.ClientGuid.ToString();
476        lbConnectionStatus.Text = sc.Status.ToString();
477        lbJobdone.Text = sc.JobsDone.ToString();
478        lbJobsAborted.Text = sc.JobsAborted.ToString();
479        lbJobsFetched.Text = sc.JobsFetched.ToString();
480
481        this.Text = "Slave Console (" + sc.Status.ToString() + ")";
482
483        ListViewItem curJobStatusItem;
484
485        if (sc.Jobs != null) {
486          lvJobDetail.Items.Clear();
487          double progress;
488          foreach (JobStatus curJob in sc.Jobs) {
489            curJobStatusItem = new ListViewItem(curJob.JobId.ToString());
490            curJobStatusItem.SubItems.Add(curJob.Since.ToString());
491            lvJobDetail.Items.Add(curJobStatusItem);
492          }
493          lvJobDetail.Sort();
494        }
495
496        UpdateGraph(sc);
497
498        if (sc.Status == NetworkEnumWcfConnState.Connected) {
499          btConnect.Enabled = false;
500          btnDisconnect.Enabled = true;
501          lbCs.Text = sc.ConnectedSince.ToString();
502          slaveCommunicator.GetCurrentConnectionAsync();
503        } else if (sc.Status == NetworkEnumWcfConnState.Disconnected) {
504          btConnect.Enabled = true;
505          btnDisconnect.Enabled = false;
506          lbCs.Text = String.Empty;
507        } else if (sc.Status == NetworkEnumWcfConnState.Failed) {
508          btConnect.Enabled = true;
509          btnDisconnect.Enabled = false;
510          lbCs.Text = String.Empty;
511        }
512
513        slaveCommunicator.GetCurrentConnection();
514      } else {
515        ManageFatalException("Connection Error, check if Hive Slave is running!", "Connection Error", null);
516      }
517    }
518
519    #endregion
520
521    #region Exception
522    private void ManageFatalException(string body, string caption, Exception e) {
523      if (!isfired) {
524        isfired = true;
525        refreshTimer.Stop();
526        DialogResult res = MessageBox.Show(body, caption, MessageBoxButtons.OK, MessageBoxIcon.Error);
527        if (res == DialogResult.OK)
528          this.Close();
529      }
530    }
531
532    #endregion
533
534    #endregion
535
536    #region GUI Events
537
538    private void btConnect_Click(object sender, EventArgs e) {
539      IPAddress ipAdress;
540      ConnectionContainer cc = new ConnectionContainer();
541      if (IPAddress.TryParse(tbIPAdress.Text, out ipAdress)) {
542        cc.IPAdress = tbIPAdress.Text;
543        slaveCommunicator.SetConnectionAsync(cc);
544      } else {
545        MessageBox.Show("IP Adress and/or Port Error", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
546      }
547    }
548
549    private void btnDisconnect_Click(object sender, EventArgs e) {
550      //slaveCommunicator.DisconnectAsync(); // [chn] todo
551    }
552
553    private void btn_slaveShutdown_Click(object sender, EventArgs e) {
554      DialogResult res = MessageBox.Show("Do you really want to shutdown the Hive Slace?", "Hive Slave Console", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
555      if (res == DialogResult.Yes) {
556        logFileReader.Stop();
557        slaveCommunicator.ShutdownClient();
558        this.Close();
559      }
560    }
561
562    private void Connection_KeyPress(object sender, KeyPressEventArgs e) {
563      if (e.KeyChar == (char)Keys.Return)
564        btConnect_Click(null, null);
565    }
566
567    #endregion
568
569
570
571  }
572}
Note: See TracBrowser for help on using the repository browser.