Наследование: IDisposable
Пример #1
0
        public void BootstrapsBasicApplicationFileChange()
        {
            string path = ApplicationUtils.CreateValidExampleApplication();
            string filePath = Path.Combine(path, Path.GetFileNameWithoutExtension(Path.GetRandomFileName()) + ".dll");
            ManualResetEvent handle = new ManualResetEvent(false);

            try
            {
                using (Bootstraps bootstraps = new Bootstraps(path, null, 500))
                {
                    bootstraps.ApplicationFilesChanged += (sender, e) =>
                    {
                        Assert.AreEqual(filePath, e.FullPath);
                        handle.Set();
                    };

                    Assert.AreEqual(BootstrapsPullupResultType.Success, bootstraps.PullUp().ResultType);

                    using (File.Create(filePath))
                    {
                    }

                    WaitHandle.WaitAll(new WaitHandle[] { handle });
                }
            }
            finally
            {
                handle.Close();
            }
        }
Пример #2
0
 /// <summary>
 /// Raises the console's CancelKeyPress event.
 /// </summary>
 /// <param name="sender">The event sender.</param>
 /// <param name="e">The event arguments.</param>
 private static void ConsoleCancelKeyPress(object sender, ConsoleCancelEventArgs e)
 {
     lock (Locker)
     {
         if (bootstraps != null)
         {
             bootstraps.Dispose();
             bootstraps = null;
         }
     }
 }
Пример #3
0
        private static void WaitForInput()
        {
            while (isRunning)
            {
                string input = (Console.ReadLine() ?? string.Empty).Trim().ToUpperInvariant();

                if (input == "EXIT")
                {
                    Console.WriteLine();
                    Console.ForegroundColor = ConsoleColor.Cyan;
                    Console.WriteLine("Waiting for all workers to stop...");
                    Console.ResetColor();
                    Console.WriteLine();

                    isRunning = false;

                    lock (Locker)
                    {
                        if (bootstraps != null)
                        {
                            bootstraps.Pushdown(false);
                            bootstraps.Dispose();
                            bootstraps = null;
                        }
                    }
                }
                else if (input == "FORCE")
                {
                    isRunning = false;

                    lock (Locker)
                    {
                        if (bootstraps != null)
                        {
                            bootstraps.Dispose();
                            bootstraps = null;
                        }
                    }
                }
                else if (!string.IsNullOrEmpty(input))
                {
                    Console.WriteLine();
                    Console.ForegroundColor = ConsoleColor.Red;
                    Console.WriteLine("Unrecognized command.");
                    Console.WriteLine();
                    Console.ForegroundColor = ConsoleColor.Cyan;
                    Console.WriteLine("Type 'exit' to shutdown gracefully, or Ctl+C to exit immediately.");
                    Console.ResetColor();
                    Console.WriteLine();
                }
            }
        }
Пример #4
0
        /// <summary>
        /// Attempts a Pullup() operation on the bootstraps instance indefinitely until it succeeds.
        /// </summary>
        private static void PullupBootstraps()
        {
            while (isRunning)
            {
                BootstrapsPullupResult result;

                lock (Locker)
                {
                    if (bootstraps == null)
                    {
                        bootstraps = new Bootstraps(options.ApplicationPath, options.ConfigPath, options.Threshold);
                        bootstraps.ApplicationFilesChanged += new EventHandler <FileSystemEventArgs>(BootstrapsApplicationFilesChanged);
                        bootstraps.Log += new EventHandler <EventLoggerEventArgs>(BootstrapsLog);
                    }

                    logger.Info("Starting the application at '{0}'.", bootstraps.ApplicationPath);
                    result = bootstraps.PullUp();
                }

                if (result.ResultType == BootstrapsPullupResultType.Success)
                {
                    logger.Info("The application at '{0}' is running.", bootstraps.ApplicationPath);
                    break;
                }
                else
                {
                    switch (result.ResultType)
                    {
                    case BootstrapsPullupResultType.ApplicationDirectoryNotFound:
                        logger.Warn("The application directory '{0}' was not found. Trying again in 10 seconds.", bootstraps.ApplicationPath);
                        break;

                    case BootstrapsPullupResultType.ConfigurationFileNotFound:
                        logger.Warn("The configuration file '{0}' was not found. Trying again in 10 seconds.", bootstraps.ConfigPath);
                        break;

                    case BootstrapsPullupResultType.Exception:
                        logger.Error(result.Exception, "An exception occurred while starting the application. Trying again in 10 seconds.");
                        break;

                    default:
                        throw new NotImplementedException();
                    }

                    Thread.Sleep(10000);
                }
            }
        }
Пример #5
0
        /// <summary>
        /// Raises the bootstraps' ApplicationFilesChanged event.
        /// </summary>
        /// <param name="sender">The event sender.</param>
        /// <param name="e">The event arguments.</param>
        private static void BootstrapsApplicationFilesChanged(object sender, FileSystemEventArgs e)
        {
            logger.Info("A change was detected in '{0}'. Shutting down.", e.FullPath);

            lock (Locker)
            {
                if (bootstraps != null)
                {
                    bootstraps.Pushdown(false);
                    bootstraps.Dispose();
                    bootstraps = null;
                }
            }

            logger.Info("Re-starting the application at '{0}'.", options.ApplicationPath);
            PullupBootstraps();
        }
Пример #6
0
        /// <summary>
        /// Raises the parent process' Exited event.
        /// </summary>
        /// <param name="sender">The event sender.</param>
        /// <param name="e">The event arguments.</param>
        private static void ParentProcessExited(object sender, EventArgs e)
        {
            logger.Info("The process for the application at '{0}' has been orphaned. Shutting down.", options.ApplicationPath);
            isRunning = false;

            lock (Locker)
            {
                if (bootstraps != null)
                {
                    bootstraps.Pushdown(false);
                    bootstraps.Dispose();
                    bootstraps = null;
                }

                if (inputThread != null)
                {
                    inputThread.IsBackground = true;
                }
            }
        }
Пример #7
0
        /// <summary>
        /// Executes tests that ensure assemblies are not locked when the remote app domain
        /// is loaded by <see cref="Bootstraps"/>.
        /// </summary>
        /// <param name="path">The path of the application to test.</param>
        /// <param name="pathToDelete">The path of the assembly file to delete.</param>
        private static void AssembliesNotLocked(string path, string pathToDelete)
        {
            using (Bootstraps bootstraps = new Bootstraps(path, null, 500))
            {
                Assert.AreEqual(BootstrapsPullupResultType.Success, bootstraps.PullUp().ResultType);
                Assert.IsTrue(File.Exists(pathToDelete));

                ProcessStartInfo info = new ProcessStartInfo()
                {
                    Arguments = string.Format(CultureInfo.InvariantCulture, @"/C del ""{0}""", pathToDelete),
                    CreateNoWindow = true,
                    FileName = "cmd.exe",
                    RedirectStandardError = true,
                    RedirectStandardOutput = true,
                    UseShellExecute = false
                };

                using (Process process = new Process())
                {
                    process.StartInfo = info;
                    Assert.IsTrue(process.Start());

                    process.WaitForExit();
                    Assert.AreEqual(0, process.ExitCode);
                    Assert.AreEqual(string.Empty, process.StandardError.ReadToEnd());
                    Assert.IsFalse(File.Exists(pathToDelete));
                }
            }
        }
Пример #8
0
        public void BootstrapsWebApplicationConfigFileChange()
        {
            string path = ApplicationUtils.CreateValidExampleWebApplication();
            ManualResetEvent handle = new ManualResetEvent(false);

            try
            {
                using (Bootstraps bootstraps = new Bootstraps(path, null, 500))
                {
                    bootstraps.ApplicationFilesChanged += (sender, e) =>
                    {
                        Assert.AreEqual(Path.Combine(path, "Web.config"), e.FullPath);
                        handle.Set();
                    };

                    Assert.AreEqual(BootstrapsPullupResultType.Success, bootstraps.PullUp().ResultType);

                    using (File.Create(Path.Combine(path, "Web.config")))
                    {
                    }

                    WaitHandle.WaitAll(new WaitHandle[] { handle });
                }
            }
            finally
            {
                handle.Close();
            }
        }
Пример #9
0
        public void BootstrapsPullUpFail()
        {
            string path = ApplicationUtils.CreateValidExampleApplication();
            File.Delete(Path.Combine(path, "BlueCollar.dll"));

            using (Bootstraps bootstraps = new Bootstraps(path, null, 500))
            {
                BootstrapsPullupResult result = bootstraps.PullUp();
                Assert.AreEqual(BootstrapsPullupResultType.Exception, result.ResultType);
                Assert.IsNotNull(result.Exception);
            }
        }
Пример #10
0
        public void BootstrapsPullUpBasicWebApplication()
        {
            string path = ApplicationUtils.CreateValidExampleWebApplication();

            using (Bootstraps bootstraps = new Bootstraps(path, null, 500))
            {
                Assert.AreEqual(BootstrapsPullupResultType.Success, bootstraps.PullUp().ResultType);
                Assert.IsTrue(bootstraps.IsLoaded);
            }
        }
Пример #11
0
        public void BootstrapsPullUpAndExecuteJob()
        {
            string path = ApplicationUtils.CreateValidExampleApplication();

            using (Bootstraps bootstraps = new Bootstraps(path, null, 500))
            {
                Assert.AreEqual(BootstrapsPullupResultType.Success, bootstraps.PullUp(true).ResultType);

                CreateFileJob job = new CreateFileJob()
                {
                    Path = Path.Combine(path, Path.GetRandomFileName())
                };

                Assert.IsFalse(File.Exists(job.Path));

                // The default configuration specifies a SQLite repository pointing
                // to BlueCollar.sqlite in the application's root directory.
                using (IRepository repository = new SQLiteRepository(string.Format(CultureInfo.InvariantCulture, "data source={0};journal mode=Off;synchronous=Off;version=3", Path.Combine(path, "BlueCollar.sqlite"))))
                {
                    job.Enqueue("Default", null, repository);
                }

                // Default worker heartbeat is 5 seconds.
                Thread.Sleep(6000);
                Assert.IsTrue(File.Exists(job.Path));
            }
        }
Пример #12
0
 /// <summary>
 /// Raises the console's CancelKeyPress event.
 /// </summary>
 /// <param name="sender">The event sender.</param>
 /// <param name="e">The event arguments.</param>
 private static void ConsoleCancelKeyPress(object sender, ConsoleCancelEventArgs e)
 {
     lock (Locker)
     {
         if (bootstraps != null)
         {
             bootstraps.Dispose();
             bootstraps = null;
         }
     }
 }
Пример #13
0
        private static void WaitForInput()
        {
            while (isRunning)
            {
                string input = (Console.ReadLine() ?? string.Empty).Trim().ToUpperInvariant();

                if (input == "EXIT")
                {
                    Console.WriteLine();
                    Console.ForegroundColor = ConsoleColor.Cyan;
                    Console.WriteLine("Waiting for all workers to stop...");
                    Console.ResetColor();
                    Console.WriteLine();

                    isRunning = false;

                    lock (Locker)
                    {
                        if (bootstraps != null)
                        {
                            bootstraps.Pushdown(false);
                            bootstraps.Dispose();
                            bootstraps = null;
                        }
                    }
                }
                else if (input == "FORCE")
                {
                    isRunning = false;

                    lock (Locker)
                    {
                        if (bootstraps != null)
                        {
                            bootstraps.Dispose();
                            bootstraps = null;
                        }
                    }
                }
                else if (!string.IsNullOrEmpty(input))
                {
                    Console.WriteLine();
                    Console.ForegroundColor = ConsoleColor.Red;
                    Console.WriteLine("Unrecognized command.");
                    Console.WriteLine();
                    Console.ForegroundColor = ConsoleColor.Cyan;
                    Console.WriteLine("Type 'exit' to shutdown gracefully, or Ctl+C to exit immediately.");
                    Console.ResetColor();
                    Console.WriteLine();
                }
            }
        }
Пример #14
0
        /// <summary>
        /// Attempts a Pullup() operation on the bootstraps instance indefinitely until it succeeds.
        /// </summary>
        private static void PullupBootstraps()
        {
            while (isRunning)
            {
                BootstrapsPullupResult result;

                lock (Locker)
                {
                    if (bootstraps == null)
                    {
                        bootstraps = new Bootstraps(options.ApplicationPath, options.ConfigPath, options.Threshold);
                        bootstraps.ApplicationFilesChanged += new EventHandler<FileSystemEventArgs>(BootstrapsApplicationFilesChanged);
                        bootstraps.Log += new EventHandler<EventLoggerEventArgs>(BootstrapsLog);
                    }

                    logger.Info("Starting the application at '{0}'.", bootstraps.ApplicationPath);
                    result  = bootstraps.PullUp();
                }

                if (result.ResultType == BootstrapsPullupResultType.Success)
                {
                    logger.Info("The application at '{0}' is running.", bootstraps.ApplicationPath);
                    break;
                }
                else
                {
                    switch (result.ResultType)
                    {
                        case BootstrapsPullupResultType.ApplicationDirectoryNotFound:
                            logger.Warn("The application directory '{0}' was not found. Trying again in 10 seconds.", bootstraps.ApplicationPath);
                            break;
                        case BootstrapsPullupResultType.ConfigurationFileNotFound:
                            logger.Warn("The configuration file '{0}' was not found. Trying again in 10 seconds.", bootstraps.ConfigPath);
                            break;
                        case BootstrapsPullupResultType.Exception:
                            logger.Error(result.Exception, "An exception occurred while starting the application. Trying again in 10 seconds.");
                            break;
                        default:
                            throw new NotImplementedException();
                    }

                    Thread.Sleep(10000);
                }
            }
        }
Пример #15
0
        /// <summary>
        /// Raises the parent process' Exited event.
        /// </summary>
        /// <param name="sender">The event sender.</param>
        /// <param name="e">The event arguments.</param>
        private static void ParentProcessExited(object sender, EventArgs e)
        {
            logger.Info("The process for the application at '{0}' has been orphaned. Shutting down.", options.ApplicationPath);
            isRunning = false;

            lock (Locker)
            {
                if (bootstraps != null)
                {
                    bootstraps.Pushdown(false);
                    bootstraps.Dispose();
                    bootstraps = null;
                }

                if (inputThread != null)
                {
                    inputThread.IsBackground = true;
                }
            }
        }
Пример #16
0
        public void BootstrapsPullUpAndExcecuteJobWithHttpApplicationEntryPoint()
        {
            string path = ApplicationUtils.CreateValidExampleApplication();

            using (Bootstraps bootstraps = new Bootstraps(path, null, 500))
            {
                Assert.AreEqual(BootstrapsPullupResultType.Success, bootstraps.PullUp(true).ResultType);

                CreateFileJob job = new CreateFileJob()
                {
                    Path = Path.Combine(path, Path.GetRandomFileName())
                };

                Assert.IsFalse(File.Exists(job.Path));

                using (IRepository repository = new SQLiteRepository(string.Format(CultureInfo.InvariantCulture, "data source={0};journal mode=Off;synchronous=Off;version=3", Path.Combine(path, "BlueCollar.sqlite"))))
                {
                    job.Enqueue("Default", null, repository);
                }

                Thread.Sleep(6000);
                Assert.IsTrue(File.Exists("HttpApplicationStart"));

                bootstraps.Pushdown(true);
                Assert.IsTrue(File.Exists("HttpApplicationEnd"));
            }
        }
Пример #17
0
        /// <summary>
        /// Raises the bootstraps' ApplicationFilesChanged event.
        /// </summary>
        /// <param name="sender">The event sender.</param>
        /// <param name="e">The event arguments.</param>
        private static void BootstrapsApplicationFilesChanged(object sender, FileSystemEventArgs e)
        {
            logger.Info("A change was detected in '{0}'. Shutting down.", e.FullPath);

            lock (Locker)
            {
                if (bootstraps != null)
                {
                    bootstraps.Pushdown(false);
                    bootstraps.Dispose();
                    bootstraps = null;
                }
            }

            logger.Info("Re-starting the application at '{0}'.", options.ApplicationPath);
            PullupBootstraps();
        }