forked from ravendb/ravendb
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
10 changed files
with
548 additions
and
2 deletions.
There are no files selected for viewing
104 changes: 104 additions & 0 deletions
104
Bundles/Raven.Bundles.LiveTest/LiveTestDatabaseCleanerStartupTask.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
// ----------------------------------------------------------------------- | ||
// <copyright file="LiveTestDatabaseCleanerStartupTask.cs" company="Hibernating Rhinos LTD"> | ||
// Copyright (c) Hibernating Rhinos LTD. All rights reserved. | ||
// </copyright> | ||
// ----------------------------------------------------------------------- | ||
using System; | ||
using System.Configuration; | ||
using System.Linq; | ||
using System.Threading; | ||
|
||
using Raven.Abstractions; | ||
using Raven.Abstractions.Data; | ||
using Raven.Database.Extensions; | ||
using Raven.Database.Plugins; | ||
using Raven.Json.Linq; | ||
using Raven.Server; | ||
|
||
namespace Raven.Bundles.LiveTest | ||
{ | ||
public class LiveTestDatabaseCleanerStartupTask : IServerStartupTask | ||
{ | ||
private Timer checkTimer; | ||
|
||
private RavenDbServer server; | ||
|
||
private TimeSpan maxTimeDatabaseCanBeIdle; | ||
|
||
public void Execute(RavenDbServer server) | ||
{ | ||
this.server = server; | ||
|
||
int val; | ||
if (int.TryParse(ConfigurationManager.AppSettings["Raven/Bundles/LiveTest/Tenants/MaxIdleTimeForTenantDatabase"], out val) == false) | ||
val = 900; | ||
|
||
maxTimeDatabaseCanBeIdle = TimeSpan.FromSeconds(val); ; | ||
|
||
checkTimer = new Timer(ExecuteCleanup, null, TimeSpan.FromMinutes(1), TimeSpan.FromMinutes(10)); | ||
} | ||
|
||
public void Dispose() | ||
{ | ||
if (checkTimer != null) | ||
checkTimer.Dispose(); | ||
} | ||
|
||
private void ExecuteCleanup(object state) | ||
{ | ||
var databaseLandLord = server.Options.DatabaseLandlord; | ||
var systemDatabase = databaseLandLord.SystemDatabase; | ||
if (server.Disposed) | ||
{ | ||
Dispose(); | ||
return; | ||
} | ||
|
||
int nextStart = 0; | ||
var databaseDocuments = systemDatabase | ||
.Documents | ||
.GetDocumentsWithIdStartingWith(Constants.RavenDatabasesPrefix, null, null, 0, int.MaxValue, CancellationToken.None, ref nextStart); | ||
|
||
var databaseIds = databaseDocuments | ||
.Select(x => ((RavenJObject)x)["@metadata"]) | ||
.Where(x => x != null) | ||
.Select(x => x.Value<string>("@id")) | ||
.Where(x => x != null && x != Constants.SystemDatabase) | ||
.ToList(); | ||
|
||
foreach (var databaseId in databaseIds) | ||
{ | ||
var key = databaseId; | ||
if (key.StartsWith(Constants.RavenDatabasesPrefix)) | ||
key = key.Substring(Constants.RavenDatabasesPrefix.Length); | ||
|
||
var shouldCleanup = false; | ||
|
||
DateTime value; | ||
if (databaseLandLord.IsDatabaseLoaded(key) == false) | ||
shouldCleanup = true; | ||
else if (databaseLandLord.LastRecentlyUsed.TryGetValue(key, out value) && (SystemTime.UtcNow - value) > maxTimeDatabaseCanBeIdle) | ||
shouldCleanup = true; | ||
|
||
if (shouldCleanup == false) | ||
continue; | ||
|
||
var configuration = databaseLandLord.CreateTenantConfiguration(key, true); | ||
|
||
databaseLandLord.Cleanup(key, maxTimeDatabaseCanBeIdle, database => false); | ||
|
||
var docKey = Constants.RavenDatabasesPrefix + key; | ||
systemDatabase.Documents.Delete(docKey, null, null); | ||
|
||
if (configuration == null) | ||
continue; | ||
|
||
IOExtensions.DeleteDirectory(configuration.DataDirectory); | ||
if (configuration.IndexStoragePath != null) | ||
IOExtensions.DeleteDirectory(configuration.IndexStoragePath); | ||
if (configuration.JournalsStoragePath != null) | ||
IOExtensions.DeleteDirectory(configuration.JournalsStoragePath); | ||
} | ||
} | ||
} | ||
} |
75 changes: 75 additions & 0 deletions
75
Bundles/Raven.Bundles.LiveTest/LiveTestDatabaseDocumentPutTrigger.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
// ----------------------------------------------------------------------- | ||
// <copyright file="LiveTestDatabaseCreationTrigger.cs" company="Hibernating Rhinos LTD"> | ||
// Copyright (c) Hibernating Rhinos LTD. All rights reserved. | ||
// </copyright> | ||
// ----------------------------------------------------------------------- | ||
using System; | ||
using System.Configuration; | ||
|
||
using Raven.Abstractions.Data; | ||
using Raven.Database.Config; | ||
using Raven.Database.Extensions; | ||
using Raven.Database.Plugins; | ||
using Raven.Json.Linq; | ||
|
||
namespace Raven.Bundles.LiveTest | ||
{ | ||
public class LiveTestDatabaseDocumentPutTrigger : AbstractPutTrigger | ||
{ | ||
private const int QuotasHardLimitInKb = 512 * 1024; | ||
|
||
private const int QuotasSoftMarginInKb = (int)(0.75 * QuotasHardLimitInKb); | ||
|
||
public override void OnPut(string key, RavenJObject document, RavenJObject metadata, TransactionInformation transactionInformation) | ||
{ | ||
if (string.IsNullOrEmpty(Database.Name) == false && Database.Name != Constants.SystemDatabase) | ||
return; | ||
|
||
if (key.StartsWith(Constants.RavenDatabasesPrefix, StringComparison.OrdinalIgnoreCase) == false) | ||
return; | ||
|
||
RavenJObject settings; | ||
RavenJToken value; | ||
if (document.TryGetValue("Settings", out value) == false) | ||
document["Settings"] = settings = new RavenJObject(); | ||
else | ||
settings = (RavenJObject)value; | ||
|
||
EnsureQuotasBundleActivated(settings); | ||
EnsureVoronIsSetAsStorageEngineAndIsRunningInMemory(settings); | ||
} | ||
|
||
private static void EnsureVoronIsSetAsStorageEngineAndIsRunningInMemory(RavenJObject settings) | ||
{ | ||
settings["Raven/StorageEngine"] = InMemoryRavenConfiguration.VoronTypeName; | ||
settings["Raven/RunInMemory"] = true; | ||
} | ||
|
||
private static void EnsureQuotasBundleActivated(RavenJObject settings) | ||
{ | ||
RavenJToken value; | ||
if (settings.TryGetValue(Constants.ActiveBundles, out value) == false) | ||
settings[Constants.ActiveBundles] = value = new RavenJValue(string.Empty); | ||
|
||
var activeBundles = value.Value<string>(); | ||
var bundles = activeBundles.GetSemicolonSeparatedValues(); | ||
|
||
if (bundles.Contains("Quotas") == false) | ||
bundles.Add("Quotas"); | ||
|
||
int hardLimitInKb; | ||
if (int.TryParse(ConfigurationManager.AppSettings["Raven/Bundles/LiveTest/Quotas/Size/HardLimitInKB"], out hardLimitInKb) == false) | ||
hardLimitInKb = QuotasHardLimitInKb; | ||
|
||
int softMarginInKb; | ||
if (int.TryParse(ConfigurationManager.AppSettings["Raven/Bundles/LiveTest/Quotas/Size/SoftLimitInKB"], out softMarginInKb) == false) | ||
softMarginInKb = QuotasSoftMarginInKb; | ||
|
||
settings[Constants.ActiveBundles] = string.Join(";", bundles); | ||
settings[Constants.SizeHardLimitInKB] = hardLimitInKb; | ||
settings[Constants.SizeSoftLimitInKB] = softMarginInKb; | ||
settings[Constants.DocsHardLimit] = null; | ||
settings[Constants.DocsSoftLimit] = null; | ||
} | ||
} | ||
} |
79 changes: 79 additions & 0 deletions
79
Bundles/Raven.Bundles.LiveTest/Raven.Bundles.LiveTest.csproj
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
<?xml version="1.0" encoding="utf-8"?> | ||
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> | ||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" /> | ||
<PropertyGroup> | ||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> | ||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> | ||
<ProjectGuid>{108260D1-12ED-4EC5-8C6B-1DED1D73271F}</ProjectGuid> | ||
<OutputType>Library</OutputType> | ||
<AppDesignerFolder>Properties</AppDesignerFolder> | ||
<RootNamespace>Raven.Bundles.LiveTest</RootNamespace> | ||
<AssemblyName>Raven.Bundles.LiveTest</AssemblyName> | ||
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion> | ||
<FileAlignment>512</FileAlignment> | ||
</PropertyGroup> | ||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> | ||
<DebugSymbols>true</DebugSymbols> | ||
<DebugType>full</DebugType> | ||
<Optimize>false</Optimize> | ||
<OutputPath>bin\Debug\</OutputPath> | ||
<DefineConstants>DEBUG;TRACE</DefineConstants> | ||
<ErrorReport>prompt</ErrorReport> | ||
<WarningLevel>4</WarningLevel> | ||
</PropertyGroup> | ||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> | ||
<DebugType>pdbonly</DebugType> | ||
<Optimize>true</Optimize> | ||
<OutputPath>bin\Release\</OutputPath> | ||
<DefineConstants>TRACE</DefineConstants> | ||
<ErrorReport>prompt</ErrorReport> | ||
<WarningLevel>4</WarningLevel> | ||
</PropertyGroup> | ||
<PropertyGroup> | ||
<SignAssembly>true</SignAssembly> | ||
</PropertyGroup> | ||
<PropertyGroup> | ||
<AssemblyOriginatorKeyFile>..\..\Raven.Database\RavenDB.snk</AssemblyOriginatorKeyFile> | ||
</PropertyGroup> | ||
<ItemGroup> | ||
<Reference Include="System" /> | ||
<Reference Include="System.Configuration" /> | ||
<Reference Include="System.Core" /> | ||
<Reference Include="System.Xml.Linq" /> | ||
<Reference Include="System.Data.DataSetExtensions" /> | ||
<Reference Include="Microsoft.CSharp" /> | ||
<Reference Include="System.Data" /> | ||
<Reference Include="System.Xml" /> | ||
</ItemGroup> | ||
<ItemGroup> | ||
<Compile Include="..\..\CommonAssemblyInfo.cs"> | ||
<Link>Properties\CommonAssemblyInfo.cs</Link> | ||
</Compile> | ||
<Compile Include="LiveTestDatabaseCleanerStartupTask.cs" /> | ||
<Compile Include="LiveTestDatabaseDocumentPutTrigger.cs" /> | ||
</ItemGroup> | ||
<ItemGroup> | ||
<ProjectReference Include="..\..\Raven.Abstractions\Raven.Abstractions.csproj"> | ||
<Project>{41ac479e-1eb2-4d23-aaf2-e4c8df1bc2ba}</Project> | ||
<Name>Raven.Abstractions</Name> | ||
</ProjectReference> | ||
<ProjectReference Include="..\..\Raven.Database\Raven.Database.csproj"> | ||
<Project>{212823cd-25e1-41ac-92d1-d6df4d53fc85}</Project> | ||
<Name>Raven.Database</Name> | ||
</ProjectReference> | ||
</ItemGroup> | ||
<ItemGroup /> | ||
<ItemGroup> | ||
<None Include="..\..\Raven.Database\RavenDB.snk"> | ||
<Link>RavenDB.snk</Link> | ||
</None> | ||
</ItemGroup> | ||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> | ||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it. | ||
Other similar extension points exist, see Microsoft.Common.targets. | ||
<Target Name="BeforeBuild"> | ||
</Target> | ||
<Target Name="AfterBuild"> | ||
</Target> | ||
--> | ||
</Project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
// ----------------------------------------------------------------------- | ||
// <copyright file="PutTriggerTests.cs" company="Hibernating Rhinos LTD"> | ||
// Copyright (c) Hibernating Rhinos LTD. All rights reserved. | ||
// </copyright> | ||
// ----------------------------------------------------------------------- | ||
using System.ComponentModel.Composition.Hosting; | ||
using System.Configuration; | ||
|
||
using Raven.Abstractions.Data; | ||
using Raven.Bundles.LiveTest; | ||
using Raven.Client.Connection; | ||
using Raven.Database.Config; | ||
using Raven.Database.Extensions; | ||
using Raven.Json.Linq; | ||
using Raven.Tests.Common; | ||
|
||
using Xunit; | ||
|
||
namespace Raven.Tests.Bundles.LiveTest | ||
{ | ||
public class PutTriggerTests : RavenTest | ||
{ | ||
protected override void ModifyConfiguration(InMemoryRavenConfiguration configuration) | ||
{ | ||
configuration.Catalog.Catalogs.Add(new AssemblyCatalog(typeof(LiveTestDatabaseDocumentPutTrigger).Assembly)); | ||
} | ||
|
||
[Fact] | ||
public void PutTriggerShouldEnableQuotasAndVoron() | ||
{ | ||
using (var store = NewDocumentStore()) | ||
{ | ||
store | ||
.DatabaseCommands | ||
.GlobalAdmin | ||
.CreateDatabase(new DatabaseDocument | ||
{ | ||
Id = "Northwind", | ||
Settings = | ||
{ | ||
{ "Raven/ActiveBundles", "Replication" }, | ||
{ "Raven/DataDir", NewDataPath() } | ||
} | ||
}); | ||
|
||
var document = store.DatabaseCommands.Get("Raven/Databases/Northwind"); | ||
Assert.NotNull(document); | ||
|
||
var databaseDocument = document.DataAsJson.Deserialize<DatabaseDocument>(store.Conventions); | ||
AsserDatabaseDocument(databaseDocument); | ||
|
||
databaseDocument.Settings[Constants.SizeHardLimitInKB] = "123"; | ||
databaseDocument.Settings[Constants.SizeSoftLimitInKB] = "321"; | ||
databaseDocument.Settings[Constants.DocsHardLimit] = "456"; | ||
databaseDocument.Settings[Constants.DocsSoftLimit] = "654"; | ||
databaseDocument.Settings["Raven/RunInMemory"] = "false"; | ||
databaseDocument.Settings["Raven/StorageEngine"] = "esent"; | ||
|
||
store.DatabaseCommands.Put("Raven/Databases/Northwind", null, RavenJObject.FromObject(databaseDocument), document.Metadata); | ||
|
||
document = store.DatabaseCommands.Get("Raven/Databases/Northwind"); | ||
Assert.NotNull(document); | ||
|
||
databaseDocument = document.DataAsJson.Deserialize<DatabaseDocument>(store.Conventions); | ||
AsserDatabaseDocument(databaseDocument); | ||
} | ||
} | ||
|
||
private static void AsserDatabaseDocument(DatabaseDocument databaseDocument) | ||
{ | ||
var activeBundles = databaseDocument.Settings[Constants.ActiveBundles].GetSemicolonSeparatedValues(); | ||
|
||
Assert.Contains("Replication", activeBundles); | ||
|
||
Assert.Contains("Quotas", activeBundles); | ||
Assert.Equal(ConfigurationManager.AppSettings["Raven/Bundles/LiveTest/Quotas/Size/HardLimitInKB"], databaseDocument.Settings[Constants.SizeHardLimitInKB]); | ||
Assert.Equal(ConfigurationManager.AppSettings["Raven/Bundles/LiveTest/Quotas/Size/SoftLimitInKB"], databaseDocument.Settings[Constants.SizeSoftLimitInKB]); | ||
Assert.Null(databaseDocument.Settings[Constants.DocsHardLimit]); | ||
Assert.Null(databaseDocument.Settings[Constants.DocsSoftLimit]); | ||
|
||
Assert.True(bool.Parse(databaseDocument.Settings["Raven/RunInMemory"])); | ||
Assert.Equal(InMemoryRavenConfiguration.VoronTypeName, databaseDocument.Settings["Raven/StorageEngine"]); | ||
} | ||
} | ||
} |
Oops, something went wrong.