internal static RepositoryInstance Start(RepositoryStartSettings settings) { if (!_started) { lock (_startStopSync) { 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); }
internal static void Shutdown() { if (_instance == null) { _started = false; SnLog.WriteWarning("Repository shutdown has already completed."); return; } lock (_startStopSync) { if (_instance == null) { _started = false; SnLog.WriteWarning("Repository shutdown has already completed."); return; } SnTrace.Repository.Write("Sending a goodbye message."); _instance.ConsoleWriteLine(); _instance.ConsoleWriteLine("Sending a goodbye message..."); DistributedApplication.ClusterChannel.ClusterMemberInfo.NeedToRecover = false; var pingMessage = new PingMessage(); pingMessage.SendAsync(CancellationToken.None).GetAwaiter().GetResult(); foreach (var svc in _instance.serviceInstances) { SnTrace.Repository.Write("Shutting down {0}", svc.GetType().Name); svc.Shutdown(); } SnTrace.Repository.Write("Shutting down {0}", DistributedApplication.ClusterChannel.GetType().Name); DistributedApplication.ClusterChannel.ShutDownAsync(CancellationToken.None).GetAwaiter().GetResult(); SnTrace.Repository.Write("Shutting down Security."); SecurityHandler.ShutDownSecurity(); SnTrace.Repository.Write("Shutting down IndexingEngine."); IndexManager.ShutDown(); ContextHandler.Reset(); var t = DateTime.UtcNow - _instance._startupInfo.Starting; var msg = $"Repository has stopped. Running time: {t.Days}.{t.Hours:d2}:{t.Minutes:d2}:{t.Seconds:d2}"; SnTrace.Repository.Write(msg); SnTrace.Flush(); _instance.ConsoleWriteLine(msg); _instance.ConsoleWriteLine(); SnLog.WriteInformation(msg); _instance = null; _started = false; } }
internal static void Shutdown() { _instance.ConsoleWriteLine(); DistributedApplication.ClusterChannel.ShutDown(); if (Instance.StartSettings.BackupIndexAtTheEnd) { if (LuceneManagerIsRunning) { _instance.ConsoleWriteLine("Backing up the index..."); SenseNet.Search.Indexing.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) { SenseNet.Search.Indexing.LuceneManager.ShutDown(); } WaitForWriterLockFileIsReleased(WaitForLockFileType.OnEnd); var t = DateTime.Now - _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(msg); _instance = null; }
/// <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 (SenseNet.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); SystemAccount.Execute(() => Root); 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 (SenseNet.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(); Root = (PortalRoot)Node.LoadNode(RootPath); AccessProvider.RestoreOriginalUser(); return(instance); }
public static RepositoryInstance Start(RepositoryBuilder builder) { // Required early configuration BlobStorageComponents.DataProvider = Providers.Instance.BlobMetaDataProvider; BlobStorageComponents.ProviderSelector = Providers.Instance.BlobProviderSelector; var initialData = builder.InitialData; if (initialData != null) { DataStore.InstallInitialDataAsync(initialData, CancellationToken.None) .GetAwaiter().GetResult(); } RepositoryInstance repositoryInstance = null; var exclusiveLockOptions = builder.Services?.GetService <IOptions <ExclusiveLockOptions> >()?.Value; ExclusiveBlock.RunAsync("SenseNet.PatchManager", Guid.NewGuid().ToString(), ExclusiveBlockType.WaitAndAcquire, exclusiveLockOptions, CancellationToken.None, () => { var logger = Providers.Instance.GetProvider <ILogger <SnILogger> >(); var patchManager = new PatchManager(builder, logRecord => { logRecord.WriteTo(logger); }); patchManager.ExecutePatchesOnBeforeStart(); repositoryInstance = Start((RepositoryStartSettings)builder); var permissions = initialData?.Permissions; if (permissions != null && permissions.Count > 0) { SecurityHandler.SecurityInstaller.InstallDefaultSecurityStructure(initialData); } var indexingEngine = Providers.Instance.SearchEngine.IndexingEngine; if (indexingEngine.Running && initialData?.IndexDocuments != null) { indexingEngine.ClearIndexAsync(CancellationToken.None) .ConfigureAwait(false).GetAwaiter().GetResult(); indexingEngine.WriteIndexAsync(null, null, initialData.IndexDocuments, CancellationToken.None) .ConfigureAwait(false).GetAwaiter().GetResult(); } patchManager.ExecutePatchesOnAfterStart(); RepositoryVersionInfo.Reset(); return(System.Threading.Tasks.Task.CompletedTask); }).GetAwaiter().GetResult(); return(repositoryInstance); }
/// <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 (SenseNet.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) { if (!settings.ExecutingPatches) { // Switch ON this flag so that inner repository start operations // do not try to execute patches again recursively. settings.ExecutingPatches = true; //TODO: [auto-patch] this feature is not released yet //PackageManager.ExecuteAssemblyPatches(settings); } var instance = RepositoryInstance.Start(settings); SystemAccount.Execute(() => Root); 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; SnLog.WriteError(string.Format(template, Indexing.IndexLockFileWaitForRemovedTimeout, AppDomain.CurrentDomain.FriendlyName, AppDomain.CurrentDomain.BaseDirectory)); if (waitType == WaitForLockFileType.OnStart) { RepositoryInstance.SendWaitForLockErrorMail(); } } }
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 (SqlException) //Workaround for VPN connectivity problem in LR office { Thread.Sleep(5000); try { instance.DoStart(); } catch (Exception) { _instance = null; throw; } } catch (Exception) { _instance = null; throw; } _started = true; } } } return(_instance); }
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 (SqlException) //Workaround for VPN connectivity problem in LR office { Thread.Sleep(5000); try { instance.DoStart(); } catch (Exception) { _instance = null; throw; } } catch (Exception) { _instance = null; throw; } _started = true; } } } return _instance; }
internal static void Shutdown() { _instance.ConsoleWriteLine(); DistributedApplication.ClusterChannel.ShutDown(); if (Instance.StartSettings.BackupIndexAtTheEnd) { if (LuceneManagerIsRunning) { _instance.ConsoleWriteLine("Backing up the index..."); SenseNet.Search.Indexing.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) SenseNet.Search.Indexing.LuceneManager.ShutDown(); WaitForWriterLockFileIsReleased(WaitForLockFileType.OnEnd); var t = DateTime.Now - _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(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()); }
internal static void Shutdown() { if (_instance == null) { SnLog.WriteWarning("Repository shutdown has already completed."); return; } lock (_shutDownSync) { if (_instance == null) { SnLog.WriteWarning("Repository shutdown has already completed."); return; } SnTrace.Repository.Write("Sending a goodbye message."); _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) { SnTrace.Repository.Write("Shutting down {0}", svc.GetType().Name); svc.Shutdown(); } SnTrace.Repository.Write("Shutting down {0}", DistributedApplication.ClusterChannel.GetType().Name); DistributedApplication.ClusterChannel.ShutDown(); if (Instance.StartSettings.BackupIndexAtTheEnd) { SnTrace.Repository.Write("Backing up the index."); if (LuceneManagerIsRunning) { _instance.ConsoleWriteLine("Backing up the index..."); SenseNet.Search.Indexing.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) { SnTrace.Repository.Write("Shutting down LuceneManager."); SenseNet.Search.Indexing.LuceneManager.ShutDown(); } SnTrace.Repository.Write("Waiting for writer lock file is released."); WaitForWriterLockFileIsReleased(WaitForLockFileType.OnEnd); 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); SnTrace.Repository.Write(msg); SnTrace.Flush(); _instance.ConsoleWriteLine(msg); _instance.ConsoleWriteLine(); SnLog.WriteInformation(msg); _instance = null; } }
public static RepositoryInstance Start(RepositoryBuilder builder) { var connectionStrings = builder.Services?.GetRequiredService <IOptions <ConnectionStringOptions> >(); Providers.Instance.InitializeBlobProviders(connectionStrings?.Value ?? new ConnectionStringOptions()); EnsureDatabase(builder); var initialData = builder.InitialData; if (initialData != null) { Providers.Instance.DataStore.InstallInitialDataAsync(initialData, CancellationToken.None) .GetAwaiter().GetResult(); } RepositoryInstance repositoryInstance = null; var exclusiveLockOptions = builder.Services?.GetService <IOptions <ExclusiveLockOptions> >()?.Value; ExclusiveBlock.RunAsync("SenseNet.PatchManager", Guid.NewGuid().ToString(), ExclusiveBlockType.WaitAndAcquire, exclusiveLockOptions, CancellationToken.None, () => { var logger = Providers.Instance.GetProvider <ILogger <SnILogger> >(); var patchManager = new PatchManager(builder, logRecord => { logRecord.WriteTo(logger); }); patchManager.ExecutePatchesOnBeforeStart(); repositoryInstance = Start((RepositoryStartSettings)builder); var permissions = initialData?.Permissions; if (permissions != null && permissions.Count > 0) { new SecurityInstaller(Providers.Instance.SecurityHandler, Providers.Instance.StorageSchema, Providers.Instance.DataStore).InstallDefaultSecurityStructure(initialData); } var indexingEngine = Providers.Instance.SearchEngine.IndexingEngine; if (indexingEngine.Running) { if (initialData?.IndexDocuments != null) { // Build the index from an in-memory structure. This is a developer use case. indexingEngine.ClearIndexAsync(CancellationToken.None) .ConfigureAwait(false).GetAwaiter().GetResult(); indexingEngine.WriteIndexAsync(null, null, initialData.IndexDocuments, CancellationToken.None) .ConfigureAwait(false).GetAwaiter().GetResult(); } else { // make sure the index exists and contains documents EnsureIndex(builder); } } patchManager.ExecutePatchesOnAfterStart(); RepositoryVersionInfo.Reset(); return(System.Threading.Tasks.Task.CompletedTask); }).GetAwaiter().GetResult(); return(repositoryInstance); }