internal static RepositoryInstance Start(RepositoryStartSettings settings) { if (!_started) { lock (_startupSync) { if (!_started) { var instance = new RepositoryInstance(); instance._settings = new RepositoryStartSettings.ImmutableRepositoryStartSettings(settings); _instance = instance; try { instance.DoStart(); } catch (Exception) { _instance = null; throw; } _started = true; } } } return(_instance); }
/// <summary> /// Executes the boot sequence of the Repository by the passed <see cref="RepositoryStartSettings"/>. /// </summary> /// <example> /// Use the following code in your tool or other outer application: /// <code> /// var startSettings = new RepositoryStartSettings /// { /// PluginsPath = pluginsPath, // Local directory path of plugins if it is different from your tool's path. /// Console = Console.Out // Startup sequence will be traced to given writer. /// }; /// using (ContentRepository.Repository.Start(startSettings)) /// { /// // your code /// } /// </code> /// </example> /// <remarks> /// Repository will be stopped if the returned <see cref="RepositoryStartSettings"/> instance is disposed. /// </remarks> /// <returns>A new IDisposable <see cref="RepositoryInstance"/> instance.</returns> /// <returns></returns> public static RepositoryInstance Start(RepositoryStartSettings settings) { var instance = RepositoryInstance.Start(settings); AccessProvider.ChangeToSystemAccount(); Repository._root = (PortalRoot)Node.LoadNode(RootPath); AccessProvider.RestoreOriginalUser(); return(instance); }
/// <summary> /// Waits for write.lock to disappear for a configured time interval. Timeout: configured with IndexLockFileWaitForRemovedTimeout key. /// If timeout is exceeded an error is logged and execution continues. For errors at OnStart an email is also sent to a configured address. /// </summary> /// <param name="waitType">A parameter that influences the logged error message and email template only.</param> public static void WaitForWriterLockFileIsReleased(WaitForLockFileType waitType) { // check if writer.lock is still there -> if yes, wait for other appdomain to quit or lock to disappear - until a given timeout. // after timeout is passed, Repository.Start will deliberately attempt to remove lock file on following startup if (!WaitForWriterLockFileIsReleased()) { // lock file was not removed by other or current appdomain for the given time interval (onstart: other appdomain might use it, onend: current appdomain did not release it yet) // onstart -> notify operator and start repository anyway // onend -> log error, and continue var template = waitType == WaitForLockFileType.OnEnd ? WRITELOCKREMOVEERRORONENDTEMPLATESTR : WRITELOCKREMOVEERRORTEMPLATESTR; Logger.WriteError(Logger.EventId.NotDefined, string.Format(template, RepositoryConfiguration.IndexLockFileWaitForRemovedTimeout, AppDomain.CurrentDomain.FriendlyName, AppDomain.CurrentDomain.BaseDirectory)); if (waitType == WaitForLockFileType.OnStart) { RepositoryInstance.SendWaitForLockErrorMail(); } } }
internal static void Shutdown() { if (_instance == null) { Logger.WriteWarning(Logger.EventId.NotDefined, "Repository shutdown has already completed."); return; } lock (_shutDownSync) { if (_instance == null) { Logger.WriteWarning(Logger.EventId.NotDefined, "Repository shutdown has already completed."); return; } DetailedLogger.Log("Sending a goodbye message."); // category: general _instance.ConsoleWriteLine(); _instance.ConsoleWriteLine("Sending a goodbye message..."); DistributedApplication.ClusterChannel.ClusterMemberInfo.NeedToRecover = false; var pingMessage = new PingMessage(); pingMessage.Send(); foreach (var svc in _instance.serviceInstances) { DetailedLogger.Log("Shutting down {0}", svc.GetType().Name); // category: general svc.Shutdown(); } BackgroundOperations.TaskManager.Stop(); DetailedLogger.Log("Shutting down {0}", DistributedApplication.ClusterChannel.GetType().Name); // category: general DistributedApplication.ClusterChannel.ShutDown(); if (Instance.StartSettings.BackupIndexAtTheEnd) { DetailedLogger.Log("Backing up the index."); // category: general if (LuceneManagerIsRunning) { _instance.ConsoleWriteLine("Backing up the index..."); BackupTools.SynchronousBackupIndex(); _instance.ConsoleWriteLine("The backup of index is finished."); } else { _instance.ConsoleWriteLine("Backing up index is skipped because Lucene was not started."); } } if (LuceneManagerIsRunning) { DetailedLogger.Log("Shutting down LuceneManager."); // category: general LuceneManager.ShutDown(); } DetailedLogger.Log("Waiting for writer lock file is released."); // category: general WaitForWriterLockFileIsReleased(WaitForLockFileType.OnEnd); DetailedLogger.Log("Repository has stopped."); // category: general var t = DateTime.UtcNow - _instance._startupInfo.Starting; var msg = String.Format("Repository has stopped. Running time: {0}.{1:d2}:{2:d2}:{3:d2}", t.Days, t.Hours, t.Minutes, t.Seconds); _instance.ConsoleWriteLine(msg); _instance.ConsoleWriteLine(); Logger.WriteInformation(Logger.EventId.NotDefined, msg); _instance = null; } }
/// <summary> /// Stops all internal services of the Repository. /// </summary> public static void Shutdown() { RepositoryInstance.Shutdown(); }
/// <summary> /// Returns the running state of the Repository. /// </summary> /// <returns>True if the Repository has started yet otherwise false.</returns> public static bool Started() { return(RepositoryInstance.Started()); }