Changeset 15792


Ignore:
Timestamp:
02/20/18 14:32:16 (18 months ago)
Author:
jzenisek
Message:

#2839 preliminary integration of several HiveAdministrator related improvements from #2877 (full merge pending)

  • slaves and slave groups are sorted by name
  • slave state is indicated by different colors
  • number of contained slaves is shown for each group
  • CPU utilization is shown for each calculating slave
  • last heartbeat date is shown for each offline slave
Location:
branches/2839_HiveProjectManagement
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • branches/2839_HiveProjectManagement/HeuristicLab.Clients.Hive.Administrator/3.3/Views/ProjectsView.cs

    r15777 r15792  
    250250      if (result == DialogResult.Yes) {
    251251        await SecurityExceptionUtil.TryAsyncAndReportSecurityExceptions(
    252           action: () => RemoveProject(selectedProject),
     252          action: () => {
     253            RemoveProject(selectedProject); 
     254          },
    253255          finallyCallback: () => {
    254256            removeButton.Enabled = true;
     
    358360
    359361    #region Helpers
    360     private void ResetTreeNodes(TreeNodeCollection nodes, Color c1, Color c2, bool resetText) {
    361       foreach (TreeNode n in nodes) {
    362         var pro = ((Project)n.Tag);
    363         if (n.BackColor.Equals(c1)) {
    364           n.BackColor = c2;
    365         }
    366         if (resetText) {
    367           n.Text = pro.Name;
    368 
    369           if (pro.Id == Guid.Empty) {
    370             n.Text += " [not stored]";
    371           } else if (pro.Modified) {
    372             n.Text += " [changes not stored]";
    373           }
    374         }
    375         if (n.Nodes.Count > 0) {
    376           ResetTreeNodes(n.Nodes, c1, c2, resetText);
    377         }
    378       }
    379     }
    380 
    381     private void ChangeSelectedProject(Project project) {
    382       projectView.Content = project;
    383       projectPermissionsView.Content = project;
    384       projectResourcesView.Content = project;
    385 
    386       bool locked = project == null || (project != null && project.Id == Guid.Empty);
    387       addButton.Enabled = !locked;
    388       projectPermissionsView.Locked = locked;
    389       projectResourcesView.Locked = locked;
    390       selectedProject = project;
    391     }
    392 
    393     private void ChangeSelectedProjectNode(TreeNode projectNode) {
    394       if (projectNode == null) return;
    395       SelectedProject = (Project)projectNode.Tag;
    396       ResetTreeNodes(projectsTreeView.Nodes, selectedColor, Color.Transparent, true);
    397       projectNode.BackColor = selectedColor;
    398       projectNode.Text += " [selected]";
    399     }
    400 
    401362    private void BuildProjectTree(IEnumerable<Project> projects) {
    402363      projectsTreeView.Nodes.Clear();
     
    407368        .Where(x => x.ParentProjectId.HasValue
    408369        && !projects.Select(y => y.Id).Contains(x.ParentProjectId.Value)));
    409             mainProjects.UnionWith(parentedMainProjects);
     370      mainProjects.UnionWith(parentedMainProjects);
    410371      var subProbjects = new HashSet<Project>(projects.Except(mainProjects));
    411372
     
    416377      TreeNode currentNode = null;
    417378      Project currentProject = null;
    418      
     379
    419380      while (stack.Any()) {
    420381        var newProject = stack.Pop();
    421382        var newNode = new TreeNode(newProject.Name) { Tag = newProject };
    422 
    423         if (newProject.Id == Guid.Empty) {
    424           newNode.Text += " [not stored]";
    425         } else if(newProject.Modified) {
    426           newNode.Text += " [changes not stored]";
    427         }
     383        StyleTreeNode(newNode, newProject);
     384     
    428385        if (selectedProject == null) {
    429386          SelectedProject = newProject;
     
    467424    }
    468425
     426    private void StyleTreeNode(TreeNode n, Project p) {
     427      n.Text = p.Name;
     428      n.BackColor = Color.Transparent;
     429      n.ForeColor = Color.Black;
     430
     431      if (p.Id == Guid.Empty) {
     432        n.Text += " [not stored]";
     433      } else if (p.Modified) {
     434        n.Text += " [changes not stored]";
     435      }
     436    }
     437
     438    private void ResetTreeNodes(TreeNodeCollection nodes) {
     439      foreach (TreeNode n in nodes) {
     440        StyleTreeNode(n, (Project)n.Tag);
     441        if (n.Nodes.Count > 0) {
     442          ResetTreeNodes(n.Nodes);
     443        }
     444      }
     445    }
     446
     447    private void ChangeSelectedProject(Project project) {
     448      projectView.Content = project;
     449      projectPermissionsView.Content = project;
     450      projectResourcesView.Content = project;
     451
     452      bool locked = project == null || (project != null && project.Id == Guid.Empty);
     453      addButton.Enabled = !locked;
     454      projectPermissionsView.Locked = locked;
     455      projectResourcesView.Locked = locked;
     456      selectedProject = project;
     457    }
     458
     459    private void ChangeSelectedProjectNode(TreeNode projectNode) {
     460      if (projectNode == null) return;
     461      SelectedProject = (Project)projectNode.Tag;
     462      ResetTreeNodes(projectsTreeView.Nodes);
     463      projectNode.BackColor = selectedColor;
     464      projectNode.Text += " [selected]";
     465    }
     466
    469467    private void UpdateProjects() {
    470468      try {
     
    480478
    481479      try {
    482         if(project.Id != Guid.Empty) HiveAdminClient.Delete(project);
    483         Content.Remove(selectedProject);
     480        if (project.Id != Guid.Empty) {
     481          var projectsToSave = Content.Where(x => x.Id == Guid.Empty || x.Modified);
     482          foreach (var p in projectsToSave)
     483            p.Store();
     484          HiveAdminClient.Delete(project);
     485          UpdateProjects();
     486        } else {
     487          Content.Remove(project);
     488        }
    484489      } catch (AnonymousUserException) {
    485490        ShowHiveInformationDialog();
  • branches/2839_HiveProjectManagement/HeuristicLab.Clients.Hive.Administrator/3.3/Views/ResourcesView.cs

    r15777 r15792  
    4545    private readonly Color changedColor = Color.FromArgb(255, 87, 191, 193); // #57bfc1
    4646    private readonly Color selectedColor = Color.FromArgb(255, 240, 194, 59); // #f0c23b
     47    private readonly Color calculatingColor = Color.FromArgb(255, 58, 114, 35); // #3a7223
     48    private readonly Color offlineColor = Color.FromArgb(255, 187, 36, 36); // #bb2424
    4749
    4850    private Resource selectedResource = null;
     
    215217      };
    216218
     219      HiveAdminClient.Instance.UpdateResourceGenealogy(Content);
    217220      SelectedResource = group;
    218221      Content.Add(group);
     
    252255      if (result == DialogResult.Yes) {
    253256        await SecurityExceptionUtil.TryAsyncAndReportSecurityExceptions(
    254           action: () => RemoveResource(selectedResource),
    255           finallyCallback: () => {
     257          action: () => {
     258            RemoveResource(selectedResource);
     259          },
     260          finallyCallback: () => {
    256261            btnRemoveGroup.Enabled = true;
    257262          });
     
    279284    private void treeSlaveGroup_MouseDown(object sender, MouseEventArgs e) {
    280285      var node = treeView.GetNodeAt(e.Location);
    281       if(node != null && node.Name != ungroupedGroupName) ChangeSelectedResourceNode(node);
     286      if(node != null && !node.Text.StartsWith(ungroupedGroupName)) ChangeSelectedResourceNode(node);
    282287    }
    283288
     
    325330      }
    326331
     332      HiveAdminClient.Instance.UpdateResourceGenealogy(Content);
    327333      SelectedResource = sourceResource;
    328334      OnContentChanged();
     
    350356        || sourceNode == targetNode
    351357        || !HiveAdminClient.Instance.CheckParentChange(sourceResource, targetResource)
    352         || (targetNode != null && (targetNode.Text == ungroupedGroupName || targetNode.Parent != null && targetNode.Parent.Text == ungroupedGroupName))) {
     358        || (targetNode != null && (targetNode.Text.StartsWith(ungroupedGroupName) || targetNode.Parent != null && targetNode.Parent.Text.StartsWith(ungroupedGroupName)))) {
    353359        e.Effect = DragDropEffects.None;
    354360      }
     
    361367
    362368    #region Helpers
    363     private void ResetTreeNodes(TreeNodeCollection nodes, Color c1, Color c2, bool resetText) {
    364       foreach (TreeNode n in nodes) {
    365         var res = ((Resource)n.Tag);
    366         if (n.BackColor.Equals(c1)) {
    367           n.BackColor = c2;
    368         }
    369         if (resetText) {
    370           n.Text = res.Name;
    371 
    372           if (res.Id == Guid.Empty && res.Name != ungroupedGroupName) {
    373             n.Text += " [not stored]";
    374           } else if (res.Modified && res.Name != ungroupedGroupName) {
    375             n.Text += " [changes not stored]";
    376           }
    377         }
    378         if (n.Nodes.Count > 0) {
    379           ResetTreeNodes(n.Nodes, c1, c2, resetText);
    380         }
    381       }
    382     }
    383 
    384369    private void BuildResourceTree(IEnumerable<Resource> resources) {
    385370      treeView.Nodes.Clear();
     
    400385      Resource currentResource = null;
    401386
    402       while(stack.Any()) {
     387      while (stack.Any()) {
    403388        var newResource = stack.Pop();
    404389        var newNode = new TreeNode(newResource.Name) { Tag = newResource };
    405 
    406         if(newResource.Id == Guid.Empty) {
    407           newNode.Text += " [not stored]";
    408         } else if(newResource.Modified) {
    409           newNode.Text += " [changes not stored]";
    410         }
     390        StyleTreeNode(newNode, newResource, resources);
     391
    411392        if (selectedResource == null) {
    412393          SelectedResource = newResource;
     
    426407        }
    427408
    428         if(currentNode == null) {
     409        if (currentNode == null) {
    429410          treeView.Nodes.Add(newNode);
    430411        } else {
     
    432413        }
    433414
    434         if(newResource is Slave) {
    435           newNode.ImageIndex = slaveImageIndex;
    436         } else {
    437           newNode.ImageIndex = slaveGroupImageIndex;
    438 
     415        if (newResource is SlaveGroup) {
    439416          var childResources = subResources.Where(x => x.ParentResourceId == newResource.Id);
    440           if(childResources.Any()) {
    441             foreach(var resource in childResources.OrderByDescending(x => x.Name)) {
     417          if (childResources.Any()) {
     418            foreach (var resource in childResources.OrderByDescending(x => x.Name)) {
    442419              subResources.Remove(resource);
    443420              stack.Push(resource);
     
    448425        }
    449426        newNode.SelectedImageIndex = newNode.ImageIndex;
    450         //if (newResource.OwnerUserId == UserInformation.Instance.User.Id)
    451         //  newNode.BackColor = ownedResourceColor;
    452427      }
    453428
     
    460435      };
    461436
     437      int ungroupedSlavesCount = 0;
    462438      foreach (var slave in subResources.OfType<Slave>().OrderBy(x => x.Name)) {
    463439        var slaveNode = new TreeNode(slave.Name) { Tag = slave };
     440        StyleTreeNode(slaveNode, slave, resources);
    464441        ungroupedNode.Nodes.Add(slaveNode);
    465         if(selectedResource == null) {
     442        ungroupedSlavesCount++;
     443        if (selectedResource == null) {
    466444          SelectedResource = slave;
    467445        }
    468         if (slave.Id == Guid.Empty) {
    469           slaveNode.Text += " [not stored]";
    470         } else if (slave.Modified) {
    471           slaveNode.Text += " [changes not stored]";
    472         }
     446
    473447        if (slave.Id == selectedResource.Id && !nodeSelected) {
    474448          slaveNode.BackColor = selectedColor;
     
    478452      }
    479453
     454      if (ungroupedSlavesCount > 0)
     455        ungroupedNode.Text += " [" + ungroupedSlavesCount.ToString() + "]";
    480456      treeView.Nodes.Add(ungroupedNode);
    481457      treeView.ExpandAll();
     458     
    482459    }
    483460
     
    488465          UpdateChildHbIntervall(r);
    489466        }
    490       }
    491     }
    492 
    493     private bool CheckParentsEqualsMovedNode(TreeNode dest, TreeNode movedNode) {
    494       TreeNode tmp = dest;
    495 
    496       while (tmp != null) {
    497         if (tmp == movedNode) {
    498           return true;
    499         }
    500         tmp = tmp.Parent;
    501       }
    502       return false;
    503     }
    504 
    505     private void ResetView() {
    506       if (InvokeRequired) Invoke((Action)ResetView);
    507       else {
    508         treeView.Nodes.Clear();
    509 
    510         if (viewHost.Content != null && viewHost.Content is SlaveGroup) {
    511           ((SlaveGroup)viewHost.Content).PropertyChanged -= SlaveViewContent_PropertyChanged;
    512         }
    513 
    514         viewHost.Content = null;
    515         if (scheduleView.Content != null) {
    516           scheduleView.Content.Clear();
    517         }
    518 
    519         HiveAdminClient.Instance.ResetDowntime();
    520467      }
    521468    }
     
    534481
    535482      try {
    536         if(resource.Id != Guid.Empty) HiveAdminClient.Delete(resource);
    537         Content.Remove(selectedResource);
     483        if (resource.Id != Guid.Empty) {
     484          var resourcesToSave = Content.Where(x => x.Id == Guid.Empty || x.Modified);
     485          foreach (var r in resourcesToSave)
     486            r.Store();
     487          HiveAdminClient.Delete(resource);
     488          UpdateResources();
     489        } else {
     490          Content.Remove(selectedResource);
     491        }
    538492      } catch(AnonymousUserException) {
    539493        ShowHiveInformationDialog();
     
    549503    }
    550504
    551     private bool IsAuthorized(Resource resource) {
    552       return resource != null
    553           && resource.Name != ungroupedGroupName
    554           //&& resource.Id != Guid.Empty
    555           && UserInformation.Instance.UserExists
    556           && (HiveRoles.CheckAdminUserPermissions()
    557             || HiveAdminClient.Instance.CheckOwnershipOfResource(resource, UserInformation.Instance.User.Id));
    558     }
    559 
    560505    private bool IsAdmin() {
    561506      return HiveRoles.CheckAdminUserPermissions();
     507    }
     508
     509    private void StyleTreeNode(TreeNode n, Resource r, IEnumerable<Resource> resources) {
     510      n.Text = r.Name;
     511      n.BackColor = Color.Transparent;
     512      n.ForeColor = Color.Black;
     513
     514      // slave count
     515      int childSlavesCount = 0;
     516      if (r.Id != Guid.Empty && r is SlaveGroup) {
     517        var descendants = HiveAdminClient.Instance.ResourceDescendants;
     518        if (descendants.ContainsKey(r.Id)) {
     519          childSlavesCount = resources
     520            .OfType<Slave>()
     521            .Where(x => descendants[r.Id].Select(y => y.Id)
     522            .Contains(x.Id))
     523            .Count();
     524        }
     525      } else if(r.Name.StartsWith(ungroupedGroupName)) {
     526        childSlavesCount = resources
     527          .OfType<Slave>()
     528          .Where(x => x.ParentResourceId == null
     529            || (x.ParentResourceId.HasValue && x.ParentResourceId.Value == Guid.Empty))
     530          .Count();
     531      }
     532      if (childSlavesCount > 0)
     533        n.Text += " [" + childSlavesCount.ToString() + "]";
     534
     535      // slave image index, state, utilization
     536      if (r is Slave) {
     537        n.ImageIndex = slaveImageIndex;
     538        var s = r as Slave;
     539        if (s.SlaveState == SlaveState.Calculating) {
     540          n.ForeColor = calculatingColor;
     541          n.Text += " [" + s.CpuUtilization.ToString("N2") + "%]";
     542        } else if (s.SlaveState == SlaveState.Offline) {
     543          n.ForeColor = offlineColor;
     544          if (s.LastHeartbeat.HasValue)
     545            n.Text += " [" + s.LastHeartbeat?.ToString("g") + "]";
     546        }
     547      } else {
     548        n.ImageIndex = slaveGroupImageIndex;
     549      }
     550
     551      // not stored (i.e. new), changed
     552      if (r.Id == Guid.Empty && !r.Name.StartsWith(ungroupedGroupName)) {
     553        n.Text += " [not stored]";
     554      } else if (r.Modified && !r.Name.StartsWith(ungroupedGroupName)) {
     555        n.Text += " [changes not stored]";
     556      }
     557
     558      // ungrouped
     559      if(r.Name.StartsWith(ungroupedGroupName)) {
     560        n.ForeColor = ForeColor = SystemColors.GrayText;
     561      }
     562    }
     563
     564    private void ResetTreeNodes(TreeNodeCollection nodes, IEnumerable<Resource> resources) {
     565      foreach (TreeNode n in nodes) {
     566        StyleTreeNode(n, (Resource)n.Tag, resources);
     567        if (n.Nodes.Count > 0) {
     568          ResetTreeNodes(n.Nodes, resources);
     569        }
     570      }
    562571    }
    563572
     
    571580
    572581      bool locked = !IsAdmin() || resource == null;
    573       bool addLocked = locked || (resource != null && resource.Id == Guid.Empty);
     582      bool scheduleLocked = locked || (resource != null && resource.Id == Guid.Empty);
     583      bool addLocked = locked || (resource != null && resource.Id == Guid.Empty) || resource is Slave;
    574584
    575585      btnAddGroup.Enabled = !addLocked;
     
    578588      viewHost.Locked = locked;
    579589      scheduleView.Locked = locked;
    580       scheduleView.SetEnabledStateOfSchedule(!addLocked);
     590      scheduleView.SetEnabledStateOfSchedule(!scheduleLocked);
    581591    }
    582592
     
    584594      if (resourceNode == null) return;
    585595      SelectedResource = (Resource)resourceNode.Tag;
    586       ResetTreeNodes(treeView.Nodes, selectedColor, Color.Transparent, true);
     596      ResetTreeNodes(treeView.Nodes, Content);
    587597      resourceNode.BackColor = selectedColor;
    588598      resourceNode.Text += " [selected]";
     
    597607      }
    598608    }
     609
     610    private void ResetView() {
     611      if (InvokeRequired) Invoke((Action)ResetView);
     612      else {
     613        treeView.Nodes.Clear();
     614
     615        if (viewHost.Content != null && viewHost.Content is SlaveGroup) {
     616          ((SlaveGroup)viewHost.Content).PropertyChanged -= SlaveViewContent_PropertyChanged;
     617        }
     618
     619        viewHost.Content = null;
     620        if (scheduleView.Content != null) {
     621          scheduleView.Content.Clear();
     622        }
     623
     624        HiveAdminClient.Instance.ResetDowntime();
     625      }
     626    }
     627
    599628    #endregion
    600629  }
  • branches/2839_HiveProjectManagement/HeuristicLab.Clients.Hive/3.3/HiveAdminClient.cs

    r15777 r15792  
    7777    private Dictionary<Guid, HashSet<Resource>> resourceAncestors;
    7878    public Dictionary<Guid, HashSet<Resource>> ResourceAncestors {
    79       get { return ResourceAncestors; }
     79      get { return resourceAncestors; }
    8080    }
    8181
    8282    private Dictionary<Guid, HashSet<Resource>> resourceDescendants;
    8383    public Dictionary<Guid, HashSet<Resource>> ResourceDescendants {
    84       get { return ResourceDescendants; }
     84      get { return resourceDescendants; }
    8585    }
    8686
     
    122122        });
    123123
    124         UpdateResourceGenealogy();
    125         UpdateProjectGenealogy();
     124        UpdateResourceGenealogy(resources);
     125        UpdateProjectGenealogy(projects);
    126126      }
    127127      catch {
     
    133133    }
    134134
    135     private void UpdateResourceGenealogy() {
     135    public void UpdateResourceGenealogy(IItemList<Resource> resources) {
    136136      resourceAncestors.Clear();
    137137      resourceDescendants.Clear();
     
    157157    }
    158158
    159     private void UpdateProjectGenealogy() {
     159    public void UpdateProjectGenealogy(IItemList<Project> projects) {
    160160      projectAncestors.Clear();
    161161      projectDescendants.Clear();
Note: See TracChangeset for help on using the changeset viewer.