Free cookie consent management tool by TermsFeed Policy Generator

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

Last change on this file since 5511 was 5000, checked in by cneumuel, 14 years ago

#1260

  • custom configuration file is now deployed on slaves
  • made plugin distribution process more robust
  • fixed bug: slave assemblies are required in each sandbox appdomain
  • cleaned up some configuration elements in slave console client
  • fixed wrong path for locally persisted jobs
File size: 18.8 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.GetUptimeCalendarCompleted += new EventHandler<GetUptimeCalendarCompletedEventArgs>(slaveCommunicator_GetUptimeCalendarCompleted);
93        slaveCommunicator.SetUptimeCalendarCompleted += new EventHandler<System.ComponentModel.AsyncCompletedEventArgs>(slaveCommunicator_SetUptimeCalendarCompleted);
94      } catch (Exception ex) {
95        ManageFatalException("Connection Error, check if Hive Slave is running!", "Connection Error", ex);
96      }
97    }
98
99    #endregion
100
101    #region Logging
102
103    private void InitLogFileReader() {
104      //logFileReader = new LogFileReader(AppDomain.CurrentDomain.BaseDirectory + @"/Hive.Slave.log");
105      logFileReader = new LogServiceReader();
106      logFileReader.MoreData += new MoreDataHandler(logFileReader_MoreData);
107      logFileReader.Start();
108    }
109
110    private void logFileReader_MoreData(object sender, string newData) {
111      int maxChars = txtLog.MaxLength;
112      if (newData.Length > maxChars) {
113        newData = newData.Remove(0, newData.Length - maxChars);
114      }
115      int newLength = this.txtLog.Text.Length + newData.Length;
116      if (newLength > maxChars) {
117        RemoveText(newLength, maxChars);
118      }
119      AppendText(newData);
120    }
121
122    private void RemoveText(int newLength, int maxChars) {
123      if (this.txtLog.InvokeRequired) {
124        this.txtLog.Invoke(new
125          RemoveTextDelegate(RemoveText), new object[] { newLength, maxChars });
126      } else {
127        this.txtLog.Text = this.txtLog.Text.Remove(0, newLength - (int)maxChars);
128      }
129    }
130
131    private void AppendText(string message) {
132      if (this.txtLog.InvokeRequired) {
133        this.txtLog.Invoke(new
134          AppendTextDelegate(AppendText), new object[] { message });
135      } else {
136        this.txtLog.AppendText(message);
137      }
138    }
139
140    #endregion
141
142    #region Gui Refresh
143
144    private void InitTimer() {
145      refreshTimer = new System.Windows.Forms.Timer();
146      refreshTimer.Interval = 1000;
147      refreshTimer.Tick += new EventHandler(refreshTimer_Tick);
148      refreshTimer.Start();
149    }
150
151    private void RefreshGui() {
152      try {
153        slaveCommunicator.GetStatusInfosAsync();
154      } catch (Exception ex) {
155        ManageFatalException("Connection Error, check if Hive Slave is running!", "Connection Error", ex);
156      }
157    }
158
159    private void UpdateGraph(StatusCommons sc) {
160      ZedGraphControl zgc = new ZedGraphControl();
161      GraphPane myPane = zgc.GraphPane;
162      myPane.GraphObjList.Clear();
163
164      myPane.Title.IsVisible = false;  // no title
165      myPane.Border.IsVisible = false; // no border
166      myPane.Chart.Border.IsVisible = false; // no border around the chart
167      myPane.XAxis.IsVisible = false;  // no x-axis
168      myPane.YAxis.IsVisible = false;  // no y-axis
169      myPane.Legend.IsVisible = false; // no legend
170
171      myPane.Fill.Color = this.BackColor;
172
173      myPane.Chart.Fill.Type = FillType.None;
174      myPane.Fill.Type = FillType.Solid;
175
176      double allProgress = 0;
177      double done = 0;
178
179
180      /*if (jobs.Length == 0)
181      {
182        myPane.AddPieSlice(100, Color.Green, 0.1, "");
183      }
184      else
185      {
186        for (int i = 0; i < jobs.Length; i++)
187        {
188          allProgress += jobs[i].Progress;
189        } */
190
191      //done = allProgress / jobs.Length;
192
193      myPane.AddPieSlice((sc.FreeCores / (double)sc.TotalCores), Color.Red, 0, "");
194      myPane.AddPieSlice(((sc.TotalCores - sc.FreeCores) / (double)sc.TotalCores), Color.Green, 0, "");
195      // }
196      //Hides the slice labels
197      PieItem.Default.LabelType = PieLabelType.None;
198
199      myPane.AxisChange();
200
201      pbGraph.Image = zgc.GetImage();
202    }
203
204    #region Events
205
206    private void refreshTimer_Tick(object sender, EventArgs e) {
207      RefreshGui();
208    }
209
210    #endregion
211
212
213    #endregion
214
215    #region Calendar stuff
216
217    private void InitCalender() {
218      dvOnline.StartDate = DateTime.Now;
219      dvOnline.OnNewAppointment += new EventHandler<NewAppointmentEventArgs>(dvOnline_OnNewAppointment);
220      dvOnline.OnResolveAppointments += new EventHandler<ResolveAppointmentsEventArgs>(dvOnline_OnResolveAppointments);
221
222      //get calender from slave
223      slaveCommunicator.GetUptimeCalendarAsync();
224    }
225
226    private bool CreateAppointment() {
227      DateTime from, to;
228
229      if (!string.IsNullOrEmpty(dtpFrom.Text) && !string.IsNullOrEmpty(dtpTo.Text)) {
230        if (chbade.Checked) {
231          //whole day appointment, only dates are visible
232          if (DateTime.TryParse(dtpFrom.Text, out from) && DateTime.TryParse(dtpTo.Text, out to) && from <= to)
233            onlineTimes.Add(CreateAppointment(from, to.AddDays(1), true));
234          else
235            MessageBox.Show("Incorrect date format", "Schedule Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
236        } else if (!string.IsNullOrEmpty(txttimeFrom.Text) && !string.IsNullOrEmpty(txttimeTo.Text)) {
237          //Timeframe appointment
238          if (DateTime.TryParse(dtpFrom.Text + " " + txttimeFrom.Text, out from) && DateTime.TryParse(dtpTo.Text + " " + txttimeTo.Text, out to) && from < to) {
239            if (from.Date == to.Date)
240              onlineTimes.Add(CreateAppointment(from, to, false));
241            else {
242              //more than 1 day selected
243              while (from.Date != to.Date) {
244                onlineTimes.Add(CreateAppointment(from, new DateTime(from.Year, from.Month, from.Day, to.Hour, to.Minute, 0, 0), false));
245                from = from.AddDays(1);
246              }
247              onlineTimes.Add(CreateAppointment(from, new DateTime(from.Year, from.Month, from.Day, to.Hour, to.Minute, 0, 0), false));
248            }
249          } else
250            MessageBox.Show("Incorrect date format", "Schedule Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
251        }
252        dvOnline.Invalidate();
253        return true;
254      } else {
255        MessageBox.Show("Error in create appointment, please fill out all textboxes!", "Schedule Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
256        return false;
257      }
258    }
259
260    private Appointment CreateAppointment(DateTime startDate, DateTime endDate, bool allDay) {
261      Appointment App = new Appointment();
262      App.StartDate = startDate;
263      App.EndDate = endDate;
264      App.AllDayEvent = allDay;
265      App.BorderColor = Color.Red;
266      App.Locked = true;
267      App.Subject = "Online";
268      App.Recurring = false;
269      return App;
270    }
271
272    private Appointment CreateAppointment(DateTime startDate, DateTime endDate, bool allDay, bool recurring, Guid recurringId) {
273      Appointment App = new Appointment();
274      App.StartDate = startDate;
275      App.EndDate = endDate;
276      App.AllDayEvent = allDay;
277      App.BorderColor = Color.Red;
278      App.Locked = true;
279      App.Subject = "Online";
280      App.Recurring = recurring;
281      App.RecurringId = recurringId;
282      return App;
283    }
284
285    private void DeleteAppointment() {
286      onlineTimes.Remove(dvOnline.SelectedAppointment);
287    }
288
289    private void DeleteRecurringAppointment(Guid recurringId) {
290      onlineTimes.RemoveAll(a => a.RecurringId.ToString() == dvOnline.SelectedAppointment.RecurringId.ToString());
291    }
292
293    private void ChangeRecurrenceAppointment(Guid recurringId) {
294      int hourfrom = int.Parse(txttimeFrom.Text.Substring(0, txttimeFrom.Text.IndexOf(':')));
295      int hourTo = int.Parse(txttimeTo.Text.Substring(0, txttimeTo.Text.IndexOf(':')));
296      List<Appointment> recurringAppointments = onlineTimes.Where(appointment => appointment.RecurringId == recurringId).ToList();
297      recurringAppointments.ForEach(appointment => appointment.StartDate = new DateTime(appointment.StartDate.Year, appointment.StartDate.Month, appointment.StartDate.Day, hourfrom, 0, 0));
298      recurringAppointments.ForEach(appointment => appointment.EndDate = new DateTime(appointment.EndDate.Year, appointment.EndDate.Month, appointment.EndDate.Day, hourTo, 0, 0));
299
300      DeleteRecurringAppointment(recurringId);
301      onlineTimes.AddRange(recurringAppointments);
302    }
303
304    public void DialogClosed(RecurrentEvent e) {
305      CreateDailyRecurrenceAppointments(e.DateFrom, e.DateTo, e.AllDay, e.IncWeeks, e.WeekDays);
306    }
307
308    private void CreateDailyRecurrenceAppointments(DateTime dateFrom, DateTime dateTo, bool allDay, int incWeek, HashSet<DayOfWeek> daysOfWeek) {
309      DateTime incDate = dateFrom;
310      Guid guid = Guid.NewGuid();
311
312      while (incDate.Date <= dateTo.Date) {
313        if (daysOfWeek.Contains(incDate.Date.DayOfWeek))
314          onlineTimes.Add(CreateAppointment(incDate, new DateTime(incDate.Year, incDate.Month, incDate.Day, dateTo.Hour, dateTo.Minute, 0), allDay, true, guid));
315        incDate = incDate.AddDays(1);
316      }
317
318      dvOnline.Invalidate();
319    }
320
321    #region Calendar Events
322
323    private void btbDelete_Click(object sender, EventArgs e) {
324      Appointment selectedAppointment = dvOnline.SelectedAppointment;
325      if (dvOnline.SelectedAppointment != null) {
326        if (!selectedAppointment.Recurring)
327          DeleteAppointment();
328        else {
329          DialogResult res = MessageBox.Show("Delete all events in this series?", "Delete recurrences", MessageBoxButtons.YesNo);
330          if (res != DialogResult.Yes)
331            DeleteAppointment();
332          else
333            DeleteRecurringAppointment(selectedAppointment.RecurringId);
334        }
335      }
336      dvOnline.Invalidate();
337    }
338
339    private void chbade_CheckedChanged(object sender, EventArgs e) {
340      txttimeFrom.Visible = !chbade.Checked;
341      txttimeTo.Visible = !chbade.Checked;
342    }
343
344    private void dvOnline_OnSelectionChanged(object sender, EventArgs e) {
345      //btCreate.Enabled = true;
346      if (dvOnline.Selection == SelectionType.DateRange) {
347        dtpFrom.Text = dvOnline.SelectionStart.ToShortDateString();
348        dtpTo.Text = dvOnline.SelectionEnd.Date.ToShortDateString();
349        txttimeFrom.Text = dvOnline.SelectionStart.ToShortTimeString();
350        txttimeTo.Text = dvOnline.SelectionEnd.ToShortTimeString();
351
352        btCreate.Text = "Save";
353      }
354
355      if (dvOnline.Selection == SelectionType.Appointment) {
356
357        dtpFrom.Text = dvOnline.SelectedAppointment.StartDate.ToShortDateString();
358        dtpTo.Text = dvOnline.SelectedAppointment.EndDate.ToShortDateString();
359        txttimeFrom.Text = dvOnline.SelectedAppointment.StartDate.ToShortTimeString();
360        txttimeTo.Text = dvOnline.SelectedAppointment.EndDate.ToShortTimeString();
361
362        if (dvOnline.SelectedAppointment.Recurring)
363          //btCreate.Enabled = false;
364          //also change the caption of the save button
365          btCreate.Text = "Save changes";
366      }
367
368      if (dvOnline.Selection == SelectionType.None) {
369        //also change the caption of the save button
370        btCreate.Text = "Save";
371      }
372
373    }
374
375    private void mcOnline_DateChanged(object sender, DateRangeEventArgs e) {
376      dvOnline.StartDate = mcOnline.SelectionStart;
377    }
378
379    private void btCreate_Click(object sender, EventArgs e) {
380      if (dvOnline.Selection != SelectionType.Appointment) {
381        CreateAppointment();
382      } else {
383        //now we want to change an existing appointment
384        if (!dvOnline.SelectedAppointment.Recurring) {
385          if (CreateAppointment())
386            DeleteAppointment();
387        } else {
388          //change recurring appointment
389          //check, if only selected appointment has to change or whole recurrence
390          DialogResult res = MessageBox.Show("Change all events in this series?", "Change recurrences", MessageBoxButtons.YesNo);
391          if (res != DialogResult.Yes) {
392            if (CreateAppointment())
393              DeleteAppointment();
394          } else
395            ChangeRecurrenceAppointment(dvOnline.SelectedAppointment.RecurringId);
396        }
397      }
398      dvOnline.Invalidate();
399    }
400
401    private void btnRecurrence_Click(object sender, EventArgs e) {
402      Recurrence recurrence = new Recurrence();
403      recurrence.dialogClosedDelegate = new OnDialogClosedDelegate(this.DialogClosed);
404      recurrence.Show();
405    }
406
407    private void btnSaveCal_Click(object sender, EventArgs e) {
408      slaveCommunicator.SetUptimeCalendarAsync(onlineTimes);
409    }
410
411    private void dvOnline_OnResolveAppointments(object sender, ResolveAppointmentsEventArgs e) {
412      List<Appointment> Apps = new List<Appointment>();
413
414      foreach (Appointment m_App in onlineTimes)
415        if ((m_App.StartDate >= e.StartDate) &&
416            (m_App.StartDate <= e.EndDate))
417          Apps.Add(m_App);
418      e.Appointments = Apps;
419    }
420
421    private void btnUpdateCalender_Click(object sender, EventArgs e) {
422      slaveCommunicator.GetUptimeCalendarAsync();
423    }
424
425    private void dvOnline_OnNewAppointment(object sender, NewAppointmentEventArgs e) {
426      Appointment Appointment = new Appointment();
427
428      Appointment.StartDate = e.StartDate;
429      Appointment.EndDate = e.EndDate;
430
431      onlineTimes.Add(Appointment);
432    }
433
434    #endregion
435
436    #endregion
437
438    #region Slave communicator events
439
440    void slaveCommunicator_SetUptimeCalendarCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e) {
441      if (e.Error == null) {
442        MessageBox.Show("Calendar successfully saved!", "Calender", MessageBoxButtons.OK, MessageBoxIcon.Information);
443      } else {
444        MessageBox.Show("Error saving calender \n" + e.Error.ToString(), "Calender", MessageBoxButtons.OK, MessageBoxIcon.Error);
445      }
446    }
447
448    void slaveCommunicator_GetUptimeCalendarCompleted(object sender, GetUptimeCalendarCompletedEventArgs e) {
449      if (e.Error == null) {
450        if (e.Result != null) {
451          onlineTimes = e.Result.ToList<Appointment>();
452          onlineTimes.ForEach(a => a.BorderColor = Color.Red);
453          dvOnline.Invalidate();
454
455        } else {
456          onlineTimes = new List<Appointment>();
457        }
458      }
459    }
460
461    private void slaveCommunicator_GetStatusInfosCompleted(object sender, GetStatusInfosCompletedEventArgs e) {
462      if (e.Error == null) {
463        StatusCommons sc = e.Result;
464
465        lbGuid.Text = sc.ClientGuid.ToString();
466        lbConnectionStatus.Text = sc.Status.ToString();
467        lbJobdone.Text = sc.JobsDone.ToString();
468        lbJobsAborted.Text = sc.JobsAborted.ToString();
469        lbJobsFetched.Text = sc.JobsFetched.ToString();
470
471        this.Text = "Slave Console (" + sc.Status.ToString() + ")";
472
473        ListViewItem curJobStatusItem;
474
475        if (sc.Jobs != null) {
476          lvJobDetail.Items.Clear();
477          double progress;
478          foreach (JobStatus curJob in sc.Jobs) {
479            curJobStatusItem = new ListViewItem(curJob.JobId.ToString());
480            curJobStatusItem.SubItems.Add(curJob.Since.ToString());
481            lvJobDetail.Items.Add(curJobStatusItem);
482          }
483          lvJobDetail.Sort();
484        }
485
486        UpdateGraph(sc);
487      } else {
488        ManageFatalException("Connection Error, check if Hive Slave is running!", "Connection Error", null);
489      }
490    }
491
492    #endregion
493
494    #region Exception
495    private void ManageFatalException(string body, string caption, Exception e) {
496      if (!isfired) {
497        isfired = true;
498        refreshTimer.Stop();
499       
500        DialogResult res;
501        if (e != null) {
502          res = MessageBox.Show(body + "\n" + e.Message + ": " + e.StackTrace, caption, MessageBoxButtons.OK, MessageBoxIcon.Error);
503        } else {
504          res = MessageBox.Show(body + " (no exception available)", caption, MessageBoxButtons.OK, MessageBoxIcon.Error);
505        }
506        if (res == DialogResult.OK)
507          this.Close();
508      }
509    }
510
511    #endregion
512
513    #endregion
514
515    #region GUI Events
516
517
518    private void btn_slaveShutdown_Click(object sender, EventArgs e) {
519      DialogResult res = MessageBox.Show("Do you really want to shutdown the Hive Slace?", "Hive Slave Console", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
520      if (res == DialogResult.Yes) {
521        logFileReader.Stop();
522        slaveCommunicator.ShutdownClient();
523        this.Close();
524      }
525    }
526
527    #endregion
528
529
530
531  }
532}
Note: See TracBrowser for help on using the repository browser.