#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);
}
}
}