Exemplo n.º 1
0
        //--- Class Methods ---
        private static int Main(string[] args)
        {
            bool     useTty = true;
            TimeSpan time;

            // process command line arguments
            XDoc config = new XDoc("config");

            for (int i = 0; i < args.Length; i += 2)
            {
                string key   = args[i].ToLowerInvariant();
                string value = ((i + 1) < args.Length) ? args[i + 1] : string.Empty;
                switch (key)
                {
                case "help":
                    PrintUsage();
                    return(0);

                case "notty":
                    --i;
                    useTty = false;
                    break;

                case "capture-stack-trace":
                    --i;
                    DebugUtil.CaptureStackTrace = true;
                    break;

                case "nolog":
                    --i;

                    // NOTE (steveb): this option used to disable logging, but was removed in favor of using the automatic re-reading of app.config by log4net

                    break;

                case "settings":
                case "config":
                    if (!File.Exists(value))
                    {
                        WriteError(key, "config file not found");
                        return(1);
                    }
                    config = XDocFactory.LoadFrom(value, MimeType.XML);
                    break;

                case "script":
                    config.Start("script").Attr("src", value).End();
                    break;

                case "ip":
                case "host":
                    config.Elem("host", value);
                    break;

                case "http-port":
                case "path-prefix":
                case "server-path":
                case "server-name":
                case "storage-dir":
                case "connect-limit":
                case "apikey":
                case "guid":
                    config.Elem(key, value);
                    break;

                case "public-uri":
                case "root-uri":
                    config.Elem("uri.public", value);
                    break;

                case "service-dir":
                    config.Elem("storage-dir", value);
                    break;

                case "collect-interval":
                    int interval;
                    if (!int.TryParse(value, out interval))
                    {
                        WriteError(key, "invalid collection interval (must be an integer representing seconds)");
                        return(1);
                    }
                    if (interval > 0)
                    {
                        DebugUtil.SetCollectionInterval(TimeSpan.FromSeconds(interval));
                    }
                    break;

                case "auth":
                    config.Elem("authentication-shemes", value);
                    break;

                default:
                    WriteError(key, "unknown setting");
                    return(1);
                }
            }
            try {
                // initialize environment
                if (config["apikey"].IsEmpty)
                {
                    string apikey = StringUtil.CreateAlphaNumericKey(32);
                    config.Elem("apikey", apikey);
                    Console.WriteLine("Dream Host APIKEY: {0}", apikey);
                }
                Console.WriteLine("-------------------- initializing");
                time = DebugUtil.Stopwatch(() => {
                    _host = new DreamHost(config);
                });
                Console.WriteLine("-------------------- initialized {0} secs", time.TotalSeconds);

                // execute scripts
                time = DebugUtil.Stopwatch(() => {
                    _host.RunScripts(config, null);
                });
                Console.WriteLine("-------------------- ready {0} secs", time.TotalSeconds);

                // for UNIX systems, let's also listen to SIGTERM
                if (SysUtil.IsUnix)
                {
                    new Thread(SigTermHandler)
                    {
                        IsBackground = true
                    }.Start();
                }

                // check if we can use the console
                if (useTty)
                {
                    int debuglevel = 0;

                    // wait for user input then exit
                    while (_host.IsRunning)
                    {
                        Thread.Sleep(250);
                        #region Interactive Key Handler
                        if (Console.KeyAvailable)
                        {
                            ConsoleKeyInfo key = Console.ReadKey(true);
                            switch (key.Key)
                            {
                            case ConsoleKey.Q:
                            case ConsoleKey.Escape:
                            case ConsoleKey.Spacebar:
                                Console.WriteLine("Shutting down");
                                return(0);

                            case ConsoleKey.G:
                                Console.WriteLine("Full garbage collection pass");
                                System.GC.Collect();
                                break;

                            case ConsoleKey.C:
                                Console.Clear();
                                break;

                            case ConsoleKey.D:
                                switch (++debuglevel)
                                {
                                default:
                                    debuglevel = 0;
                                    Threading.RendezVousEvent.CaptureTaskState = false;
                                    DebugUtil.CaptureStackTrace = false;
                                    Console.WriteLine("Debug capture: none");
                                    break;

                                case 1:
                                    Threading.RendezVousEvent.CaptureTaskState = true;
                                    DebugUtil.CaptureStackTrace = false;
                                    Console.WriteLine("Debug capture: task-state only");
                                    break;

                                case 2:
                                    Threading.RendezVousEvent.CaptureTaskState = true;
                                    DebugUtil.CaptureStackTrace = true;
                                    Console.WriteLine("Debug capture: task-state and stack-trace");
                                    break;
                                }
                                break;

                            case ConsoleKey.I: {
                                Console.WriteLine("--- System Information ---");

                                // show memory
                                Console.WriteLine("Allocated memory: {0}", GC.GetTotalMemory(false));

                                // show threads
                                int workerThreads;
                                int completionThreads;
                                int dispatcherThreads;
                                int backgroundThreads;
                                AsyncUtil.GetAvailableThreads(out workerThreads, out completionThreads, out dispatcherThreads, out backgroundThreads);
                                int maxWorkerThreads;
                                int maxCompletionThreads;
                                int maxDispatcherThreads;
                                int maxBackgroundThreads;
                                AsyncUtil.GetMaxThreads(out maxWorkerThreads, out maxCompletionThreads, out maxDispatcherThreads, out maxBackgroundThreads);
                                Console.WriteLine("Thread-pool worker threads available: {0} (max: {1})", workerThreads, maxWorkerThreads);
                                Console.WriteLine("Thread-pool completion threads available: {0} (max: {1})", completionThreads, maxCompletionThreads);
                                Console.WriteLine("Dispatcher threads available: {0} (max: {1})", dispatcherThreads, maxDispatcherThreads);
                                Console.WriteLine("Thread-pool background worker threads available: {0} (max: {1})", backgroundThreads, maxBackgroundThreads);

                                // show pending/waiting timers
                                var taskTimerStats = Tasking.TaskTimerFactory.GetStatistics();
                                Console.WriteLine("Pending timer objects: {0}", taskTimerStats.PendingTimers);
                                Console.WriteLine("Queued timer objects: {0}", taskTimerStats.QueuedTimers);
                                Console.WriteLine("Timer retries: {0}", taskTimerStats.Retries);

                                // show activities
                                var activities = _host.ActivityMessages;
                                Console.WriteLine("Host activities: {0}", activities.Length);
                                foreach (var activity in activities)
                                {
                                    Console.WriteLine("* {0}: {1}", activity.Created.ToString(XDoc.RFC_DATETIME_FORMAT), activity.Description);
                                }

                                // show pending tasks
                                Console.WriteLine("Pending rendez-vous events: {0}", Threading.RendezVousEvent.PendingCounter);
                                Console.WriteLine("Pending results: {0}", AResult.PendingCounter);
                                lock (Threading.RendezVousEvent.Pending) {
                                    int count = 0;
                                    foreach (var entry in Threading.RendezVousEvent.Pending.Values)
                                    {
                                        ++count;
                                        if (entry.Key != null)
                                        {
                                            var context = entry.Key.GetState <DreamContext>();
                                            if (context != null)
                                            {
                                                Console.WriteLine("--- DreamContext for pending rendez-vous event #{0} ---", count);
                                                Console.WriteLine(context.Uri.ToString(false));
                                            }
                                        }
                                        Console.WriteLine();
                                        if (entry.Value != null)
                                        {
                                            Console.WriteLine("--- Stack trace for pending rendez-vous event #{0} ---", count);
                                            Console.WriteLine(entry.Value.ToString());
                                        }
                                    }
                                }
                                Console.WriteLine("--------------------------");
                            }
                            break;

                            case ConsoleKey.H:
                                Console.WriteLine("Help:");
                                Console.WriteLine("   Q     - quit application");
                                Console.WriteLine("   ESC   - quit application");
                                Console.WriteLine("   SPACE - quit application");
                                Console.WriteLine("   G     - full garbage collection");
                                Console.WriteLine("   C     - clear screen");
                                Console.WriteLine("   D     - set debug capture level");
                                Console.WriteLine("   I     - show system information (memory, threads, pending tasks)");
                                Console.WriteLine("   H     - this help text");
                                break;
                            }
                        }
                        #endregion
                    }
                }
                else
                {
                    _host.WaitUntilShutdown();
                }
            } finally {
                Console.WriteLine("-------------------- shutting down");
                TaskTimerFactory.ShutdownAll();
                if (_host != null)
                {
                    _host.Dispose();
                }
            }
            return(0);
        }