Skip to content
This repository has been archived by the owner on Jul 9, 2023. It is now read-only.

Add Autoscale options #54

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 12 additions & 2 deletions src/Orleans.Clustering.CosmosDB/CosmosDBMembershipTable.cs
Original file line number Diff line number Diff line change
Expand Up @@ -409,8 +409,18 @@ private async Task TryCreateCosmosDBResources()
//}
containerProperties.IndexingPolicy.IndexingMode = IndexingMode.Consistent;

await dbResponse.CreateContainerIfNotExistsAsync(
containerProperties, this._options.CollectionThroughput);
if (this._options.UseDedicatedThroughput)
{
ThroughputProperties throughputProperties = this._options.UseAutoscaleThroughput
? ThroughputProperties.CreateAutoscaleThroughput(this._options.AutoscaleThroughputMax)
: ThroughputProperties.CreateManualThroughput(this._options.CollectionThroughput);

await dbResponse.CreateContainerIfNotExistsAsync(containerProperties, throughputProperties);
}
else
{
await dbResponse.CreateContainerIfNotExistsAsync(containerProperties);
}
}

public async Task CleanupDefunctSiloEntries(DateTimeOffset beforeDate)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,10 @@ public class CosmosDBClusteringOptions
{
private const string ORLEANS_DB = "Orleans";
private const string ORLEANS_CLUSTER_COLLECTION = "OrleansCluster";
private const bool ORLEANS_CLUSTER_DEDICATED_THROUGHPUT_ENABLED = true;
private const int ORLEANS_CLUSTER_COLLECTION_THROUGHPUT = 400;
private const bool ORLEANS_CLUSTER_AUTOSCALE_THROUGHPUT_ENABLED = false;
private const int ORLEANS_CLUSTER_AUTOSCALE_THROUGHPUT_MAX = 4000;

public CosmosClient Client { get; set; }
public string AccountEndpoint { get; set; }
Expand All @@ -17,7 +20,11 @@ public class CosmosDBClusteringOptions
public bool CanCreateResources { get; set; }
public string DB { get; set; } = ORLEANS_DB;
public string Collection { get; set; } = ORLEANS_CLUSTER_COLLECTION;
public bool UseDedicatedThroughput { get; set; } = ORLEANS_CLUSTER_DEDICATED_THROUGHPUT_ENABLED;
public int CollectionThroughput { get; set; } = ORLEANS_CLUSTER_COLLECTION_THROUGHPUT;
public bool UseAutoscaleThroughput { get; set; } = ORLEANS_CLUSTER_AUTOSCALE_THROUGHPUT_ENABLED;
public int AutoscaleThroughputMax { get; set; } = ORLEANS_CLUSTER_AUTOSCALE_THROUGHPUT_MAX;


[JsonConverter(typeof(StringEnumConverter))]
public ConnectionMode ConnectionMode { get; set; } = ConnectionMode.Direct;
Expand Down
35 changes: 28 additions & 7 deletions src/Orleans.Persistence.CosmosDB/CosmosDBGrainStorage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -405,12 +405,21 @@ private static bool IsNumericType(Type o)

private async Task TryCreateCosmosDBResources()
{
var offerThroughput =
this._options.DatabaseThroughput >= 400
? (int?)this._options.DatabaseThroughput
: null;
DatabaseResponse dbResponse;

if (this._options.DatabaseUseSharedThroughput)
{
var throughputProperties = this._options.DatabaseUseAutoscaleThroughput
? ThroughputProperties.CreateAutoscaleThroughput(this._options.DatabaseAutoscaleThroughputMax)
: ThroughputProperties.CreateManualThroughput(this._options.DatabaseThroughput);

dbResponse = await this._cosmos.CreateDatabaseIfNotExistsAsync(this._options.DB, throughputProperties);
}
else
{
dbResponse = await this._cosmos.CreateDatabaseIfNotExistsAsync(this._options.DB);
}

var dbResponse = await this._cosmos.CreateDatabaseIfNotExistsAsync(this._options.DB, offerThroughput);
var db = dbResponse.Database;

var stateCollection = new ContainerProperties(this._options.Collection, DEFAULT_PARTITION_KEY_PATH);
Expand All @@ -430,8 +439,20 @@ private async Task TryCreateCosmosDBResources()
const int maxRetries = 3;
for (var retry = 0; retry <= maxRetries; ++retry)
{
var collResponse = await db.CreateContainerIfNotExistsAsync(
stateCollection, offerThroughput);
ContainerResponse collResponse;

if (this._options.CollectionUseDedicatedThroughput)
{
var throughputProperties = this._options.CollectionUseAutoscaleThroughput
? ThroughputProperties.CreateAutoscaleThroughput(this._options.CollectionAutoscaleThroughputMax)
: ThroughputProperties.CreateManualThroughput(this._options.CollectionThroughput);

collResponse = await db.CreateContainerIfNotExistsAsync(stateCollection, throughputProperties);
}
else
{
collResponse = await db.CreateContainerIfNotExistsAsync(stateCollection);
}

if (collResponse.StatusCode == HttpStatusCode.OK || collResponse.StatusCode == HttpStatusCode.Created)
{
Expand Down
36 changes: 34 additions & 2 deletions src/Orleans.Persistence.CosmosDB/Options/CosmosDBStorageOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,11 @@ public class CosmosDBStorageOptions
{
private const string ORLEANS_DB = "Orleans";
internal const string ORLEANS_STORAGE_COLLECTION = "OrleansStorage";
private const bool ORLEANS_STORAGE_DEDICATED_THROUGHPUT_ENABLED = true;
private const bool ORLEANS_STORAGE_SHARED_THROUGHPUT_ENABLED = true;
private const int ORLEANS_STORAGE_COLLECTION_THROUGHPUT = 400;
private const bool ORLEANS_STORAGE_AUTOSCALE_THROUGHPUT_ENABLED = false;
private const int ORLEANS_STORAGE_AUTOSCALE_THROUGHPUT_MAX = 4000;

public CosmosClient Client { get; set; }

Expand All @@ -23,11 +27,19 @@ public class CosmosDBStorageOptions
/// Database configured throughput, if set to 0 it will not be configured and collection throughput must be set. See https://docs.microsoft.com/en-us/azure/cosmos-db/set-throughput
/// </summary>
public int DatabaseThroughput { get; set; } = ORLEANS_STORAGE_COLLECTION_THROUGHPUT;
public bool DatabaseUseSharedThroughput { get; set; } = ORLEANS_STORAGE_SHARED_THROUGHPUT_ENABLED;
public bool DatabaseUseAutoscaleThroughput { get; set; } = ORLEANS_STORAGE_AUTOSCALE_THROUGHPUT_ENABLED;
public int DatabaseAutoscaleThroughputMax { get; set; } = ORLEANS_STORAGE_AUTOSCALE_THROUGHPUT_MAX;

public string Collection { get; set; } = ORLEANS_STORAGE_COLLECTION;
/// <summary>
/// RU units for collection, can be set to 0 if throughput is specified on database level. See https://docs.microsoft.com/en-us/azure/cosmos-db/set-throughput
/// </summary>
public int CollectionThroughput { get; set; } = ORLEANS_STORAGE_COLLECTION_THROUGHPUT;
public bool CollectionUseDedicatedThroughput { get; set; } = ORLEANS_STORAGE_DEDICATED_THROUGHPUT_ENABLED;
public bool CollectionUseAutoscaleThroughput { get; set; } = ORLEANS_STORAGE_AUTOSCALE_THROUGHPUT_ENABLED;
public int CollectionAutoscaleThroughputMax { get; set; } = ORLEANS_STORAGE_AUTOSCALE_THROUGHPUT_MAX;

public bool CanCreateResources { get; set; }
public bool DeleteStateOnClear { get; set; }

Expand Down Expand Up @@ -95,9 +107,29 @@ public void ValidateConfiguration()
throw new OrleansConfigurationException(
$"Configuration for CosmosDBStorage {this.name} is invalid. {nameof(this.options.Collection)} is not valid.");

if (this.options.CollectionThroughput < 400 && this.options.DatabaseThroughput < 400)
if (!this.options.CollectionUseDedicatedThroughput && !this.options.DatabaseUseSharedThroughput)
throw new OrleansConfigurationException(
$"Configuration for CosmosDBStorage {this.name} is invalid. Either {nameof(this.options.CollectionUseDedicatedThroughput)} and/or {nameof(this.options.DatabaseUseSharedThroughput)} must be true");

if (this.options.CollectionUseAutoscaleThroughput && !this.options.CollectionUseDedicatedThroughput)
throw new OrleansConfigurationException(
$"Configuration for CosmosDBStorage {this.name} is invalid. If {nameof(this.options.CollectionUseAutoscaleThroughput)} is true, {nameof(this.options.CollectionUseDedicatedThroughput)} must also be true.");

if (this.options.CollectionUseAutoscaleThroughput && this.options.CollectionAutoscaleThroughputMax < 4000)
throw new OrleansConfigurationException(
$"Configuration for CosmosDBStorage {this.name} is invalid. {nameof(this.options.CollectionAutoscaleThroughputMax)} must be 4000 or greater.");

if (this.options.DatabaseUseAutoscaleThroughput && this.options.DatabaseAutoscaleThroughputMax < 4000)
throw new OrleansConfigurationException(
$"Configuration for CosmosDBStorage {this.name} is invalid. {nameof(this.options.DatabaseAutoscaleThroughputMax)} must be 4000 or greater.");

if (!this.options.CollectionUseAutoscaleThroughput && this.options.CollectionThroughput < 400)
throw new OrleansConfigurationException(
$"Configuration for CosmosDBStorage {this.name} is invalid. {nameof(this.options.CollectionThroughput)} must be 400 or greater.");

if (!this.options.DatabaseUseAutoscaleThroughput && this.options.DatabaseThroughput < 400)
throw new OrleansConfigurationException(
$"Configuration for CosmosDBStorage {this.name} is invalid. Either {nameof(this.options.DatabaseThroughput)} or {nameof(this.options.CollectionThroughput)} must exceed 400.");
$"Configuration for CosmosDBStorage {this.name} is invalid. {nameof(this.options.DatabaseThroughput)} must be 400 or greater.");
}
}
}
35 changes: 28 additions & 7 deletions src/Orleans.Reminders.CosmosDB/CosmosDBReminderTable.cs
Original file line number Diff line number Diff line change
Expand Up @@ -375,12 +375,21 @@ private async Task TryDeleteDatabase()

private async Task TryCreateCosmosDBResources()
{
var offerThroughput =
this._options.CollectionThroughput >= 400
? (int?)this._options.CollectionThroughput
: null;
DatabaseResponse dbResponse;

if (this._options.DatabaseUseSharedThroughput)
{
var throughputProperties = this._options.DatabaseUseAutoscaleThroughput
? ThroughputProperties.CreateAutoscaleThroughput(this._options.DatabaseAutoscaleThroughputMax)
: ThroughputProperties.CreateManualThroughput(this._options.DatabaseThroughput);

dbResponse = await this._cosmos.CreateDatabaseIfNotExistsAsync(this._options.DB, throughputProperties);
}
else
{
dbResponse = await this._cosmos.CreateDatabaseIfNotExistsAsync(this._options.DB);
}

var dbResponse = await this._cosmos.CreateDatabaseIfNotExistsAsync(this._options.DB, offerThroughput);
var db = dbResponse.Database;

var remindersCollection = new ContainerProperties(this._options.Collection, PARTITION_KEY_PATH);
Expand All @@ -394,8 +403,20 @@ private async Task TryCreateCosmosDBResources()
const int maxRetries = 3;
for (var retry = 0; retry <= maxRetries; ++retry)
{
var collResponse = await db.CreateContainerIfNotExistsAsync(
remindersCollection, offerThroughput);
ContainerResponse collResponse;

if (this._options.CollectionUseDedicatedThroughput)
{
var throughputProperties = this._options.CollectionUseAutoscaleThroughput
? ThroughputProperties.CreateAutoscaleThroughput(this._options.CollectionAutoscaleThroughputMax)
: ThroughputProperties.CreateManualThroughput(this._options.CollectionThroughput);

collResponse = await db.CreateContainerIfNotExistsAsync(remindersCollection, throughputProperties);
}
else
{
collResponse = await db.CreateContainerIfNotExistsAsync(remindersCollection);
}

if (retry == maxRetries || dbResponse.StatusCode != HttpStatusCode.Created || collResponse.StatusCode == HttpStatusCode.Created)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,25 @@ public class CosmosDBReminderStorageOptions
{
private const string ORLEANS_DB = "Orleans";
private const string ORLEANS_REMINDERS_COLLECTION = "OrleansReminders";
private const bool ORLEANS_STORAGE_DEDICATED_THROUGHPUT_ENABLED = true;
private const bool ORLEANS_STORAGE_SHARED_THROUGHPUT_ENABLED = true;
private const int ORLEANS_STORAGE_COLLECTION_THROUGHPUT = 400;
private const bool ORLEANS_STORAGE_AUTOSCALE_THROUGHPUT_ENABLED = false;
private const int ORLEANS_STORAGE_AUTOSCALE_THROUGHPUT_MAX = 4000;
public CosmosClient Client { get; set; }
public string AccountEndpoint { get; set; }
[Redact]
public string AccountKey { get; set; }
public string DB { get; set; } = ORLEANS_DB;
public int DatabaseThroughput { get; set; } = ORLEANS_STORAGE_COLLECTION_THROUGHPUT;
public bool DatabaseUseSharedThroughput { get; set; } = ORLEANS_STORAGE_SHARED_THROUGHPUT_ENABLED;
public bool DatabaseUseAutoscaleThroughput { get; set; } = ORLEANS_STORAGE_AUTOSCALE_THROUGHPUT_ENABLED;
public int DatabaseAutoscaleThroughputMax { get; set; } = ORLEANS_STORAGE_AUTOSCALE_THROUGHPUT_MAX;
public string Collection { get; set; } = ORLEANS_REMINDERS_COLLECTION;
public int CollectionThroughput { get; set; } = ORLEANS_STORAGE_COLLECTION_THROUGHPUT;
public bool CollectionUseDedicatedThroughput { get; set; } = ORLEANS_STORAGE_DEDICATED_THROUGHPUT_ENABLED;
public bool CollectionUseAutoscaleThroughput { get; set; } = ORLEANS_STORAGE_AUTOSCALE_THROUGHPUT_ENABLED;
public int CollectionAutoscaleThroughputMax { get; set; } = ORLEANS_STORAGE_AUTOSCALE_THROUGHPUT_MAX;
public bool CanCreateResources { get; set; }

[JsonConverter(typeof(StringEnumConverter))]
Expand Down