using System; using ln.application; using System.Threading; using ln.logging; using ln.application.service; using ln.skyscanner.entities; using ln.skyscanner.checks; using System.Collections.Generic; using ln.types.threads; using System.Linq; using ln.snmp; using ln.types.odb.ng; namespace ln.skyscanner.services { public class CheckService : ApplicationServiceBase { public static bool DEBUG = false; Pool checkPool; EntityService entityService; PerformanceValueService performanceValueService; public EntityService EntityService => entityService; public PerformanceValueService PerformanceValueService => performanceValueService; public SNMPEngine SNMPEngine { get; private set; } SkyScanner.Service coreService; CheckServiceRPC RPC; Mapper SessionMapper { get; set; } Dictionary checkJobs = new Dictionary(); public CheckService() :base("Check Service") { DependOnService(); DependOnService(); DependOnService(); } public override void ServiceMain(IApplicationInterface applicationInterface) { coreService = Dependency(); entityService = Dependency(); performanceValueService = Dependency(); HashSet currentNodes = new HashSet(); checkPool = new Pool(96); checkPool.PoolJobFinished += PoolJobFinished; SNMPEngine = new SNMPEngine(); SNMPEngine.Timeout = 2000; long nextMinute = DateTimeOffset.Now.ToUnixTimeMilliseconds(); RPC = new CheckServiceRPC(this); coreService.RPCContainer.Add("CheckService",RPC); using (Session session = new Session(entityService.StorageContainer)) { SessionMapper = new Mapper(session); Ready(); while (!StopRequested) { Logging.Log(LogLevel.INFO, "SkyChecker.scheduler(): scheduler starts"); UpdateNodeList(); foreach (CheckJob checkJob in checkJobs.Values) checkJob.Prepare(); 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)); while (true) { while ((nextMinute - DateTimeOffset.Now.ToUnixTimeMilliseconds()) < 0) nextMinute += 60000; try { Thread.Sleep((int)(nextMinute - DateTimeOffset.Now.ToUnixTimeMilliseconds())); break; } catch (ThreadInterruptedException) { Logging.Log(LogLevel.INFO, "CheckService: scheduler was interrupted"); if (StopRequested) break; } } } } coreService.RPCContainer.Remove("CheckService"); entityService = null; performanceValueService = null; coreService = null; } private void UpdateNodeList() { lock (this) { Logging.Log(LogLevel.DEBUG, "CheckService: Synchronizing CheckJobs"); HashSet knownNodes = new HashSet(SessionMapper.Load()); HashSet currentNodes = new HashSet(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(checkJob.Node); } public SkyCheckState[] GetCheckStates(Node node) { Query stateQuery = Query.Equals("Node", node.ID); SkyCheckState[] skyCheckStates = SessionMapper.Load(stateQuery).ToArray(); Dictionary checkStates = new Dictionary(); 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)); SessionMapper.Save(checkStates[check.Name]); } } return checkStates.Values.ToArray(); } class CheckServiceRPC { CheckService checkService; public CheckServiceRPC(CheckService checkService) { this.checkService = checkService; } public Node[] GetIssueList() { List nodes = new List(); foreach (Node node in checkService.SessionMapper.Load()) { 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(); } } } }