#region License Information /* HeuristicLab * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL) * * This file is part of HeuristicLab. * * HeuristicLab is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * HeuristicLab is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with HeuristicLab. If not, see . */ #endregion using HeuristicLab.Clients.Hive.WebJobManager.Services; using Microsoft.AspNetCore.SignalR; using Newtonsoft.Json; using System; using System.Collections.Generic; namespace HeuristicLab.Clients.Hive.WebJobManager { /// /// SignalR Hub for updating a current selected job /// public class JobUpdaterHub : Hub { private RefreshableJob Job;//Current job (only used as reference, instance gets lost) private WebLoginService weblog; private FileOpeningService fileopener; private Guid userId; private void loader() { weblog = WebLoginService.Instance; string uid = Context.QueryString["userid"]; if (uid == null || uid == "" || Guid.Parse(uid) == Guid.Empty) { userId = Guid.Empty; } else { userId = Guid.Parse(uid); fileopener = weblog.getJobOpener(userId); } } /// /// Initial connection call from client /// public void initConnection() { loader(); fileopener.previousids = new List(); fileopener.previousLogs = new List(); Job = fileopener.Job; updateAll();//start initial update } /// /// Starts update loop for selected job. Sends end token when done and calls GC /// public void updateAll() { loader(); fileopener.refreshJob();//refresh all data from job Job = fileopener.Job; updateJob(); foreach (var t in Job.HiveTasks) { looperTasks(t);//starts recursive loop } Clients.Caller.requestDone();//Final note from server when all tasks are checked. //Client starts countdown and resends the updateAll when done GC.Collect(); GC.WaitForPendingFinalizers(); } private void updateJob() { Clients.Caller.processJobData(Job.Job.CalculatingCount, Job.Job.FinishedCount); } /// /// Recursive loop for updating the selected job view /// /// Loops on all children private void looperTasks(HiveTask task) { try { int index; bool test = false; if (fileopener.previousids.Contains(task.Task.Id)) { index = fileopener.previousids.IndexOf(task.Task.Id); } else {//initial add to previous list, used to check if updates happened fileopener.previousids.Add(task.Task.Id); index = fileopener.previousids.IndexOf(task.Task.Id); fileopener.previousLogs.Add(task.Task.StateLog.Count); test = true;//initial added task, data must be sent } var previous = fileopener.previousLogs[index]; if (test || previous < task.Task.StateLog.Count) {//Checks if change happened so data is not sent unnecessary fileopener.previousLogs[index] = task.Task.StateLog.Count; JsonSerializerSettings settings = new JsonSerializerSettings(); settings.ContractResolver = new JsonTaskResolver(); //limits loaded data var json = JsonConvert.SerializeObject(task.Task, settings); Clients.Caller.processData(task.Task.Id, json, task.ItemTask.Name.ToString()); //data sent to user } foreach (var t in task.ChildHiveTasks) {//loop on childs looperTasks(t); } } catch (JsonSerializationException e) { }//Taskresolver fixes much but img tries to throw this sometimes } /// /// Restarts a failed task, sent by client /// /// Task id from failed task public void restartTask(Guid id) { loader(); weblog.getServiceLocator(userId).getHiveServiceClient().RestartTask(id); } } }