using System; using ln.logging; using ln.http; using System.Net; using ln.skyscanner.http; using System.IO; using ln.skyscanner.crawl; using ln.types.threads; using System.Threading; using Newtonsoft.Json; using Newtonsoft.Json.Converters; using ln.skyscanner.checks; using System.Collections.Generic; using ln.skyscanner.import.skytron; using System.Linq; namespace ln.skyscanner { [JsonConverter(typeof(StringEnumConverter))] public enum ComponentState { STOPPED, INITIALIZED, STARTED, FAILED, STOPPING } public class SkyScanner { public static SkyScanner Instance { get; private set; } public String[] Arguments { get; } public String BasePath { get; private set; } public Pool ConveniencePool { get; } public HTTPServer HTTPServer { get; private set; } public Crawler Crawler { get; private set; } public SkyEntities Entities { get; private set; } public SkyChecker Checker { get; private set; } public MemoryLogger MemoryLogger { get; private set; } public SkyScanner(String[] args) :this() { MemoryLogger = new MemoryLogger(4096); Logger.Default.Backends.Add(MemoryLogger); Logging.Log(LogLevel.INFO, "SkyScanner: Constructor"); BasePath = Path.GetFullPath("/var/cache/ln.skyscanner"); Logging.Log(LogLevel.INFO, "SkyScanner: BasePath={0}", BasePath); ConveniencePool = new Pool(); Arguments = args; String skytronImport = null; String benchMark = null; Queue qArguments = new Queue(Arguments); while (qArguments.Count > 0) { string arg = qArguments.Dequeue(); switch (arg) { case "-p": BasePath = Path.GetFullPath(qArguments.Dequeue()); break; case "--import-skytron": skytronImport = qArguments.Dequeue(); break; case "--benchmark": benchMark = qArguments.Dequeue(); break; } } Entities = new SkyEntities(this); Checker = new SkyChecker(); if (skytronImport != null) { SkytronImport si = new SkytronImport(skytronImport); si.Import(); } if (benchMark != null) { switch (benchMark) { case "odb": BenchmarkODB(); break; default: Logging.Log(LogLevel.ERROR, "Unknown Benchmark: {0}", benchMark); break; } throw new Exception("Quitting after benchmarking"); } } private SkyScanner() { if (Instance != null) throw new NotSupportedException("only one SkyScanner may be created"); Instance = this; } public void Start() { Logging.Log(LogLevel.INFO, "SkyScanner: Start()"); StartHttpServer(); StartCrawler(); Checker.Start(); lock (this) { Monitor.Wait(this); } } public void Stop() { Logging.Log(LogLevel.INFO, "SkyScanner: Stop()"); Checker.Stop(); StopCrawler(); new Thread(() => ConveniencePool.Close()).Start(); StopHttpServer(); lock (this) { Monitor.Pulse(this); } } /** HTTP Server **/ public ComponentState HttpStatus { get { if (HTTPServer != null) { if (HTTPServer.IsRunning) return ComponentState.STARTED; return ComponentState.INITIALIZED; } return ComponentState.STOPPED; } } public void StartHttpServer() { HTTPServer = new HTTPServer(); HTTPServer.AddEndpoint(new System.Net.IPEndPoint(IPAddress.Any,8080)); HTTPServer.DefaultApplication = new SkyScannerHttpApplication(this); HTTPServer.Start(); } public void StopHttpServer() { if (HTTPServer != null) { if (HTTPServer.IsRunning) { HTTPServer.Stop(); } } } /** Crawler **/ public ComponentState CrawlerStatus { get { if (Crawler != null) { return Crawler.CrawlerState; } return ComponentState.STOPPED; } } public void StartCrawler() { if (Crawler == null) { Crawler = new Crawler(this); } else { Crawler.Start(); } } public void StopCrawler() { if (Crawler != null) { Crawler.Stop(); } } public void BenchmarkODB() { int maxIterations = 10000; for (int i = 0; i < maxIterations; i++) { int n = 0; Logging.Log(LogLevel.INFO, "Benchmark ODB: Iteration {0} of {1}", i, maxIterations); foreach (SkyCheckState checkState in SkyScanner.Instance.Entities.SkyCheckStates.ToArray()) { SkyScanner.Instance.Entities.SkyCheckStates.Upsert(checkState); n++; } Logging.Log(LogLevel.INFO, "Saved {0} SkyCheckStates", n); } } } }