ln.skyscanner/services/CheckService.cs

197 lines
6.6 KiB
C#
Raw Normal View History

2019-08-03 12:57:32 +02:00
using System;
using ln.application;
using System.Threading;
using ln.logging;
using ln.application.service;
2019-08-06 00:26:53 +02:00
using ln.skyscanner.entities;
using ln.skyscanner.checks;
using System.Collections.Generic;
using ln.types.threads;
using System.Linq;
2019-08-29 13:14:52 +02:00
using ln.snmp;
using ln.types.odb.ng;
2019-08-30 07:16:54 +02:00
2019-08-03 12:57:32 +02:00
namespace ln.skyscanner.services
{
public class CheckService : ApplicationServiceBase
{
2019-08-29 13:14:52 +02:00
public static bool DEBUG = false;
2019-08-06 00:26:53 +02:00
Pool checkPool;
2019-08-19 14:15:10 +02:00
EntityService entityService;
2019-08-29 13:14:52 +02:00
PerformanceValueService performanceValueService;
public EntityService EntityService => entityService;
public PerformanceValueService PerformanceValueService => performanceValueService;
public SNMPEngine SNMPEngine { get; private set; }
SkyScanner.Service coreService;
CheckServiceRPC RPC;
2019-08-06 00:26:53 +02:00
2019-08-30 07:16:54 +02:00
Mapper SessionMapper { get; set; }
Dictionary<Node, CheckJob> checkJobs = new Dictionary<Node, CheckJob>();
2019-08-03 12:57:32 +02:00
public CheckService()
:base("Check Service")
{
2019-08-29 13:14:52 +02:00
DependOnService<SkyScanner.Service>();
2019-08-03 12:57:32 +02:00
DependOnService<EntityService>();
2019-08-29 13:14:52 +02:00
DependOnService<PerformanceValueService>();
2019-08-03 12:57:32 +02:00
}
public override void ServiceMain(IApplicationInterface applicationInterface)
{
2019-08-29 13:14:52 +02:00
coreService = Dependency<SkyScanner.Service>();
2019-08-19 14:15:10 +02:00
entityService = Dependency<EntityService>();
2019-08-29 13:14:52 +02:00
performanceValueService = Dependency<PerformanceValueService>();
2019-08-06 00:26:53 +02:00
HashSet<Node> currentNodes = new HashSet<Node>();
2019-08-29 13:14:52 +02:00
checkPool = new Pool(96);
2019-08-30 07:16:54 +02:00
checkPool.PoolJobFinished += PoolJobFinished;
2019-08-29 13:14:52 +02:00
SNMPEngine = new SNMPEngine();
SNMPEngine.Timeout = 2000;
2019-08-06 00:26:53 +02:00
2019-08-03 12:57:32 +02:00
long nextMinute = DateTimeOffset.Now.ToUnixTimeMilliseconds();
2019-08-29 13:14:52 +02:00
RPC = new CheckServiceRPC(this);
coreService.RPCContainer.Add("CheckService",RPC);
2019-08-30 07:16:54 +02:00
using (Session session = new Session(entityService.StorageContainer))
2019-08-03 12:57:32 +02:00
{
2019-08-30 07:16:54 +02:00
SessionMapper = new Mapper(session);
2019-08-03 12:57:32 +02:00
2019-08-30 07:16:54 +02:00
Ready();
2019-08-06 00:26:53 +02:00
2019-08-30 07:16:54 +02:00
while (!StopRequested)
2019-08-03 12:57:32 +02:00
{
2019-08-30 07:16:54 +02:00
Logging.Log(LogLevel.INFO, "SkyChecker.scheduler(): scheduler starts");
2019-08-06 00:26:53 +02:00
2019-08-30 07:16:54 +02:00
UpdateNodeList();
2019-08-06 00:26:53 +02:00
2019-08-30 07:16:54 +02:00
foreach (CheckJob checkJob in checkJobs.Values)
checkJob.Prepare();
2019-08-06 00:26:53 +02:00
2019-08-30 07:16:54 +02:00
Logging.Log(LogLevel.INFO, "SkyChecker.scheduler(): currently knows {0} checks", checkJobs.Count);
Logging.Log(LogLevel.INFO, "SkyChecker.scheduler(): currently {0} checks alive", checkPool.NumQueuedJobs);
Logging.Log(LogLevel.INFO, "SkyChecker.scheduler(): scheduled {0} checks", checkPool.Enqueue(checkJobs.Values));
2019-08-03 12:57:32 +02:00
2019-08-30 07:16:54 +02:00
while (true)
2019-08-03 12:57:32 +02:00
{
2019-08-30 07:16:54 +02:00
while ((nextMinute - DateTimeOffset.Now.ToUnixTimeMilliseconds()) < 0)
nextMinute += 60000;
try
{
Thread.Sleep((int)(nextMinute - DateTimeOffset.Now.ToUnixTimeMilliseconds()));
2019-08-03 12:57:32 +02:00
break;
2019-08-30 07:16:54 +02:00
}
catch (ThreadInterruptedException)
{
Logging.Log(LogLevel.INFO, "CheckService: scheduler was interrupted");
if (StopRequested)
break;
}
2019-08-03 12:57:32 +02:00
}
}
}
2019-08-19 14:15:10 +02:00
2019-08-29 13:14:52 +02:00
coreService.RPCContainer.Remove("CheckService");
2019-08-19 14:15:10 +02:00
entityService = null;
2019-08-29 13:14:52 +02:00
performanceValueService = null;
coreService = null;
2019-08-19 14:15:10 +02:00
}
2019-08-30 07:16:54 +02:00
private void UpdateNodeList()
{
lock (this)
{
Logging.Log(LogLevel.DEBUG, "CheckService: Synchronizing CheckJobs");
HashSet<Node> knownNodes = new HashSet<Node>(SessionMapper.Load<Node>());
HashSet<Node> currentNodes = new HashSet<Node>(checkJobs.Keys);
foreach (Node node in knownNodes)
{
if (!currentNodes.Contains(node))
{
CheckJob checkJob = new CheckJob(this, node);
checkJobs.Add(node, checkJob);
}
}
foreach (Node node in currentNodes)
{
if (!knownNodes.Contains(node))
{
checkJobs.Remove(node);
}
}
}
}
void PoolJobFinished(Pool pool, PoolJob job)
{
CheckJob checkJob = job as CheckJob;
SessionMapper.Save<Node>(checkJob.Node);
}
2019-08-19 14:15:10 +02:00
public SkyCheckState[] GetCheckStates(Node node)
{
Query stateQuery = Query.Equals<SkyCheckState>("Node", node.ID);
2019-08-30 07:16:54 +02:00
SkyCheckState[] skyCheckStates = SessionMapper.Load<SkyCheckState>(stateQuery).ToArray();
2019-08-19 14:15:10 +02:00
Dictionary<string, SkyCheckState> checkStates = new Dictionary<string, SkyCheckState>();
foreach (SkyCheckState checkState in skyCheckStates)
{
checkStates.Add(checkState.CheckName, checkState);
}
foreach (SkyCheck check in SkyCheck.SkyChecks)
{
if (!checkStates.ContainsKey(check.Name) && check.IsValid(node))
{
checkStates.Add(check.Name, check.PrepareCheckState(this, node));
2019-08-30 07:16:54 +02:00
SessionMapper.Save<SkyCheckState>(checkStates[check.Name]);
2019-08-19 14:15:10 +02:00
}
}
return checkStates.Values.ToArray();
}
class CheckServiceRPC
{
CheckService checkService;
public CheckServiceRPC(CheckService checkService)
{
this.checkService = checkService;
}
2019-08-29 13:14:52 +02:00
public Node[] GetIssueList()
{
List<Node> nodes = new List<Node>();
2019-08-30 07:16:54 +02:00
foreach (Node node in checkService.SessionMapper.Load<Node>())
2019-08-29 13:14:52 +02:00
{
foreach (SkyCheckState checkState in node.CheckStates)
{
if (!String.Empty.Equals(node.Vendor) && ((checkState.CheckState != CheckState.OK) || ((checkState.UnchangedTime < TimeSpan.FromMinutes(10)) && (checkState.History.Length > 1)))){
nodes.Add(node);
break;
}
}
}
return nodes.ToArray();
}
2019-08-03 12:57:32 +02:00
}
2019-08-19 14:15:10 +02:00
2019-08-03 12:57:32 +02:00
}
}