using System; using ln.logging; using System.IO; using ln.types.threads; using ln.types.net; using ln.application; using ln.application.service; using ln.skyscanner.services; using System.Threading; using ln.http.resources; using ln.types.rpc; using ln.json; namespace ln.skyscanner { public enum ComponentState { STOPPED, INITIALIZED, STARTED, FAILED, STOPPING } public class SkyScanner : Application { public static SkyScanner Instance { get; private set; } public String BasePath { get; private set; } public Pool ConveniencePool { get; } public SkyScanner() { if (Instance != null) throw new NotSupportedException("only one SkyScanner may be created"); Instance = this; Arguments .Add(0, "base-path", Path.GetFullPath("/var/cache/ln.skyscanner")) .Add(0, "import-skytron", null) .Add(0, "benchmark", null) .Add(0, "debug-check", null) .Add("disable-checker") .Add(0, "crawl-vendor", null) .Add(0, "crawl", null) ; Logging.Log(LogLevel.INFO, "SkyScanner: Constructor"); BasePath = Arguments["base-path"].Value; Logging.Log(LogLevel.INFO, "SkyScanner: BasePath={0}", BasePath); ConveniencePool = new Pool(); } public override void PrepareStart() { base.PrepareStart(); FileLogger fileLogger = new FileLogger("skyscanner.log"); fileLogger.MaxLogLevel = (LogLevel)Enum.Parse(typeof(LogLevel), Arguments["log-level"].Value); Logger.Default.Backends.Add(fileLogger); if (Arguments["import-skytron"].IsSet) { //SkytronImport si = new SkytronImport(Arguments["import-skytron"].Value); //si.Import(); } if (Arguments["benchmark"].IsSet) { switch (Arguments["benchmark"].Value) { case "odb": BenchmarkODB(); break; default: Logging.Log(LogLevel.ERROR, "Unknown Benchmark: {0}", Arguments["benchmark"].Value); break; } throw new Exception("Quitting after benchmarking"); } /* if (crawlHost != null) { CrawlHost(crawlHost); throw new Exception("Quitting after --crawl"); } if (debugCheckNode != null) { DebugCheck(debugCheckNode); throw new Exception("Quitting after --debug-check"); } */ ServiceContainer.Add(ServiceDefinition.From(true)); ServiceContainer.Add(ServiceDefinition.From(true)); ServiceContainer.Add(ServiceDefinition.From(true)); ServiceContainer.Add(ServiceDefinition.From(true)); ServiceContainer.Add(ServiceDefinition.From(true)); } public class Service : ApplicationServiceBase { public ApplicationWebSocket webSocketInterface { get; private set; } public RPCContainer RPCContainer { get; private set; } public Service() : base("SkyScanner Application Service") { RPCContainer = new RPCContainer(); } public override void ServiceMain(IApplicationInterface applicationInterface) { DirectoryResource staticTemplates = new DirectoryResource(new string[] { "../../www", "www" }); staticTemplates.ResourceTypeHook = ResourceTypeHook; staticTemplates.DefaultResource = staticTemplates.GetResource("index.html"); staticTemplates.FallBackResource = staticTemplates.DefaultResource; staticTemplates.GetResource("vue").DefaultResource = staticTemplates.GetResource("vue").GetResource("vue.html"); staticTemplates.GetResource("vue").FallBackResource = staticTemplates.GetResource("vue").DefaultResource; applicationInterface.HTTPApplication.RootResource = staticTemplates; webSocketInterface = new ApplicationWebSocket(null, "socket", RPCContainer); staticTemplates.InjectResource(webSocketInterface); RPCContainer.Add("", new SkyScannerRpc(this)); RPCContainer.Add("ServiceContainer",applicationInterface.ServiceContainer.RPC); long nextCycle = DateTimeOffset.Now.ToUnixTimeMilliseconds(); Ready(); while (!StopRequested) { while ((nextCycle - DateTimeOffset.Now.ToUnixTimeMilliseconds()) < 0) nextCycle += 1000; try { int timeOut = (int)(nextCycle - DateTimeOffset.Now.ToUnixTimeMilliseconds()); if (timeOut > 0) Thread.Sleep(timeOut); } catch (ThreadInterruptedException) { if (StopRequested) break; } /* Send Application State to WebSockets */ JSONObject msg = new JSONObject(); JSONObject stateObject = new JSONObject(); stateObject.Add("currentTime", DateTimeOffset.Now.ToUnixTimeMilliseconds()); msg["state"] = stateObject; webSocketInterface.Broadcast(msg); } } private Resource ResourceTypeHook(DirectoryResource directoryResource, FileInfo fileInfo) { if (fileInfo.Extension.Equals(".html")) return new TemplateResource(directoryResource, fileInfo.FullName); return null; } class SkyScannerRpc { Service skyscannerService; public SkyScannerRpc(Service skyscannerService) { this.skyscannerService = skyscannerService; } public string GetServerString() { return "SkyScanner 0.1a"; } public void Shutdown() { ThreadPool.QueueUserWorkItem((state) => ((Application)this.skyscannerService.CurrentApplicationInterface).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); //} } public void CrawlHost(IPv4 ip) { //Logger.ConsoleLogger.MaxLogLevel = LogLevel.DEBUGFULL; //CrawledHost crawledHost = new CrawledHost(); //crawledHost.Name = ip.ToString(); //crawledHost.PrimaryIP = ip; //crawledHost.IPAddresses = new IPv4[] { ip }; //Crawl crawl = new Crawl(Crawler, crawledHost); //crawl.Prepare(); //crawl.RunJob(); //Logging.Log(LogLevel.INFO, "CrawledHost: {0}", JSONObject.From(crawledHost).ToString()); } public void DebugCheck(String uniqueID) { //Logger.ConsoleLogger.MaxLogLevel = LogLevel.DEBUGFULL; //Node node = Entities.NodeCollection.Query("uniqueIdentity", uniqueID).FirstOrDefault(); //if (node == null) //{ // Logging.Log(LogLevel.INFO, "DebugCheck(): Node not found: uniqueIdentity={0}", uniqueID); //} //else //{ // Logging.Log(LogLevel.INFO, "DebugCheck(): Node: {0}",JSONObject.From(node).ToString()); // CheckJob checkJob = new CheckJob(null, node); // Logging.Log(LogLevel.INFO, "Prepare..."); // checkJob.Prepare(); // Logging.Log(LogLevel.INFO, "Check..."); // checkJob.RunJob(); //} } } }