diff --git a/Orleans.sln b/Orleans.sln index 33448fa97b..b3b09a96e5 100644 --- a/Orleans.sln +++ b/Orleans.sln @@ -1,6 +1,6 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 15 -VisualStudioVersion = 15.0.27130.2010 +VisualStudioVersion = 15.0.27130.2024 MinimumVisualStudioVersion = 10.0.40219.1 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{4CD3AA9E-D937-48CA-BB6C-158E12257D23}" EndProject diff --git a/src/AWS/Orleans.Clustering.DynamoDB/Membership/LegacyDynamoDBMembershipConfigurator.cs b/src/AWS/Orleans.Clustering.DynamoDB/Membership/LegacyDynamoDBMembershipConfigurator.cs index d4de08c6ca..13852b50df 100644 --- a/src/AWS/Orleans.Clustering.DynamoDB/Membership/LegacyDynamoDBMembershipConfigurator.cs +++ b/src/AWS/Orleans.Clustering.DynamoDB/Membership/LegacyDynamoDBMembershipConfigurator.cs @@ -1,4 +1,4 @@ -using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection; using Orleans.Hosting; using Orleans.Runtime.Configuration; @@ -7,9 +7,10 @@ namespace Orleans.Runtime.MembershipService /// public class LegacyDynamoDBMembershipConfigurator : ILegacyMembershipConfigurator { - public void ConfigureServices(GlobalConfiguration configuration, IServiceCollection services) + public void ConfigureServices(object configuration, IServiceCollection services) { - services.UseDynamoDBMembership(options => options.ConnectionString = configuration.DataConnectionString); + var reader = new GlobalConfigurationReader(configuration); + services.UseDynamoDBMembership(options => options.ConnectionString = reader.GetPropertyValue("DataConnectionString")); } } } diff --git a/src/AWS/Orleans.Clustering.DynamoDB/Orleans.Clustering.DynamoDB.csproj b/src/AWS/Orleans.Clustering.DynamoDB/Orleans.Clustering.DynamoDB.csproj index 496d1c4ba5..afbca0cc4f 100644 --- a/src/AWS/Orleans.Clustering.DynamoDB/Orleans.Clustering.DynamoDB.csproj +++ b/src/AWS/Orleans.Clustering.DynamoDB/Orleans.Clustering.DynamoDB.csproj @@ -1,4 +1,4 @@ - + Microsoft.Orleans.Clustering.DynamoDB Microsoft Orleans clustering provider for AWS DynamoDB @@ -22,6 +22,7 @@ + diff --git a/src/AWS/Orleans.Reminders.DynamoDB/Orleans.Reminders.DynamoDB.csproj b/src/AWS/Orleans.Reminders.DynamoDB/Orleans.Reminders.DynamoDB.csproj index 365c29a42d..6cf62665df 100644 --- a/src/AWS/Orleans.Reminders.DynamoDB/Orleans.Reminders.DynamoDB.csproj +++ b/src/AWS/Orleans.Reminders.DynamoDB/Orleans.Reminders.DynamoDB.csproj @@ -1,4 +1,4 @@ - + Microsoft.Orleans.Reminders.DynamoDB Microsoft Orleans Reminders DynamoDB @@ -26,6 +26,7 @@ + diff --git a/src/AWS/Orleans.Reminders.DynamoDB/Reminders/DynamoDBReminderTable.cs b/src/AWS/Orleans.Reminders.DynamoDB/Reminders/DynamoDBReminderTable.cs index 2f58bfee3f..61ea085843 100644 --- a/src/AWS/Orleans.Reminders.DynamoDB/Reminders/DynamoDBReminderTable.cs +++ b/src/AWS/Orleans.Reminders.DynamoDB/Reminders/DynamoDBReminderTable.cs @@ -1,4 +1,4 @@ -using Orleans; +using Orleans; using System; using System.Collections.Generic; using System.Threading.Tasks; @@ -9,6 +9,7 @@ using Microsoft.Extensions.Logging; using Orleans.Reminders.DynamoDB; using Microsoft.Extensions.Options; +using Orleans.Hosting; namespace OrleansAWSUtils.Reminders { @@ -33,6 +34,7 @@ public class DynamoDBReminderTable : IReminderTable private const string TABLE_NAME_DEFAULT_VALUE = "OrleansReminders"; private ILogger logger; private readonly ILoggerFactory loggerFactory; + private readonly StorageOptions storageOptions; private DynamoDBStorage storage; private readonly Guid serviceId; @@ -41,12 +43,13 @@ public class DynamoDBReminderTable : IReminderTable /// /// The grain factory. /// logger factory to use - public DynamoDBReminderTable(IGrainReferenceConverter grainReferenceConverter, ILoggerFactory loggerFactory, IOptions siloOptions) + public DynamoDBReminderTable(IGrainReferenceConverter grainReferenceConverter, ILoggerFactory loggerFactory, IOptions siloOptions, IOptions storageOptions) { this.grainReferenceConverter = grainReferenceConverter; this.logger = loggerFactory.CreateLogger(); this.loggerFactory = loggerFactory; this.serviceId = siloOptions.Value.ServiceId; + this.storageOptions = storageOptions.Value; } /// @@ -54,10 +57,10 @@ public DynamoDBReminderTable(IGrainReferenceConverter grainReferenceConverter, I /// /// Global configuration to initialize with /// - public Task Init(GlobalConfiguration config) + public Task Init() { - storage = new DynamoDBStorage(config.DataConnectionStringForReminders, loggerFactory); - logger.Info(ErrorCode.ReminderServiceBase, "Initializing AWS DynamoDB Reminders Table"); + this.storage = new DynamoDBStorage(this.storageOptions.DataConnectionStringForReminders, this.loggerFactory); + this.logger.Info(ErrorCode.ReminderServiceBase, "Initializing AWS DynamoDB Reminders Table"); var secondaryIndex = new GlobalSecondaryIndex { @@ -70,7 +73,7 @@ public Task Init(GlobalConfiguration config) } }; - return storage.InitializeTable(TABLE_NAME_DEFAULT_VALUE, + return this.storage.InitializeTable(TABLE_NAME_DEFAULT_VALUE, new List { new KeySchemaElement { AttributeName = REMINDER_ID_PROPERTY_NAME, KeyType = KeyType.HASH }, @@ -94,7 +97,7 @@ public Task Init(GlobalConfiguration config) /// Return the RemiderTableData if the rows were read successfully public async Task ReadRow(GrainReference grainRef, string reminderName) { - var reminderId = ConstructReminderId(serviceId, grainRef, reminderName); + var reminderId = ConstructReminderId(this.serviceId, grainRef, reminderName); var keys = new Dictionary { @@ -104,11 +107,11 @@ public async Task ReadRow(GrainReference grainRef, string reminde try { - return await storage.ReadSingleEntryAsync(TABLE_NAME_DEFAULT_VALUE, keys, Resolve).ConfigureAwait(false); + return await this.storage.ReadSingleEntryAsync(TABLE_NAME_DEFAULT_VALUE, keys, this.Resolve).ConfigureAwait(false); } catch (Exception exc) { - logger.Warn(ErrorCode.ReminderServiceBase, + this.logger.Warn(ErrorCode.ReminderServiceBase, $"Intermediate error reading reminder entry {Utils.DictionaryToString(keys)} from table {TABLE_NAME_DEFAULT_VALUE}.", exc); throw; } @@ -123,20 +126,20 @@ public async Task ReadRows(GrainReference grainRef) { var expressionValues = new Dictionary { - { $":{SERVICE_ID_PROPERTY_NAME}", new AttributeValue(serviceId.ToString()) }, + { $":{SERVICE_ID_PROPERTY_NAME}", new AttributeValue(this.serviceId.ToString()) }, { $":{GRAIN_REFERENCE_PROPERTY_NAME}", new AttributeValue(grainRef.ToKeyString()) } }; try { var expression = $"{SERVICE_ID_PROPERTY_NAME} = :{SERVICE_ID_PROPERTY_NAME} AND {GRAIN_REFERENCE_PROPERTY_NAME} = :{GRAIN_REFERENCE_PROPERTY_NAME}"; - var records = await storage.ScanAsync(TABLE_NAME_DEFAULT_VALUE, expressionValues, expression, Resolve).ConfigureAwait(false); + var records = await this.storage.ScanAsync(TABLE_NAME_DEFAULT_VALUE, expressionValues, expression, this.Resolve).ConfigureAwait(false); return new ReminderTableData(records); } catch (Exception exc) { - logger.Warn(ErrorCode.ReminderServiceBase, + this.logger.Warn(ErrorCode.ReminderServiceBase, $"Intermediate error reading reminder entry {Utils.DictionaryToString(expressionValues)} from table {TABLE_NAME_DEFAULT_VALUE}.", exc); throw; } @@ -152,7 +155,7 @@ public async Task ReadRows(uint beginHash, uint endHash) { var expressionValues = new Dictionary { - { $":{SERVICE_ID_PROPERTY_NAME}", new AttributeValue(serviceId.ToString()) }, + { $":{SERVICE_ID_PROPERTY_NAME}", new AttributeValue(this.serviceId.ToString()) }, { $":Begin{GRAIN_HASH_PROPERTY_NAME}", new AttributeValue { N = beginHash.ToString() } }, { $":End{GRAIN_HASH_PROPERTY_NAME}", new AttributeValue { N = endHash.ToString() } } }; @@ -169,13 +172,13 @@ public async Task ReadRows(uint beginHash, uint endHash) expression = $"{SERVICE_ID_PROPERTY_NAME} = :{SERVICE_ID_PROPERTY_NAME} AND ({GRAIN_HASH_PROPERTY_NAME} > :Begin{GRAIN_HASH_PROPERTY_NAME} OR {GRAIN_HASH_PROPERTY_NAME} <= :End{GRAIN_HASH_PROPERTY_NAME})"; } - var records = await storage.ScanAsync(TABLE_NAME_DEFAULT_VALUE, expressionValues, expression, Resolve).ConfigureAwait(false); + var records = await this.storage.ScanAsync(TABLE_NAME_DEFAULT_VALUE, expressionValues, expression, this.Resolve).ConfigureAwait(false); return new ReminderTableData(records); } catch (Exception exc) { - logger.Warn(ErrorCode.ReminderServiceBase, + this.logger.Warn(ErrorCode.ReminderServiceBase, $"Intermediate error reading reminder entry {Utils.DictionaryToString(expressionValues)} from table {TABLE_NAME_DEFAULT_VALUE}.", exc); throw; } @@ -202,7 +205,7 @@ private ReminderEntry Resolve(Dictionary item) /// Return true if the row was removed public async Task RemoveRow(GrainReference grainRef, string reminderName, string eTag) { - var reminderId = ConstructReminderId(serviceId, grainRef, reminderName); + var reminderId = ConstructReminderId(this.serviceId, grainRef, reminderName); var keys = new Dictionary { @@ -215,7 +218,7 @@ public async Task RemoveRow(GrainReference grainRef, string reminderName, var conditionalValues = new Dictionary { { CURRENT_ETAG_ALIAS, new AttributeValue { N = eTag } } }; var expression = $"{ETAG_PROPERTY_NAME} = {CURRENT_ETAG_ALIAS}"; - await storage.DeleteEntryAsync(TABLE_NAME_DEFAULT_VALUE, keys, expression, conditionalValues).ConfigureAwait(false); + await this.storage.DeleteEntryAsync(TABLE_NAME_DEFAULT_VALUE, keys, expression, conditionalValues).ConfigureAwait(false); return true; } catch (ConditionalCheckFailedException) @@ -232,13 +235,13 @@ public async Task TestOnlyClearTable() { var expressionValues = new Dictionary { - { $":{SERVICE_ID_PROPERTY_NAME}", new AttributeValue(serviceId.ToString()) } + { $":{SERVICE_ID_PROPERTY_NAME}", new AttributeValue(this.serviceId.ToString()) } }; try { var expression = $"{SERVICE_ID_PROPERTY_NAME} = :{SERVICE_ID_PROPERTY_NAME}"; - var records = await storage.ScanAsync(TABLE_NAME_DEFAULT_VALUE, expressionValues, expression, + var records = await this.storage.ScanAsync(TABLE_NAME_DEFAULT_VALUE, expressionValues, expression, item => new Dictionary { { REMINDER_ID_PROPERTY_NAME, item[REMINDER_ID_PROPERTY_NAME] }, @@ -247,21 +250,21 @@ public async Task TestOnlyClearTable() if (records.Count <= 25) { - await storage.DeleteEntriesAsync(TABLE_NAME_DEFAULT_VALUE, records); + await this.storage.DeleteEntriesAsync(TABLE_NAME_DEFAULT_VALUE, records); } else { List tasks = new List(); foreach (var batch in records.BatchIEnumerable(25)) { - tasks.Add(storage.DeleteEntriesAsync(TABLE_NAME_DEFAULT_VALUE, batch)); + tasks.Add(this.storage.DeleteEntriesAsync(TABLE_NAME_DEFAULT_VALUE, batch)); } await Task.WhenAll(tasks); } } catch (Exception exc) { - logger.Warn(ErrorCode.ReminderServiceBase, + this.logger.Warn(ErrorCode.ReminderServiceBase, $"Intermediate error removing reminder entries {Utils.DictionaryToString(expressionValues)} from table {TABLE_NAME_DEFAULT_VALUE}.", exc); throw; } @@ -274,32 +277,32 @@ public async Task TestOnlyClearTable() /// Return the entry ETag if entry was upsert successfully public async Task UpsertRow(ReminderEntry entry) { - var reminderId = ConstructReminderId(serviceId, entry.GrainRef, entry.ReminderName); + var reminderId = ConstructReminderId(this.serviceId, entry.GrainRef, entry.ReminderName); var fields = new Dictionary { { REMINDER_ID_PROPERTY_NAME, new AttributeValue(reminderId) }, { GRAIN_HASH_PROPERTY_NAME, new AttributeValue { N = entry.GrainRef.GetUniformHashCode().ToString() } }, - { SERVICE_ID_PROPERTY_NAME, new AttributeValue(serviceId.ToString()) }, + { SERVICE_ID_PROPERTY_NAME, new AttributeValue(this.serviceId.ToString()) }, { GRAIN_REFERENCE_PROPERTY_NAME, new AttributeValue( entry.GrainRef.ToKeyString()) }, { PERIOD_PROPERTY_NAME, new AttributeValue(entry.Period.ToString()) }, { START_TIME_PROPERTY_NAME, new AttributeValue(entry.StartAt.ToString()) }, { REMINDER_NAME_PROPERTY_NAME, new AttributeValue(entry.ReminderName) }, - { ETAG_PROPERTY_NAME, new AttributeValue { N = random.Next(int.MaxValue).ToString() } } + { ETAG_PROPERTY_NAME, new AttributeValue { N = this.random.Next(int.MaxValue).ToString() } } }; try { - if (logger.IsEnabled(LogLevel.Debug)) logger.Debug("UpsertRow entry = {0}, etag = {1}", entry.ToString(), entry.ETag); + if (this.logger.IsEnabled(LogLevel.Debug)) this.logger.Debug("UpsertRow entry = {0}, etag = {1}", entry.ToString(), entry.ETag); - await storage.PutEntryAsync(TABLE_NAME_DEFAULT_VALUE, fields); + await this.storage.PutEntryAsync(TABLE_NAME_DEFAULT_VALUE, fields); entry.ETag = fields[ETAG_PROPERTY_NAME].N; return entry.ETag; } catch (Exception exc) { - logger.Warn(ErrorCode.ReminderServiceBase, + this.logger.Warn(ErrorCode.ReminderServiceBase, $"Intermediate error updating entry {entry.ToString()} to the table {TABLE_NAME_DEFAULT_VALUE}.", exc); throw; } diff --git a/src/AdoNet/Orleans.Clustering.AdoNet/Messaging/LegacySqlMembershipConfigurator.cs b/src/AdoNet/Orleans.Clustering.AdoNet/Messaging/LegacySqlMembershipConfigurator.cs index f65f536a02..05d60b9050 100644 --- a/src/AdoNet/Orleans.Clustering.AdoNet/Messaging/LegacySqlMembershipConfigurator.cs +++ b/src/AdoNet/Orleans.Clustering.AdoNet/Messaging/LegacySqlMembershipConfigurator.cs @@ -1,4 +1,4 @@ -using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection; using Orleans.Runtime.Configuration; using Orleans.Runtime.MembershipService; using Orleans.Hosting; @@ -8,13 +8,14 @@ namespace OrleansSQLUtils /// public class LegacySqlMembershipConfigurator : ILegacyMembershipConfigurator { - public void ConfigureServices(GlobalConfiguration configuration, IServiceCollection services) + public void ConfigureServices(object configuration, IServiceCollection services) { services.UseSqlMembership( options => { - options.AdoInvariant = configuration.AdoInvariant; - options.ConnectionString = configuration.DataConnectionString; + var reader = new GlobalConfigurationReader(configuration); + options.AdoInvariant = reader.GetPropertyValue("AdoInvariant"); + options.ConnectionString = reader.GetPropertyValue("DataConnectionString"); }); } } diff --git a/src/AdoNet/Orleans.Clustering.AdoNet/Orleans.Clustering.AdoNet.csproj b/src/AdoNet/Orleans.Clustering.AdoNet/Orleans.Clustering.AdoNet.csproj index a40659694c..7eebb926ef 100644 --- a/src/AdoNet/Orleans.Clustering.AdoNet/Orleans.Clustering.AdoNet.csproj +++ b/src/AdoNet/Orleans.Clustering.AdoNet/Orleans.Clustering.AdoNet.csproj @@ -34,7 +34,9 @@ + + diff --git a/src/AdoNet/Orleans.Persistence.AdoNet/Orleans.Persistence.AdoNet.csproj b/src/AdoNet/Orleans.Persistence.AdoNet/Orleans.Persistence.AdoNet.csproj index 253a8586a3..b6ea81a803 100644 --- a/src/AdoNet/Orleans.Persistence.AdoNet/Orleans.Persistence.AdoNet.csproj +++ b/src/AdoNet/Orleans.Persistence.AdoNet/Orleans.Persistence.AdoNet.csproj @@ -34,6 +34,7 @@ + diff --git a/src/AdoNet/Orleans.Reminders.AdoNet/Orleans.Reminders.AdoNet.csproj b/src/AdoNet/Orleans.Reminders.AdoNet/Orleans.Reminders.AdoNet.csproj index 3d95dce8b9..773c5d462e 100644 --- a/src/AdoNet/Orleans.Reminders.AdoNet/Orleans.Reminders.AdoNet.csproj +++ b/src/AdoNet/Orleans.Reminders.AdoNet/Orleans.Reminders.AdoNet.csproj @@ -81,6 +81,7 @@ + diff --git a/src/AdoNet/Orleans.Reminders.AdoNet/ReminderService/SqlReminderTable.cs b/src/AdoNet/Orleans.Reminders.AdoNet/ReminderService/SqlReminderTable.cs index 4efa8a5c8a..2625acafdb 100644 --- a/src/AdoNet/Orleans.Reminders.AdoNet/ReminderService/SqlReminderTable.cs +++ b/src/AdoNet/Orleans.Reminders.AdoNet/ReminderService/SqlReminderTable.cs @@ -1,5 +1,6 @@ using System.Threading.Tasks; using Microsoft.Extensions.Options; +using Orleans.Hosting; using Orleans.Reminders.AdoNet.Storage; using Orleans.Runtime.Configuration; @@ -8,48 +9,52 @@ namespace Orleans.Runtime.ReminderService internal class SqlReminderTable : IReminderTable { private readonly IGrainReferenceConverter grainReferenceConverter; + private readonly AdoNetOptions adoNetOptions; + private readonly StorageOptions storageOptions; private string serviceId; private RelationalOrleansQueries orleansQueries; - public SqlReminderTable(IGrainReferenceConverter grainReferenceConverter, IOptions siloOptions) + public SqlReminderTable(IGrainReferenceConverter grainReferenceConverter, IOptions siloOptions, IOptions adoNetOptions, IOptions storageOptions) { this.grainReferenceConverter = grainReferenceConverter; this.serviceId = siloOptions.Value.ServiceId.ToString(); + this.adoNetOptions = adoNetOptions.Value; + this.storageOptions = storageOptions.Value; } - public async Task Init(GlobalConfiguration config) + public async Task Init() { - orleansQueries = await RelationalOrleansQueries.CreateInstance(config.AdoInvariantForReminders, config.DataConnectionStringForReminders, this.grainReferenceConverter); + this.orleansQueries = await RelationalOrleansQueries.CreateInstance(this.adoNetOptions.InvariantForReminders, this.storageOptions.DataConnectionStringForReminders, this.grainReferenceConverter); } public Task ReadRows(GrainReference grainRef) { - return orleansQueries.ReadReminderRowsAsync(serviceId, grainRef); + return this.orleansQueries.ReadReminderRowsAsync(this.serviceId, grainRef); } public Task ReadRows(uint beginHash, uint endHash) { - return orleansQueries.ReadReminderRowsAsync(serviceId, beginHash, endHash); + return this.orleansQueries.ReadReminderRowsAsync(this.serviceId, beginHash, endHash); } public Task ReadRow(GrainReference grainRef, string reminderName) { - return orleansQueries.ReadReminderRowAsync(serviceId, grainRef, reminderName); + return this.orleansQueries.ReadReminderRowAsync(this.serviceId, grainRef, reminderName); } public Task UpsertRow(ReminderEntry entry) { - return orleansQueries.UpsertReminderRowAsync(serviceId, entry.GrainRef, entry.ReminderName, entry.StartAt, entry.Period); + return this.orleansQueries.UpsertReminderRowAsync(this.serviceId, entry.GrainRef, entry.ReminderName, entry.StartAt, entry.Period); } public Task RemoveRow(GrainReference grainRef, string reminderName, string eTag) { - return orleansQueries.DeleteReminderRowAsync(serviceId, grainRef, reminderName, eTag); + return this.orleansQueries.DeleteReminderRowAsync(this.serviceId, grainRef, reminderName, eTag); } public Task TestOnlyClearTable() { - return orleansQueries.DeleteReminderRowsAsync(serviceId); + return this.orleansQueries.DeleteReminderRowsAsync(this.serviceId); } } } diff --git a/src/Azure/Orleans.Clustering.AzureStorage/LegacyAzureMembershipConfigurator.cs b/src/Azure/Orleans.Clustering.AzureStorage/LegacyAzureMembershipConfigurator.cs index 64d263f64c..b41b7d8a5b 100644 --- a/src/Azure/Orleans.Clustering.AzureStorage/LegacyAzureMembershipConfigurator.cs +++ b/src/Azure/Orleans.Clustering.AzureStorage/LegacyAzureMembershipConfigurator.cs @@ -7,13 +7,14 @@ namespace Orleans.Runtime.MembershipService /// public class LegacyAzureTableMembershipConfigurator : ILegacyMembershipConfigurator { - public void ConfigureServices(GlobalConfiguration configuration, IServiceCollection services) + public void ConfigureServices(object configuration, IServiceCollection services) { services.UseAzureTableMembership( options => { - options.MaxStorageBusyRetries = configuration.MaxStorageBusyRetries; - options.ConnectionString = configuration.DataConnectionString; + var reader = new GlobalConfigurationReader(configuration); + options.MaxStorageBusyRetries = reader.GetPropertyValue("MaxStorageBusyRetries"); + options.ConnectionString = reader.GetPropertyValue("DataConnectionString"); }); } } diff --git a/src/Azure/Orleans.Clustering.AzureStorage/Orleans.Clustering.AzureStorage.csproj b/src/Azure/Orleans.Clustering.AzureStorage/Orleans.Clustering.AzureStorage.csproj index fcba2d0930..6e3eff82f2 100644 --- a/src/Azure/Orleans.Clustering.AzureStorage/Orleans.Clustering.AzureStorage.csproj +++ b/src/Azure/Orleans.Clustering.AzureStorage/Orleans.Clustering.AzureStorage.csproj @@ -26,6 +26,7 @@ + diff --git a/src/Azure/Orleans.Hosting.AzureCloudServices/Orleans.Hosting.AzureCloudServices.csproj b/src/Azure/Orleans.Hosting.AzureCloudServices/Orleans.Hosting.AzureCloudServices.csproj index 111bf261db..19eda10ae6 100644 --- a/src/Azure/Orleans.Hosting.AzureCloudServices/Orleans.Hosting.AzureCloudServices.csproj +++ b/src/Azure/Orleans.Hosting.AzureCloudServices/Orleans.Hosting.AzureCloudServices.csproj @@ -22,6 +22,7 @@ + diff --git a/src/Azure/Orleans.Persistence.AzureStorage/Orleans.Persistence.AzureStorage.csproj b/src/Azure/Orleans.Persistence.AzureStorage/Orleans.Persistence.AzureStorage.csproj index c6fc73a1f0..ee6e178240 100644 --- a/src/Azure/Orleans.Persistence.AzureStorage/Orleans.Persistence.AzureStorage.csproj +++ b/src/Azure/Orleans.Persistence.AzureStorage/Orleans.Persistence.AzureStorage.csproj @@ -26,6 +26,7 @@ + diff --git a/src/Azure/Orleans.Reminders.AzureStorage/Orleans.Reminders.AzureStorage.csproj b/src/Azure/Orleans.Reminders.AzureStorage/Orleans.Reminders.AzureStorage.csproj index f1d00784c6..83565c0a10 100644 --- a/src/Azure/Orleans.Reminders.AzureStorage/Orleans.Reminders.AzureStorage.csproj +++ b/src/Azure/Orleans.Reminders.AzureStorage/Orleans.Reminders.AzureStorage.csproj @@ -30,6 +30,7 @@ + diff --git a/src/Azure/Orleans.Reminders.AzureStorage/Storage/AzureBasedReminderTable.cs b/src/Azure/Orleans.Reminders.AzureStorage/Storage/AzureBasedReminderTable.cs index dc873eb25f..e8d1e6f4e9 100644 --- a/src/Azure/Orleans.Reminders.AzureStorage/Storage/AzureBasedReminderTable.cs +++ b/src/Azure/Orleans.Reminders.AzureStorage/Storage/AzureBasedReminderTable.cs @@ -5,6 +5,7 @@ using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using Orleans.AzureUtils.Utilities; +using Orleans.Hosting; namespace Orleans.Runtime.ReminderService { @@ -14,19 +15,21 @@ internal class AzureBasedReminderTable : IReminderTable private readonly ILogger logger; private readonly ILoggerFactory loggerFactory; private readonly SiloOptions siloOptions; + private readonly StorageOptions storageOptions; private RemindersTableManager remTableManager; - public AzureBasedReminderTable(IGrainReferenceConverter grainReferenceConverter, ILoggerFactory loggerFactory, IOptions siloOptions) + public AzureBasedReminderTable(IGrainReferenceConverter grainReferenceConverter, ILoggerFactory loggerFactory, IOptions siloOptions, IOptions storageOptions) { this.grainReferenceConverter = grainReferenceConverter; this.logger = loggerFactory.CreateLogger(); this.loggerFactory = loggerFactory; this.siloOptions = siloOptions.Value; + this.storageOptions = storageOptions.Value; } - public async Task Init(GlobalConfiguration config) + public async Task Init() { - remTableManager = await RemindersTableManager.GetManager(this.siloOptions.ServiceId, this.siloOptions.ClusterId, config.DataConnectionStringForReminders, this.loggerFactory); + this.remTableManager = await RemindersTableManager.GetManager(this.siloOptions.ServiceId, this.siloOptions.ClusterId, this.storageOptions.DataConnectionStringForReminders, this.loggerFactory); } #region Utility methods @@ -66,17 +69,17 @@ private ReminderEntry ConvertFromTableEntry(ReminderTableEntry tableEntry, strin { var error = $"Failed to parse ReminderTableEntry: {tableEntry}. This entry is corrupt, going to ignore it."; - logger.Error((int)AzureReminderErrorCode.AzureTable_49, error, exc); + this.logger.Error((int)AzureReminderErrorCode.AzureTable_49, error, exc); throw; } finally { - string serviceIdStr = ReminderTableEntry.ConstructServiceIdStr(remTableManager.ServiceId); + string serviceIdStr = ReminderTableEntry.ConstructServiceIdStr(this.remTableManager.ServiceId); if (!tableEntry.ServiceId.Equals(serviceIdStr)) { var error = $"Read a reminder entry for wrong Service id. Read {tableEntry}, but my service id is {serviceIdStr}. Going to discard it."; - logger.Warn((int)AzureReminderErrorCode.AzureTable_ReadWrongReminder, error); + this.logger.Warn((int)AzureReminderErrorCode.AzureTable_ReadWrongReminder, error); throw new OrleansException(error); } } @@ -103,7 +106,7 @@ private static ReminderTableEntry ConvertToTableEntry(ReminderEntry remEntry, Gu StartAt = LogFormatter.PrintDate(remEntry.StartAt), Period = remEntry.Period.ToString(), - GrainRefConsistentHash = String.Format("{0:X8}", consistentHash), + GrainRefConsistentHash = string.Format("{0:X8}", consistentHash), ETag = remEntry.ETag, }; } @@ -112,22 +115,22 @@ private static ReminderTableEntry ConvertToTableEntry(ReminderEntry remEntry, Gu public Task TestOnlyClearTable() { - return remTableManager.DeleteTableEntries(); + return this.remTableManager.DeleteTableEntries(); } public async Task ReadRows(GrainReference key) { try { - var entries = await remTableManager.FindReminderEntries(key); + var entries = await this.remTableManager.FindReminderEntries(key); ReminderTableData data = ConvertFromTableEntryList(entries); - if (logger.IsEnabled(LogLevel.Trace)) logger.Trace("Read for grain {0} Table=" + Environment.NewLine + "{1}", key, data.ToString()); + if (this.logger.IsEnabled(LogLevel.Trace)) this.logger.Trace("Read for grain {0} Table=" + Environment.NewLine + "{1}", key, data.ToString()); return data; } catch (Exception exc) { - logger.Warn((int)AzureReminderErrorCode.AzureTable_47, - $"Intermediate error reading reminders for grain {key} in table {remTableManager.TableName}.", exc); + this.logger.Warn((int)AzureReminderErrorCode.AzureTable_47, + $"Intermediate error reading reminders for grain {key} in table {this.remTableManager.TableName}.", exc); throw; } } @@ -136,15 +139,15 @@ public async Task ReadRows(uint begin, uint end) { try { - var entries = await remTableManager.FindReminderEntries(begin, end); + var entries = await this.remTableManager.FindReminderEntries(begin, end); ReminderTableData data = ConvertFromTableEntryList(entries); - if (logger.IsEnabled(LogLevel.Trace)) logger.Trace("Read in {0} Table=" + Environment.NewLine + "{1}", RangeFactory.CreateRange(begin, end), data); + if (this.logger.IsEnabled(LogLevel.Trace)) this.logger.Trace("Read in {0} Table=" + Environment.NewLine + "{1}", RangeFactory.CreateRange(begin, end), data); return data; } catch (Exception exc) { - logger.Warn((int)AzureReminderErrorCode.AzureTable_40, - $"Intermediate error reading reminders in range {RangeFactory.CreateRange(begin, end)} for table {remTableManager.TableName}.", exc); + this.logger.Warn((int)AzureReminderErrorCode.AzureTable_40, + $"Intermediate error reading reminders in range {RangeFactory.CreateRange(begin, end)} for table {this.remTableManager.TableName}.", exc); throw; } } @@ -153,14 +156,14 @@ public async Task ReadRow(GrainReference grainRef, string reminde { try { - if (logger.IsEnabled(LogLevel.Debug)) logger.Debug("ReadRow grainRef = {0} reminderName = {1}", grainRef, reminderName); - var result = await remTableManager.FindReminderEntry(grainRef, reminderName); + if (this.logger.IsEnabled(LogLevel.Debug)) this.logger.Debug("ReadRow grainRef = {0} reminderName = {1}", grainRef, reminderName); + var result = await this.remTableManager.FindReminderEntry(grainRef, reminderName); return result == null ? null : ConvertFromTableEntry(result.Item1, result.Item2); } catch (Exception exc) { - logger.Warn((int)AzureReminderErrorCode.AzureTable_46, - $"Intermediate error reading row with grainId = {grainRef} reminderName = {reminderName} from table {remTableManager.TableName}.", exc); + this.logger.Warn((int)AzureReminderErrorCode.AzureTable_46, + $"Intermediate error reading row with grainId = {grainRef} reminderName = {reminderName} from table {this.remTableManager.TableName}.", exc); throw; } } @@ -169,21 +172,21 @@ public async Task UpsertRow(ReminderEntry entry) { try { - if (logger.IsEnabled(LogLevel.Debug)) logger.Debug("UpsertRow entry = {0}", entry.ToString()); - ReminderTableEntry remTableEntry = ConvertToTableEntry(entry, remTableManager.ServiceId, remTableManager.DeploymentId); + if (this.logger.IsEnabled(LogLevel.Debug)) this.logger.Debug("UpsertRow entry = {0}", entry.ToString()); + ReminderTableEntry remTableEntry = ConvertToTableEntry(entry, this.remTableManager.ServiceId, this.remTableManager.DeploymentId); - string result = await remTableManager.UpsertRow(remTableEntry); + string result = await this.remTableManager.UpsertRow(remTableEntry); if (result == null) { - logger.Warn((int)AzureReminderErrorCode.AzureTable_45, + this.logger.Warn((int)AzureReminderErrorCode.AzureTable_45, $"Upsert failed on the reminder table. Will retry. Entry = {entry.ToString()}"); } return result; } catch (Exception exc) { - logger.Warn((int)AzureReminderErrorCode.AzureTable_42, - $"Intermediate error upserting reminder entry {entry.ToString()} to the table {remTableManager.TableName}.", exc); + this.logger.Warn((int)AzureReminderErrorCode.AzureTable_42, + $"Intermediate error upserting reminder entry {entry.ToString()} to the table {this.remTableManager.TableName}.", exc); throw; } } @@ -192,26 +195,26 @@ public async Task RemoveRow(GrainReference grainRef, string reminderName, { var entry = new ReminderTableEntry { - PartitionKey = ReminderTableEntry.ConstructPartitionKey(remTableManager.ServiceId, grainRef), + PartitionKey = ReminderTableEntry.ConstructPartitionKey(this.remTableManager.ServiceId, grainRef), RowKey = ReminderTableEntry.ConstructRowKey(grainRef, reminderName), ETag = eTag, }; try { - if (logger.IsEnabled(LogLevel.Trace)) logger.Trace("RemoveRow entry = {0}", entry.ToString()); + if (this.logger.IsEnabled(LogLevel.Trace)) this.logger.Trace("RemoveRow entry = {0}", entry.ToString()); - bool result = await remTableManager.DeleteReminderEntryConditionally(entry, eTag); + bool result = await this.remTableManager.DeleteReminderEntryConditionally(entry, eTag); if (result == false) { - logger.Warn((int)AzureReminderErrorCode.AzureTable_43, + this.logger.Warn((int)AzureReminderErrorCode.AzureTable_43, $"Delete failed on the reminder table. Will retry. Entry = {entry}"); } return result; } catch (Exception exc) { - logger.Warn((int)AzureReminderErrorCode.AzureTable_44, - $"Intermediate error when deleting reminder entry {entry} to the table {remTableManager.TableName}.", exc); + this.logger.Warn((int)AzureReminderErrorCode.AzureTable_44, + $"Intermediate error when deleting reminder entry {entry} to the table {this.remTableManager.TableName}.", exc); throw; } } diff --git a/src/Azure/Orleans.Streaming.AzureStorage/Orleans.Streaming.AzureStorage.csproj b/src/Azure/Orleans.Streaming.AzureStorage/Orleans.Streaming.AzureStorage.csproj index d2e5982cc9..f2d57ea24c 100644 --- a/src/Azure/Orleans.Streaming.AzureStorage/Orleans.Streaming.AzureStorage.csproj +++ b/src/Azure/Orleans.Streaming.AzureStorage/Orleans.Streaming.AzureStorage.csproj @@ -26,6 +26,7 @@ + diff --git a/src/Azure/Orleans.Streaming.EventHubs/Orleans.Streaming.EventHubs.csproj b/src/Azure/Orleans.Streaming.EventHubs/Orleans.Streaming.EventHubs.csproj index 2f276fa647..6f12755909 100644 --- a/src/Azure/Orleans.Streaming.EventHubs/Orleans.Streaming.EventHubs.csproj +++ b/src/Azure/Orleans.Streaming.EventHubs/Orleans.Streaming.EventHubs.csproj @@ -1,4 +1,4 @@ - + Microsoft.Orleans.OrleansServiceBus Microsoft Orleans EventHubs Provider @@ -27,6 +27,7 @@ + diff --git a/src/Azure/Orleans.Streaming.EventHubs/Providers/Streams/EventHub/EventHubAdapterFactory.cs b/src/Azure/Orleans.Streaming.EventHubs/Providers/Streams/EventHub/EventHubAdapterFactory.cs index b475f1b768..4e2f9ad7e8 100644 --- a/src/Azure/Orleans.Streaming.EventHubs/Providers/Streams/EventHub/EventHubAdapterFactory.cs +++ b/src/Azure/Orleans.Streaming.EventHubs/Providers/Streams/EventHub/EventHubAdapterFactory.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Threading.Tasks; @@ -11,6 +11,8 @@ using Orleans.Serialization; using Orleans.Streams; using Orleans.Runtime.Configuration; +using Microsoft.Extensions.Options; +using Orleans.Hosting; namespace Orleans.ServiceBus.Providers { @@ -63,7 +65,7 @@ public class EventHubAdapterFactory : IQueueAdapterFactory, IQueueAdapter, IQueu /// /// Name of the adapter. Primarily for logging purposes /// - public string Name => adapterSettings.StreamProviderName; + public string Name => this.adapterSettings.StreamProviderName; /// /// Determines whether this is a rewindable stream adapter - supports subscribing from previous point in time. @@ -124,45 +126,45 @@ public virtual void Init(IProviderConfiguration providerCfg, string providerName if (providerCfg == null) throw new ArgumentNullException(nameof(providerCfg)); if (string.IsNullOrWhiteSpace(providerName)) throw new ArgumentNullException(nameof(providerName)); - providerConfig = providerCfg; - serviceProvider = svcProvider; - this.loggerFactory = serviceProvider.GetRequiredService(); - receivers = new ConcurrentDictionary(); + this.providerConfig = providerCfg; + this.serviceProvider = svcProvider; + this.loggerFactory = this.serviceProvider.GetRequiredService(); + this.receivers = new ConcurrentDictionary(); this.SerializationManager = this.serviceProvider.GetRequiredService(); - adapterSettings = new EventHubStreamProviderSettings(providerName); - adapterSettings.PopulateFromProviderConfig(providerConfig); - hubSettings = adapterSettings.GetEventHubSettings(providerConfig, serviceProvider); - this.telemetryProducer = serviceProvider.GetService(); + this.adapterSettings = new EventHubStreamProviderSettings(providerName); + this.adapterSettings.PopulateFromProviderConfig(this.providerConfig); + this.hubSettings = this.adapterSettings.GetEventHubSettings(this.providerConfig, this.serviceProvider); + this.telemetryProducer = this.serviceProvider.GetService(); InitEventHubClient(); - if (CheckpointerFactory == null) + if (this.CheckpointerFactory == null) { - checkpointerSettings = adapterSettings.GetCheckpointerSettings(providerConfig, serviceProvider); - CheckpointerFactory = partition => EventHubCheckpointer.Create(checkpointerSettings, adapterSettings.StreamProviderName, partition, this.loggerFactory); + this.checkpointerSettings = this.adapterSettings.GetCheckpointerSettings(this.providerConfig, this.serviceProvider); + this.CheckpointerFactory = partition => EventHubCheckpointer.Create(this.checkpointerSettings, this.adapterSettings.StreamProviderName, partition, this.loggerFactory); } - if (CacheFactory == null) + if (this.CacheFactory == null) { - CacheFactory = CreateCacheFactory(adapterSettings).CreateCache; + this.CacheFactory = CreateCacheFactory(this.adapterSettings).CreateCache; } - if (StreamFailureHandlerFactory == null) + if (this.StreamFailureHandlerFactory == null) { //TODO: Add a queue specific default failure handler with reasonable error reporting. - StreamFailureHandlerFactory = partition => Task.FromResult(new NoOpStreamDeliveryFailureHandler()); + this.StreamFailureHandlerFactory = partition => Task.FromResult(new NoOpStreamDeliveryFailureHandler()); } - if (QueueMapperFactory == null) + if (this.QueueMapperFactory == null) { - QueueMapperFactory = partitions => new EventHubQueueMapper(partitions, adapterSettings.StreamProviderName); + this.QueueMapperFactory = partitions => new EventHubQueueMapper(partitions, this.adapterSettings.StreamProviderName); } - if (ReceiverMonitorFactory == null) + if (this.ReceiverMonitorFactory == null) { - ReceiverMonitorFactory = (dimensions, logger, telemetryProducer) => new DefaultEventHubReceiverMonitor(dimensions, telemetryProducer); + this.ReceiverMonitorFactory = (dimensions, logger, telemetryProducer) => new DefaultEventHubReceiverMonitor(dimensions, telemetryProducer); } - logger = this.loggerFactory.CreateLogger($"{this.GetType().FullName}.{hubSettings.Path}"); + this.logger = this.loggerFactory.CreateLogger($"{this.GetType().FullName}.{this.hubSettings.Path}"); } /// @@ -171,10 +173,10 @@ public virtual void Init(IProviderConfiguration providerCfg, string providerName /// public async Task CreateAdapter() { - if (streamQueueMapper == null) + if (this.streamQueueMapper == null) { - partitionIds = await GetPartitionIdsAsync(); - streamQueueMapper = QueueMapperFactory(partitionIds); + this.partitionIds = await GetPartitionIdsAsync(); + this.streamQueueMapper = this.QueueMapperFactory(this.partitionIds); } return this; } @@ -195,7 +197,7 @@ public IQueueAdapterCache GetQueueAdapterCache() public IStreamQueueMapper GetStreamQueueMapper() { //TODO: CreateAdapter must be called first. Figure out how to safely enforce this - return streamQueueMapper; + return this.streamQueueMapper; } /// @@ -205,7 +207,7 @@ public IStreamQueueMapper GetStreamQueueMapper() /// public Task GetDeliveryFailureHandler(QueueId queueId) { - return StreamFailureHandlerFactory(streamQueueMapper.QueueToPartition(queueId)); + return this.StreamFailureHandlerFactory(this.streamQueueMapper.QueueToPartition(queueId)); } /// @@ -227,7 +229,7 @@ public Task GetDeliveryFailureHandler(QueueId queueId) } EventData eventData = EventHubBatchContainer.ToEventData(this.SerializationManager, streamGuid, streamNamespace, events, requestContext); - return client.SendAsync(eventData, streamGuid.ToString()); + return this.client.SendAsync(eventData, streamGuid.ToString()); } /// @@ -251,16 +253,16 @@ public IQueueCache CreateQueueCache(QueueId queueId) private EventHubAdapterReceiver GetOrCreateReceiver(QueueId queueId) { - return receivers.GetOrAdd(queueId, q => MakeReceiver(queueId)); + return this.receivers.GetOrAdd(queueId, q => MakeReceiver(queueId)); } protected virtual void InitEventHubClient() { - var connectionStringBuilder = new EventHubsConnectionStringBuilder(hubSettings.ConnectionString) + var connectionStringBuilder = new EventHubsConnectionStringBuilder(this.hubSettings.ConnectionString) { - EntityPath = hubSettings.Path + EntityPath = this.hubSettings.Path }; - client = EventHubClient.CreateFromConnectionString(connectionStringBuilder.ToString()); + this.client = EventHubClient.CreateFromConnectionString(connectionStringBuilder.ToString()); } /// @@ -272,11 +274,9 @@ protected virtual void InitEventHubClient() /// protected virtual IEventHubQueueCacheFactory CreateCacheFactory(EventHubStreamProviderSettings providerSettings) { - var globalConfig = this.serviceProvider.GetService(); - var nodeConfig = this.serviceProvider.GetService(); - var eventHubPath = hubSettings.Path; - var sharedDimensions = new EventHubMonitorAggregationDimensions(globalConfig, nodeConfig, eventHubPath); - return new EventHubQueueCacheFactory(providerSettings, SerializationManager, sharedDimensions, this.loggerFactory); + var eventHubPath = this.hubSettings.Path; + var sharedDimensions = new EventHubMonitorAggregationDimensions(eventHubPath); + return new EventHubQueueCacheFactory(providerSettings, this.SerializationManager, sharedDimensions, this.loggerFactory); } private EventHubAdapterReceiver MakeReceiver(QueueId queueId) @@ -284,17 +284,17 @@ private EventHubAdapterReceiver MakeReceiver(QueueId queueId) var config = new EventHubPartitionSettings { Hub = hubSettings, - Partition = streamQueueMapper.QueueToPartition(queueId), + Partition = this.streamQueueMapper.QueueToPartition(queueId), }; - var receiverMonitorDimensions = new EventHubReceiverMonitorDimensions(); - receiverMonitorDimensions.EventHubPartition = config.Partition; - receiverMonitorDimensions.EventHubPath = config.Hub.Path; - receiverMonitorDimensions.NodeConfig = this.serviceProvider.GetRequiredService(); - receiverMonitorDimensions.GlobalConfig = this.serviceProvider.GetRequiredService(); + var receiverMonitorDimensions = new EventHubReceiverMonitorDimensions + { + EventHubPartition = config.Partition, + EventHubPath = config.Hub.Path, + }; - return new EventHubAdapterReceiver(config, CacheFactory, CheckpointerFactory, loggerFactory, ReceiverMonitorFactory(receiverMonitorDimensions, loggerFactory, this.telemetryProducer), - this.serviceProvider.GetRequiredService>(), + return new EventHubAdapterReceiver(config, this.CacheFactory, this.CheckpointerFactory, this.loggerFactory, this.ReceiverMonitorFactory(receiverMonitorDimensions, this.loggerFactory, this.telemetryProducer), + this.serviceProvider.GetRequiredService>().Value, this.telemetryProducer, this.EventHubReceiverFactory); } diff --git a/src/Azure/Orleans.Streaming.EventHubs/Providers/Streams/EventHub/EventHubAdapterReceiver.cs b/src/Azure/Orleans.Streaming.EventHubs/Providers/Streams/EventHub/EventHubAdapterReceiver.cs index ac20e344b3..f73cfd4b74 100644 --- a/src/Azure/Orleans.Streaming.EventHubs/Providers/Streams/EventHub/EventHubAdapterReceiver.cs +++ b/src/Azure/Orleans.Streaming.EventHubs/Providers/Streams/EventHub/EventHubAdapterReceiver.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; @@ -9,8 +9,8 @@ using Orleans.Providers.Streams.Common; using Orleans.Runtime; using Orleans.Streams; -using Orleans.Runtime.Configuration; using Orleans.ServiceBus.Providers.Testing; +using Orleans.Hosting; namespace Orleans.ServiceBus.Providers { @@ -41,6 +41,7 @@ internal class EventHubAdapterReceiver : IQueueAdapterReceiver, IQueueCache private readonly ILogger logger; private readonly IQueueAdapterReceiverMonitor monitor; private readonly ITelemetryProducer telemetryProducer; + private readonly SiloStatisticsOptions statisticsOptions; private IEventHubQueueCache cache; @@ -56,11 +57,10 @@ internal class EventHubAdapterReceiver : IQueueAdapterReceiver, IQueueCache private const int ReceiverShutdown = 0; private const int ReceiverRunning = 1; - private readonly Factory getNodeConfig; public int GetMaxAddCount() { - return flowController.GetMaxAddCount(); + return this.flowController.GetMaxAddCount(); } public EventHubAdapterReceiver(EventHubPartitionSettings settings, @@ -68,7 +68,7 @@ public int GetMaxAddCount() Func>> checkpointerFactory, ILoggerFactory loggerFactory, IQueueAdapterReceiverMonitor monitor, - Factory getNodeConfig, + SiloStatisticsOptions statisticsOptions, ITelemetryProducer telemetryProducer, Func> eventHubReceiverFactory = null) { @@ -77,6 +77,7 @@ public int GetMaxAddCount() if (checkpointerFactory == null) throw new ArgumentNullException(nameof(checkpointerFactory)); if (loggerFactory == null) throw new ArgumentNullException(nameof(loggerFactory)); if (monitor == null) throw new ArgumentNullException(nameof(monitor)); + if (statisticsOptions == null) throw new ArgumentNullException(nameof(statisticsOptions)); if (telemetryProducer == null) throw new ArgumentNullException(nameof(telemetryProducer)); this.settings = settings; this.cacheFactory = cacheFactory; @@ -84,17 +85,17 @@ public int GetMaxAddCount() this.loggerFactory = loggerFactory; this.logger = this.loggerFactory.CreateLogger($"{this.GetType().FullName}.{settings.Hub.Path}.{settings.Partition}"); this.monitor = monitor; - this.getNodeConfig = getNodeConfig; this.telemetryProducer = telemetryProducer; + this.statisticsOptions = statisticsOptions; this.eventHubReceiverFactory = eventHubReceiverFactory == null ? EventHubAdapterReceiver.CreateReceiver : eventHubReceiverFactory; } public Task Initialize(TimeSpan timeout) { - logger.Info("Initializing EventHub partition {0}-{1}.", settings.Hub.Path, settings.Partition); + this.logger.Info("Initializing EventHub partition {0}-{1}.", this.settings.Hub.Path, this.settings.Partition); // if receiver was already running, do nothing - return ReceiverRunning == Interlocked.Exchange(ref recieverState, ReceiverRunning) + return ReceiverRunning == Interlocked.Exchange(ref this.recieverState, ReceiverRunning) ? Task.CompletedTask : Initialize(); } @@ -108,41 +109,41 @@ private async Task Initialize() var watch = Stopwatch.StartNew(); try { - this.checkpointer = await checkpointerFactory(settings.Partition); + this.checkpointer = await this.checkpointerFactory(this.settings.Partition); if(this.cache != null) { this.cache.Dispose(); this.cache = null; } - this.cache = cacheFactory(settings.Partition, checkpointer, this.loggerFactory, this.telemetryProducer); - this.flowController = new AggregatedQueueFlowController(MaxMessagesPerRead) { cache, LoadShedQueueFlowController.CreateAsPercentOfLoadSheddingLimit(getNodeConfig) }; - string offset = await checkpointer.Load(); - this.receiver = await this.eventHubReceiverFactory(settings, offset, this.logger, this.telemetryProducer); + this.cache = this.cacheFactory(this.settings.Partition, this.checkpointer, this.loggerFactory, this.telemetryProducer); + this.flowController = new AggregatedQueueFlowController(MaxMessagesPerRead) { this.cache, LoadShedQueueFlowController.CreateAsPercentOfLoadSheddingLimit(this.statisticsOptions) }; + string offset = await this.checkpointer.Load(); + this.receiver = await this.eventHubReceiverFactory(this.settings, offset, this.logger, this.telemetryProducer); watch.Stop(); this.monitor?.TrackInitialization(true, watch.Elapsed, null); } catch (Exception ex) { watch.Stop(); - monitor?.TrackInitialization(false, watch.Elapsed, ex); + this.monitor?.TrackInitialization(false, watch.Elapsed, ex); throw; } } public async Task> GetQueueMessagesAsync(int maxCount) { - if (recieverState == ReceiverShutdown || maxCount <= 0) + if (this.recieverState == ReceiverShutdown || maxCount <= 0) { return new List(); } // if receiver initialization failed, retry - if (receiver == null) + if (this.receiver == null) { - logger.Warn(OrleansServiceBusErrorCode.FailedPartitionRead, - "Retrying initialization of EventHub partition {0}-{1}.", settings.Hub.Path, settings.Partition); + this.logger.Warn(OrleansServiceBusErrorCode.FailedPartitionRead, + "Retrying initialization of EventHub partition {0}-{1}.", this.settings.Hub.Path, this.settings.Partition); await Initialize(); - if (receiver == null) + if (this.receiver == null) { // should not get here, should throw instead, but just incase. return new List(); @@ -153,25 +154,25 @@ public async Task> GetQueueMessagesAsync(int maxCount) try { - messages = (await receiver.ReceiveAsync(maxCount, ReceiveTimeout))?.ToList(); + messages = (await this.receiver.ReceiveAsync(maxCount, ReceiveTimeout))?.ToList(); watch.Stop(); - monitor?.TrackRead(true, watch.Elapsed, null); + this.monitor?.TrackRead(true, watch.Elapsed, null); } catch (Exception ex) { watch.Stop(); - monitor?.TrackRead(false, watch.Elapsed, ex); - logger.Warn(OrleansServiceBusErrorCode.FailedPartitionRead, - "Failed to read from EventHub partition {0}-{1}. : Exception: {2}.", settings.Hub.Path, - settings.Partition, ex); + this.monitor?.TrackRead(false, watch.Elapsed, ex); + this.logger.Warn(OrleansServiceBusErrorCode.FailedPartitionRead, + "Failed to read from EventHub partition {0}-{1}. : Exception: {2}.", this.settings.Hub.Path, + this.settings.Partition, ex); throw; } var batches = new List(); if (messages == null || messages.Count == 0) { - monitor?.TrackMessagesReceived(0, null, null); + this.monitor?.TrackMessagesReceived(0, null, null); return batches; } @@ -181,17 +182,17 @@ public async Task> GetQueueMessagesAsync(int maxCount) DateTime oldestMessageEnqueueTime = messages[0].SystemProperties.EnqueuedTimeUtc; DateTime newestMessageEnqueueTime = messages[messages.Count - 1].SystemProperties.EnqueuedTimeUtc; - monitor?.TrackMessagesReceived(messages.Count, oldestMessageEnqueueTime, newestMessageEnqueueTime); + this.monitor?.TrackMessagesReceived(messages.Count, oldestMessageEnqueueTime, newestMessageEnqueueTime); - List messageStreamPositions = cache.Add(messages, dequeueTimeUtc); + List messageStreamPositions = this.cache.Add(messages, dequeueTimeUtc); foreach (var streamPosition in messageStreamPositions) { batches.Add(new StreamActivityNotificationBatch(streamPosition.StreamIdentity.Guid, streamPosition.StreamIdentity.Namespace, streamPosition.SequenceToken)); } - if (!checkpointer.CheckpointExists) + if (!this.checkpointer.CheckpointExists) { - checkpointer.Update( + this.checkpointer.Update( messages[0].SystemProperties.Offset, DateTime.UtcNow); } @@ -216,7 +217,7 @@ public bool TryPurgeFromCache(out IList purgedItems) public IQueueCacheCursor GetCacheCursor(IStreamIdentity streamIdentity, StreamSequenceToken token) { - return new Cursor(cache, streamIdentity, token); + return new Cursor(this.cache, streamIdentity, token); } public bool IsUnderPressure() @@ -235,17 +236,17 @@ public async Task Shutdown(TimeSpan timeout) try { // if receiver was already shutdown, do nothing - if (ReceiverShutdown == Interlocked.Exchange(ref recieverState, ReceiverShutdown)) + if (ReceiverShutdown == Interlocked.Exchange(ref this.recieverState, ReceiverShutdown)) { return; } - logger.Info("Stopping reading from EventHub partition {0}-{1}", settings.Hub.Path, settings.Partition); + this.logger.Info("Stopping reading from EventHub partition {0}-{1}", this.settings.Hub.Path, this.settings.Partition); // clear cache and receiver - IEventHubQueueCache localCache = Interlocked.Exchange(ref cache, null); + IEventHubQueueCache localCache = Interlocked.Exchange(ref this.cache, null); - var localReceiver = Interlocked.Exchange(ref receiver, null); + var localReceiver = Interlocked.Exchange(ref this.receiver, null); // start closing receiver Task closeTask = Task.CompletedTask; @@ -259,12 +260,12 @@ public async Task Shutdown(TimeSpan timeout) // finish return receiver closing task await closeTask; watch.Stop(); - monitor?.TrackShutdown(true, watch.Elapsed, null); + this.monitor?.TrackShutdown(true, watch.Elapsed, null); } catch (Exception ex) { watch.Stop(); - monitor?.TrackShutdown(false, watch.Elapsed, ex); + this.monitor?.TrackShutdown(false, watch.Elapsed, ex); throw; } } @@ -327,9 +328,9 @@ private class StreamActivityNotificationBatch : IBatchContainer public StreamActivityNotificationBatch(Guid streamGuid, string streamNamespace, StreamSequenceToken sequenceToken) { - StreamGuid = streamGuid; - StreamNamespace = streamNamespace; - SequenceToken = sequenceToken; + this.StreamGuid = streamGuid; + this.StreamNamespace = streamNamespace; + this.SequenceToken = sequenceToken; } public IEnumerable> GetEvents() { throw new NotSupportedException(); } @@ -346,7 +347,7 @@ private class Cursor : IQueueCacheCursor public Cursor(IEventHubQueueCache cache, IStreamIdentity streamIdentity, StreamSequenceToken token) { this.cache = cache; - cursor = cache.GetCursor(streamIdentity, token); + this.cursor = cache.GetCursor(streamIdentity, token); } public void Dispose() @@ -356,18 +357,18 @@ public void Dispose() public IBatchContainer GetCurrent(out Exception exception) { exception = null; - return current; + return this.current; } public bool MoveNext() { IBatchContainer next; - if (!cache.TryGetNextMessage(cursor, out next)) + if (!this.cache.TryGetNextMessage(this.cursor, out next)) { return false; } - current = next; + this.current = next; return true; } diff --git a/src/Azure/Orleans.Streaming.EventHubs/Providers/Streams/EventHub/StatisticMonitors/MonitorAggregationDimentions.cs b/src/Azure/Orleans.Streaming.EventHubs/Providers/Streams/EventHub/StatisticMonitors/MonitorAggregationDimentions.cs index ddd65a6823..7b4f518919 100644 --- a/src/Azure/Orleans.Streaming.EventHubs/Providers/Streams/EventHub/StatisticMonitors/MonitorAggregationDimentions.cs +++ b/src/Azure/Orleans.Streaming.EventHubs/Providers/Streams/EventHub/StatisticMonitors/MonitorAggregationDimentions.cs @@ -1,10 +1,3 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Orleans.Runtime.Configuration; -using Orleans.Providers.Streams.Common; namespace Orleans.ServiceBus.Providers { @@ -12,7 +5,7 @@ namespace Orleans.ServiceBus.Providers /// Base class for monitor aggregation dimensions, whcih is a information bag for the monitoring target. /// Monitors can use this information bag to build its aggregation dimensions. /// - public class EventHubMonitorAggregationDimensions : MonitorAggregationDimensions + public class EventHubMonitorAggregationDimensions { /// /// Eventhub path @@ -22,11 +15,8 @@ public class EventHubMonitorAggregationDimensions : MonitorAggregationDimensions /// /// Constructor /// - /// - /// /// - public EventHubMonitorAggregationDimensions(GlobalConfiguration globalConfig, NodeConfiguration nodeConfig, string ehHubPath) - :base(globalConfig, nodeConfig) + public EventHubMonitorAggregationDimensions(string ehHubPath) { this.EventHubPath = ehHubPath; } @@ -36,7 +26,6 @@ public EventHubMonitorAggregationDimensions(GlobalConfiguration globalConfig, No /// /// public EventHubMonitorAggregationDimensions(EventHubMonitorAggregationDimensions dimensions) - :base(dimensions.GlobalConfig, dimensions.NodeConfig) { this.EventHubPath = dimensions.EventHubPath; } diff --git a/src/Orleans.Clustering.Consul/LegacyConsulMembershipConfigurator.cs b/src/Orleans.Clustering.Consul/LegacyConsulMembershipConfigurator.cs index 885aa49c5e..48bb096707 100644 --- a/src/Orleans.Clustering.Consul/LegacyConsulMembershipConfigurator.cs +++ b/src/Orleans.Clustering.Consul/LegacyConsulMembershipConfigurator.cs @@ -1,16 +1,16 @@ -using System; +using System; using Microsoft.Extensions.DependencyInjection; using Orleans.Hosting; -using Orleans.Runtime.Configuration; namespace Orleans.Runtime.MembershipService { /// public class LegacyConsulMembershipConfigurator : ILegacyMembershipConfigurator { - public void ConfigureServices(GlobalConfiguration configuration, IServiceCollection services) + public void ConfigureServices(object configuration, IServiceCollection services) { - services.UseConsulMembership(options => options.Address = new Uri(configuration.DataConnectionString)); + var reader = new GlobalConfigurationReader(configuration); + services.UseConsulMembership(options => options.Address = new Uri(reader.GetPropertyValue("DataConnectionString"))); } } } diff --git a/src/Orleans.Clustering.Consul/Orleans.Clustering.Consul.csproj b/src/Orleans.Clustering.Consul/Orleans.Clustering.Consul.csproj index ffb6c83060..7b685f2b83 100644 --- a/src/Orleans.Clustering.Consul/Orleans.Clustering.Consul.csproj +++ b/src/Orleans.Clustering.Consul/Orleans.Clustering.Consul.csproj @@ -1,4 +1,4 @@ - + Microsoft.Orleans.OrleansConsulUtils Microsoft Orleans Membership Consul @@ -17,6 +17,7 @@ + diff --git a/src/Orleans.Clustering.ZooKeeper/LegacyZooKeeperMembershipConfigurator.cs b/src/Orleans.Clustering.ZooKeeper/LegacyZooKeeperMembershipConfigurator.cs index d862c018a7..6d4850c8de 100644 --- a/src/Orleans.Clustering.ZooKeeper/LegacyZooKeeperMembershipConfigurator.cs +++ b/src/Orleans.Clustering.ZooKeeper/LegacyZooKeeperMembershipConfigurator.cs @@ -1,4 +1,4 @@ -using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection; using Orleans.Runtime.Configuration; using Orleans.Runtime.MembershipService; using Orleans.Hosting; @@ -8,9 +8,10 @@ namespace OrleansZooKeeperUtils /// public class LegacyZooKeeperMembershipConfigurator : ILegacyMembershipConfigurator { - public void ConfigureServices(GlobalConfiguration configuration, IServiceCollection services) + public void ConfigureServices(object configuration, IServiceCollection services) { - services.UseZooKeeperMembership(options => options.ConnectionString = configuration.DataConnectionString); + var reader = new GlobalConfigurationReader(configuration); + services.UseZooKeeperMembership(options => options.ConnectionString = reader.GetPropertyValue("DataConnectionString")); } } } diff --git a/src/Orleans.Clustering.ZooKeeper/Orleans.Clustering.ZooKeeper.csproj b/src/Orleans.Clustering.ZooKeeper/Orleans.Clustering.ZooKeeper.csproj index 88cbfe2527..c0585bf5c5 100644 --- a/src/Orleans.Clustering.ZooKeeper/Orleans.Clustering.ZooKeeper.csproj +++ b/src/Orleans.Clustering.ZooKeeper/Orleans.Clustering.ZooKeeper.csproj @@ -1,4 +1,4 @@ - + Microsoft.Orleans.OrleansZooKeeperUtils Microsoft Orleans ZooKeeper Utilities @@ -17,6 +17,7 @@ + diff --git a/src/Orleans.Core.Abstractions/Concurrency/GrainAttributeConcurrency.cs b/src/Orleans.Core.Abstractions/Concurrency/GrainAttributeConcurrency.cs index 44a55869b1..2b35a1ef7b 100644 --- a/src/Orleans.Core.Abstractions/Concurrency/GrainAttributeConcurrency.cs +++ b/src/Orleans.Core.Abstractions/Concurrency/GrainAttributeConcurrency.cs @@ -1,4 +1,6 @@ -using System; +using Orleans.Placement; +using Orleans.Runtime; +using System; using System.Collections.Generic; using System.Text; @@ -43,21 +45,16 @@ public sealed class UnorderedAttribute : Attribute /// of preservation of grain state between requests and where multiple activations of the same grain are allowed to be created by the runtime. /// [AttributeUsage(AttributeTargets.Class)] - public sealed class StatelessWorkerAttribute : Attribute + public sealed class StatelessWorkerAttribute : PlacementAttribute { - /// - /// Maximal number of local StatelessWorkers in a single silo. - /// - public int MaxLocalWorkers { get; private set; } - public StatelessWorkerAttribute(int maxLocalWorkers) + : base(new StatelessWorkerPlacement(maxLocalWorkers)) { - MaxLocalWorkers = maxLocalWorkers; } public StatelessWorkerAttribute() + : base(new StatelessWorkerPlacement()) { - MaxLocalWorkers = -1; } } @@ -91,7 +88,7 @@ public sealed class MayInterleaveAttribute : Attribute public MayInterleaveAttribute(string callbackMethodName) { - CallbackMethodName = callbackMethodName; + this.CallbackMethodName = callbackMethodName; } } diff --git a/src/Orleans.Core.Abstractions/Placement/ActivationCountBasedPlacement.cs b/src/Orleans.Core.Abstractions/Placement/ActivationCountBasedPlacement.cs index c8f518e6d0..6a9a1ccacf 100644 --- a/src/Orleans.Core.Abstractions/Placement/ActivationCountBasedPlacement.cs +++ b/src/Orleans.Core.Abstractions/Placement/ActivationCountBasedPlacement.cs @@ -6,18 +6,5 @@ namespace Orleans.Runtime internal class ActivationCountBasedPlacement : PlacementStrategy { internal static ActivationCountBasedPlacement Singleton { get; } = new ActivationCountBasedPlacement(); - - private ActivationCountBasedPlacement() - {} - - public override bool Equals(object obj) - { - return obj is ActivationCountBasedPlacement; - } - - public override int GetHashCode() - { - return GetType().GetHashCode(); - } } } diff --git a/src/Orleans.Core.Abstractions/Placement/HashBasedPlacement.cs b/src/Orleans.Core.Abstractions/Placement/HashBasedPlacement.cs index 585b1fd193..fc234995cd 100644 --- a/src/Orleans.Core.Abstractions/Placement/HashBasedPlacement.cs +++ b/src/Orleans.Core.Abstractions/Placement/HashBasedPlacement.cs @@ -1,26 +1,10 @@ -using System; +using System; namespace Orleans.Runtime { [Serializable] internal class HashBasedPlacement : PlacementStrategy { - internal static HashBasedPlacement Singleton { get; } = new HashBasedPlacement(); - - - public HashBasedPlacement() - { - } - - public override bool Equals(object obj) - { - return obj is HashBasedPlacement; - } - - public override int GetHashCode() - { - return GetType().GetHashCode(); - } } } diff --git a/src/Orleans.Core.Abstractions/Placement/PlacementAttribute.cs b/src/Orleans.Core.Abstractions/Placement/PlacementAttribute.cs index 56b1b288e0..9fd19a5818 100644 --- a/src/Orleans.Core.Abstractions/Placement/PlacementAttribute.cs +++ b/src/Orleans.Core.Abstractions/Placement/PlacementAttribute.cs @@ -16,7 +16,7 @@ protected PlacementAttribute(PlacementStrategy placement) { if (placement == null) throw new ArgumentNullException(nameof(placement)); - PlacementStrategy = placement; + this.PlacementStrategy = placement; } } diff --git a/src/Orleans.Core.Abstractions/Placement/PreferLocalPlacement.cs b/src/Orleans.Core.Abstractions/Placement/PreferLocalPlacement.cs index 49d10edaaf..40d6276446 100644 --- a/src/Orleans.Core.Abstractions/Placement/PreferLocalPlacement.cs +++ b/src/Orleans.Core.Abstractions/Placement/PreferLocalPlacement.cs @@ -6,18 +6,5 @@ namespace Orleans.Runtime internal class PreferLocalPlacement : PlacementStrategy { internal static PreferLocalPlacement Singleton { get; } = new PreferLocalPlacement(); - - private PreferLocalPlacement() - { } - - public override bool Equals(object obj) - { - return obj is PreferLocalPlacement; - } - - public override int GetHashCode() - { - return GetType().GetHashCode(); - } } } diff --git a/src/Orleans.Core.Abstractions/Placement/RandomPlacement.cs b/src/Orleans.Core.Abstractions/Placement/RandomPlacement.cs index 95ab65cbb6..e8ea3baa6e 100644 --- a/src/Orleans.Core.Abstractions/Placement/RandomPlacement.cs +++ b/src/Orleans.Core.Abstractions/Placement/RandomPlacement.cs @@ -6,18 +6,5 @@ namespace Orleans.Runtime internal class RandomPlacement : PlacementStrategy { internal static RandomPlacement Singleton { get; } = new RandomPlacement(); - - private RandomPlacement() - { } - - public override bool Equals(object obj) - { - return obj is RandomPlacement; - } - - public override int GetHashCode() - { - return GetType().GetHashCode(); - } } } diff --git a/src/Orleans.Core.Abstractions/Placement/StatelessWorkerPlacement.cs b/src/Orleans.Core.Abstractions/Placement/StatelessWorkerPlacement.cs index 1dfe069f9b..c2c2e265f7 100644 --- a/src/Orleans.Core.Abstractions/Placement/StatelessWorkerPlacement.cs +++ b/src/Orleans.Core.Abstractions/Placement/StatelessWorkerPlacement.cs @@ -5,7 +5,7 @@ namespace Orleans.Runtime [Serializable] internal class StatelessWorkerPlacement : PlacementStrategy { - private static readonly int defaultMaxStatelessWorkers = Environment.ProcessorCount; + private static readonly int DefaultMaxStatelessWorkers = Environment.ProcessorCount; public int MaxLocal { get; private set; } @@ -13,24 +13,12 @@ internal StatelessWorkerPlacement(int maxLocal = -1) { // If maxLocal was not specified on the StatelessWorkerAttribute, // we will use the defaultMaxStatelessWorkers, which is System.Environment.ProcessorCount. - MaxLocal = maxLocal > 0 ? maxLocal : defaultMaxStatelessWorkers; + this.MaxLocal = maxLocal > 0 ? maxLocal : DefaultMaxStatelessWorkers; } public override string ToString() { - return String.Format("StatelessWorkerPlacement(max={0})", MaxLocal); - } - - public override bool Equals(object obj) - { - var other = obj as StatelessWorkerPlacement; - return other != null && MaxLocal == other.MaxLocal; - } - - public override int GetHashCode() - { - return GetType().GetHashCode() ^ MaxLocal.GetHashCode(); + return string.Format("StatelessWorkerPlacement(max={0})", this.MaxLocal); } } - } diff --git a/src/Orleans.Core.Abstractions/Versions/Compatibility/AllVersionsCompatible.cs b/src/Orleans.Core.Abstractions/Versions/Compatibility/AllVersionsCompatible.cs index 492efb2df0..2a8982b978 100644 --- a/src/Orleans.Core.Abstractions/Versions/Compatibility/AllVersionsCompatible.cs +++ b/src/Orleans.Core.Abstractions/Versions/Compatibility/AllVersionsCompatible.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace Orleans.Versions.Compatibility { @@ -6,18 +6,5 @@ namespace Orleans.Versions.Compatibility public class AllVersionsCompatible : CompatibilityStrategy { public static AllVersionsCompatible Singleton { get; } = new AllVersionsCompatible(); - - private AllVersionsCompatible() - { } - - public override bool Equals(object obj) - { - return obj is AllVersionsCompatible; - } - - public override int GetHashCode() - { - return GetType().GetHashCode(); - } } } diff --git a/src/Orleans.Core.Abstractions/Versions/Compatibility/BackwardCompatible.cs b/src/Orleans.Core.Abstractions/Versions/Compatibility/BackwardCompatible.cs index 6bf120ffde..a035d5560b 100644 --- a/src/Orleans.Core.Abstractions/Versions/Compatibility/BackwardCompatible.cs +++ b/src/Orleans.Core.Abstractions/Versions/Compatibility/BackwardCompatible.cs @@ -6,18 +6,5 @@ namespace Orleans.Versions.Compatibility public class BackwardCompatible : CompatibilityStrategy { public static BackwardCompatible Singleton { get; } = new BackwardCompatible(); - - private BackwardCompatible() - { } - - public override bool Equals(object obj) - { - return obj is BackwardCompatible; - } - - public override int GetHashCode() - { - return GetType().GetHashCode(); - } } } \ No newline at end of file diff --git a/src/Orleans.Core.Abstractions/Versions/Compatibility/ICompatibilityDirector.cs b/src/Orleans.Core.Abstractions/Versions/Compatibility/ICompatibilityDirector.cs index 89748e1549..1d5354f41b 100644 --- a/src/Orleans.Core.Abstractions/Versions/Compatibility/ICompatibilityDirector.cs +++ b/src/Orleans.Core.Abstractions/Versions/Compatibility/ICompatibilityDirector.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace Orleans.Versions.Compatibility { @@ -7,22 +7,8 @@ public interface ICompatibilityDirector bool IsCompatible(ushort requestedVersion, ushort currentVersion); } - public interface ICompatibilityDirector : ICompatibilityDirector where TStrategy : CompatibilityStrategy - { - } - [Serializable] public abstract class CompatibilityStrategy { - public static CompatibilityStrategy Parse(string str) - { - if (str.Equals(typeof(AllVersionsCompatible).Name)) - return AllVersionsCompatible.Singleton; - if (str.Equals(typeof(BackwardCompatible).Name)) - return BackwardCompatible.Singleton; - if (str.Equals(typeof(StrictVersionCompatible).Name)) - return StrictVersionCompatible.Singleton; - return null; - } } } \ No newline at end of file diff --git a/src/Orleans.Core.Abstractions/Versions/Compatibility/StrictVersionCompatible.cs b/src/Orleans.Core.Abstractions/Versions/Compatibility/StrictVersionCompatible.cs index fc32970833..04ec97d125 100644 --- a/src/Orleans.Core.Abstractions/Versions/Compatibility/StrictVersionCompatible.cs +++ b/src/Orleans.Core.Abstractions/Versions/Compatibility/StrictVersionCompatible.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace Orleans.Versions.Compatibility { @@ -6,18 +6,5 @@ namespace Orleans.Versions.Compatibility public class StrictVersionCompatible : CompatibilityStrategy { public static StrictVersionCompatible Singleton { get; } = new StrictVersionCompatible(); - - private StrictVersionCompatible() - { } - - public override bool Equals(object obj) - { - return obj is StrictVersionCompatible; - } - - public override int GetHashCode() - { - return GetType().GetHashCode(); - } } } \ No newline at end of file diff --git a/src/Orleans.Core.Abstractions/Versions/Selector/AllCompatibleVersions.cs b/src/Orleans.Core.Abstractions/Versions/Selector/AllCompatibleVersions.cs index 8fcd063ff9..4a57623d80 100644 --- a/src/Orleans.Core.Abstractions/Versions/Selector/AllCompatibleVersions.cs +++ b/src/Orleans.Core.Abstractions/Versions/Selector/AllCompatibleVersions.cs @@ -6,18 +6,5 @@ namespace Orleans.Versions.Selector public class AllCompatibleVersions : VersionSelectorStrategy { public static AllCompatibleVersions Singleton { get; } = new AllCompatibleVersions(); - - private AllCompatibleVersions() - { } - - public override bool Equals(object obj) - { - return obj is AllCompatibleVersions; - } - - public override int GetHashCode() - { - return GetType().GetHashCode(); - } } } \ No newline at end of file diff --git a/src/Orleans.Core.Abstractions/Versions/Selector/IVersionSelector.cs b/src/Orleans.Core.Abstractions/Versions/Selector/IVersionSelector.cs index 99184b992f..1d2992cf1e 100644 --- a/src/Orleans.Core.Abstractions/Versions/Selector/IVersionSelector.cs +++ b/src/Orleans.Core.Abstractions/Versions/Selector/IVersionSelector.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using Orleans.Versions.Compatibility; @@ -9,22 +9,8 @@ public interface IVersionSelector IReadOnlyList GetSuitableVersion(ushort requestedVersion, IReadOnlyList availableVersions, ICompatibilityDirector compatibilityDirector); } - public interface IVersionSelector : IVersionSelector where TPolicy : VersionSelectorStrategy - { - } - [Serializable] public abstract class VersionSelectorStrategy { - public static VersionSelectorStrategy Parse(string str) - { - if (str.Equals(typeof(AllCompatibleVersions).Name)) - return AllCompatibleVersions.Singleton; - if (str.Equals(typeof(LatestVersion).Name)) - return LatestVersion.Singleton; - if (str.Equals(typeof(MinimumVersion).Name)) - return MinimumVersion.Singleton; - return null; - } } } \ No newline at end of file diff --git a/src/Orleans.Core.Abstractions/Versions/Selector/LatestVersion.cs b/src/Orleans.Core.Abstractions/Versions/Selector/LatestVersion.cs index 69f27443b5..c3a26a7729 100644 --- a/src/Orleans.Core.Abstractions/Versions/Selector/LatestVersion.cs +++ b/src/Orleans.Core.Abstractions/Versions/Selector/LatestVersion.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace Orleans.Versions.Selector { @@ -6,18 +6,5 @@ namespace Orleans.Versions.Selector public class LatestVersion : VersionSelectorStrategy { public static LatestVersion Singleton { get; } = new LatestVersion(); - - private LatestVersion() - { } - - public override bool Equals(object obj) - { - return obj is LatestVersion; - } - - public override int GetHashCode() - { - return GetType().GetHashCode(); - } } } \ No newline at end of file diff --git a/src/Orleans.Core.Abstractions/Versions/Selector/MinimumVersion.cs b/src/Orleans.Core.Abstractions/Versions/Selector/MinimumVersion.cs index 6b0a972065..614e2b4e52 100644 --- a/src/Orleans.Core.Abstractions/Versions/Selector/MinimumVersion.cs +++ b/src/Orleans.Core.Abstractions/Versions/Selector/MinimumVersion.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace Orleans.Versions.Selector { @@ -6,18 +6,5 @@ namespace Orleans.Versions.Selector public class MinimumVersion : VersionSelectorStrategy { public static MinimumVersion Singleton { get; } = new MinimumVersion(); - - private MinimumVersion() - { } - - public override bool Equals(object obj) - { - return obj is MinimumVersion; - } - - public override int GetHashCode() - { - return GetType().GetHashCode(); - } } } \ No newline at end of file diff --git a/src/Orleans.Core/Configuration/ApplicationConfiguration.cs b/src/Orleans.Core.Legacy/Configuration/ApplicationConfiguration.cs similarity index 83% rename from src/Orleans.Core/Configuration/ApplicationConfiguration.cs rename to src/Orleans.Core.Legacy/Configuration/ApplicationConfiguration.cs index 2a173cd93b..86793db3c1 100644 --- a/src/Orleans.Core/Configuration/ApplicationConfiguration.cs +++ b/src/Orleans.Core.Legacy/Configuration/ApplicationConfiguration.cs @@ -4,7 +4,7 @@ using System.Text; using System.Xml; using Microsoft.Extensions.Logging; - +using Orleans.Hosting; namespace Orleans.Runtime.Configuration { @@ -23,15 +23,15 @@ public class ApplicationConfiguration /// public TimeSpan DefaultCollectionAgeLimit { - get { return defaults.CollectionAgeLimit.HasValue ? defaults.CollectionAgeLimit.Value : GlobalConfiguration.DEFAULT_COLLECTION_AGE_LIMIT; } + get { return this.defaults.CollectionAgeLimit ?? GrainCollectionOptions.DEFAULT_COLLECTION_AGE_LIMIT; } } internal TimeSpan ShortestCollectionAgeLimit { get { - TimeSpan shortest = DefaultCollectionAgeLimit; - foreach (var typeConfig in ClassSpecific) + TimeSpan shortest = this.DefaultCollectionAgeLimit; + foreach (var typeConfig in this.ClassSpecific) { TimeSpan curr = typeConfig.CollectionAgeLimit.Value; if (curr < shortest) @@ -49,14 +49,14 @@ internal TimeSpan ShortestCollectionAgeLimit /// The default time period used to collect in-active activations. public ApplicationConfiguration(TimeSpan? defaultCollectionAgeLimit = null) { - classSpecific = new Dictionary(); - defaults = new GrainTypeConfiguration(null, defaultCollectionAgeLimit); + this.classSpecific = new Dictionary(); + this.defaults = new GrainTypeConfiguration(null, defaultCollectionAgeLimit); } /// /// IEnumerable of all configurations for different grain types. /// - public IEnumerable ClassSpecific { get { return classSpecific.Values; } } + public IEnumerable ClassSpecific { get { return this.classSpecific.Values; } } /// /// Load this configuratin from xml element. @@ -73,15 +73,15 @@ public void Load(XmlElement xmlElement) if (config.AreDefaults) { - defaults = config; + this.defaults = config; } else { - if (classSpecific.ContainsKey(config.FullTypeName)) + if (this.classSpecific.ContainsKey(config.FullTypeName)) { throw new InvalidOperationException(string.Format("duplicate type {0} in configuration", config.FullTypeName)); } - classSpecific.Add(config.FullTypeName, config); + this.classSpecific.Add(config.FullTypeName, config); } } @@ -112,13 +112,13 @@ public TimeSpan GetCollectionAgeLimit(Type type) /// public TimeSpan GetCollectionAgeLimit(string grainTypeFullName) { - if (String.IsNullOrEmpty(grainTypeFullName)) + if (string.IsNullOrEmpty(grainTypeFullName)) { throw new ArgumentNullException("grainTypeFullName"); } GrainTypeConfiguration config; - return classSpecific.TryGetValue(grainTypeFullName, out config) && config.CollectionAgeLimit.HasValue ? - config.CollectionAgeLimit.Value : DefaultCollectionAgeLimit; + return this.classSpecific.TryGetValue(grainTypeFullName, out config) && config.CollectionAgeLimit.HasValue ? + config.CollectionAgeLimit.Value : this.DefaultCollectionAgeLimit; } @@ -143,17 +143,17 @@ public void SetCollectionAgeLimit(Type type, TimeSpan ageLimit) /// The age limit to use. public void SetCollectionAgeLimit(string grainTypeFullName, TimeSpan ageLimit) { - if (String.IsNullOrEmpty(grainTypeFullName)) + if (string.IsNullOrEmpty(grainTypeFullName)) { throw new ArgumentNullException("grainTypeFullName"); } ThrowIfLessThanZero(ageLimit, "ageLimit"); GrainTypeConfiguration config; - if (!classSpecific.TryGetValue(grainTypeFullName, out config)) + if (!this.classSpecific.TryGetValue(grainTypeFullName, out config)) { config = new GrainTypeConfiguration(grainTypeFullName); - classSpecific[grainTypeFullName] = config; + this.classSpecific[grainTypeFullName] = config; } config.SetCollectionAgeLimit(ageLimit); @@ -178,12 +178,12 @@ public void ResetCollectionAgeLimitToDefault(Type type) /// Grain type full name. public void ResetCollectionAgeLimitToDefault(string grainTypeFullName) { - if (String.IsNullOrEmpty(grainTypeFullName)) + if (string.IsNullOrEmpty(grainTypeFullName)) { throw new ArgumentNullException(nameof(grainTypeFullName)); } GrainTypeConfiguration config; - if (!classSpecific.TryGetValue(grainTypeFullName, out config)) return; + if (!this.classSpecific.TryGetValue(grainTypeFullName, out config)) return; config.SetCollectionAgeLimit(null); } @@ -195,7 +195,7 @@ public void ResetCollectionAgeLimitToDefault(string grainTypeFullName) public void SetDefaultCollectionAgeLimit(TimeSpan ageLimit) { ThrowIfLessThanZero(ageLimit, "ageLimit"); - defaults.SetCollectionAgeLimit(ageLimit); + this.defaults.SetCollectionAgeLimit(ageLimit); } private static void ThrowIfLessThanZero(TimeSpan timeSpan, string paramName) @@ -205,7 +205,7 @@ private static void ThrowIfLessThanZero(TimeSpan timeSpan, string paramName) internal void ValidateConfiguration(ILogger logger) { - foreach (GrainTypeConfiguration config in classSpecific.Values) + foreach (GrainTypeConfiguration config in this.classSpecific.Values) { config.ValidateConfiguration(logger); } @@ -220,10 +220,10 @@ public override string ToString() var result = new StringBuilder(); result.AppendFormat(" Application:").AppendLine(); result.AppendFormat(" Defaults:").AppendLine(); - result.AppendFormat(" Deactivate if idle for: {0}", DefaultCollectionAgeLimit) + result.AppendFormat(" Deactivate if idle for: {0}", this.DefaultCollectionAgeLimit) .AppendLine(); - foreach (GrainTypeConfiguration config in classSpecific.Values) + foreach (GrainTypeConfiguration config in this.classSpecific.Values) { if (!config.CollectionAgeLimit.HasValue) continue; @@ -250,12 +250,12 @@ public class GrainTypeConfiguration /// /// Whether this is a defualt configuration that applies to all grain types. /// - public bool AreDefaults { get { return FullTypeName == null; } } + public bool AreDefaults { get { return this.FullTypeName == null; } } /// /// The time period used to collect in-active activations of this type. /// - public TimeSpan? CollectionAgeLimit { get { return collectionAgeLimit; } } + public TimeSpan? CollectionAgeLimit { get { return this.collectionAgeLimit; } } private TimeSpan? collectionAgeLimit; @@ -265,7 +265,7 @@ public class GrainTypeConfiguration /// Grain type of this configuration. public GrainTypeConfiguration(string type) { - FullTypeName = type; + this.FullTypeName = type; } /// @@ -275,7 +275,7 @@ public GrainTypeConfiguration(string type) /// Age limit for this type. public GrainTypeConfiguration(string type, TimeSpan? ageLimit) { - FullTypeName = type; + this.FullTypeName = type; SetCollectionAgeLimit(ageLimit); } @@ -285,10 +285,10 @@ public void SetCollectionAgeLimit(TimeSpan? ageLimit) { if (ageLimit == null) { - collectionAgeLimit = null; + this.collectionAgeLimit = null; } - TimeSpan minAgeLimit = GlobalConfiguration.DEFAULT_COLLECTION_QUANTUM; + TimeSpan minAgeLimit = GrainCollectionOptions.DEFAULT_COLLECTION_QUANTUM; if (ageLimit < minAgeLimit) { if (GlobalConfiguration.ENFORCE_MINIMUM_REQUIREMENT_FOR_AGE_LIMIT) @@ -296,7 +296,7 @@ public void SetCollectionAgeLimit(TimeSpan? ageLimit) throw new ArgumentOutOfRangeException($"The AgeLimit attribute is required to be at least {minAgeLimit}."); } } - collectionAgeLimit = ageLimit; + this.collectionAgeLimit = ageLimit; } /// @@ -340,28 +340,28 @@ public static GrainTypeConfiguration Load(XmlElement xmlElement) if (found) return new GrainTypeConfiguration(fullTypeName, collectionAgeLimit); - throw new InvalidOperationException(string.Format("empty GrainTypeConfiguration for {0}", fullTypeName == null ? "defaults" : fullTypeName)); + throw new InvalidOperationException(string.Format("empty GrainTypeConfiguration for {0}", fullTypeName ?? "defaults")); } internal void ValidateConfiguration(ILogger logger) { - if (AreDefaults) return; + if (this.AreDefaults) return; Type type = null; try { - type = new CachedTypeResolver().ResolveType(FullTypeName); + type = new CachedTypeResolver().ResolveType(this.FullTypeName); } catch (Exception exception) { - string errStr = String.Format("Unable to find grain class type {0} specified in configuration; Failing silo startup.", FullTypeName); + string errStr = string.Format("Unable to find grain class type {0} specified in configuration; Failing silo startup.", this.FullTypeName); logger.Error(ErrorCode.Loader_TypeLoadError, errStr, exception); throw new OrleansException(errStr, exception); } if (type == null) { - string errStr = String.Format("Unable to find grain class type {0} specified in configuration; Failing silo startup.", FullTypeName); + string errStr = string.Format("Unable to find grain class type {0} specified in configuration; Failing silo startup.", this.FullTypeName); logger.Error(ErrorCode.Loader_TypeLoadError_2, errStr); throw new OrleansException(errStr); } @@ -369,7 +369,7 @@ internal void ValidateConfiguration(ILogger logger) // postcondition: returned type must implement IGrain. if (!typeof(IGrain).IsAssignableFrom(type)) { - string errStr = String.Format("Type {0} must implement IGrain to be used Application configuration context.",type.FullName); + string errStr = string.Format("Type {0} must implement IGrain to be used Application configuration context.",type.FullName); logger.Error(ErrorCode.Loader_TypeLoadError_3, errStr); throw new OrleansException(errStr); } @@ -377,7 +377,7 @@ internal void ValidateConfiguration(ILogger logger) if (!typeInfo.IsInterface && !typeInfo.IsClass) { - string errStr = String.Format("Type {0} must either be an interface or class used Application configuration context.",type.FullName); + string errStr = string.Format("Type {0} must either be an interface or class used Application configuration context.",type.FullName); logger.Error(ErrorCode.Loader_TypeLoadError_4, errStr); throw new OrleansException(errStr); } diff --git a/src/Orleans.Core/Configuration/ClusterConfiguration.cs b/src/Orleans.Core.Legacy/Configuration/ClusterConfiguration.cs similarity index 57% rename from src/Orleans.Core/Configuration/ClusterConfiguration.cs rename to src/Orleans.Core.Legacy/Configuration/ClusterConfiguration.cs index a616e589e5..e7f1f8ac21 100644 --- a/src/Orleans.Core/Configuration/ClusterConfiguration.cs +++ b/src/Orleans.Core.Legacy/Configuration/ClusterConfiguration.cs @@ -38,7 +38,7 @@ public class ClusterConfiguration /// /// The Primary Node IP and port (in dev setting). /// - public IPEndPoint PrimaryNode { get { return primaryNode; } set { SetPrimaryNode(value); } } + public IPEndPoint PrimaryNode { get { return this.primaryNode; } set { SetPrimaryNode(value); } } /// /// Per silo configuration parameters overrides. @@ -67,12 +67,12 @@ public ClusterConfiguration(TextReader input) private void Init() { - Globals = new GlobalConfiguration(); - Defaults = new NodeConfiguration(); - Overrides = new Dictionary(); - overrideXml = new Dictionary(); - SourceFile = ""; - IsRunningAsUnitTest = false; + this.Globals = new GlobalConfiguration(); + this.Defaults = new NodeConfiguration(); + this.Overrides = new Dictionary(); + this.overrideXml = new Dictionary(); + this.SourceFile = ""; + this.IsRunningAsUnitTest = false; } /// @@ -96,24 +96,24 @@ internal void LoadFromXml(XmlElement root) switch (child.LocalName) { case "Globals": - Globals.Load(child); + this.Globals.Load(child); // set subnets so this is independent of order - Defaults.Subnet = Globals.Subnet; - foreach (var o in Overrides.Values) + this.Defaults.Subnet = this.Globals.Subnet; + foreach (var o in this.Overrides.Values) { - o.Subnet = Globals.Subnet; + o.Subnet = this.Globals.Subnet; } - if (Globals.SeedNodes.Count > 0) + if (this.Globals.SeedNodes.Count > 0) { - primaryNode = Globals.SeedNodes[0]; + this.primaryNode = this.Globals.SeedNodes[0]; } break; case "Defaults": - Defaults.Load(child); - Defaults.Subnet = Globals.Subnet; + this.Defaults.Load(child); + this.Defaults.Subnet = this.Globals.Subnet; break; case "Override": - overrideXml[child.GetAttribute("Node")] = WriteXml(child); + this.overrideXml[child.GetAttribute("Node")] = WriteXml(child); break; } } @@ -136,57 +136,57 @@ private static string WriteXml(XmlElement element) private void CalculateOverrides() { - if (Globals.LivenessEnabled && - Globals.LivenessType == GlobalConfiguration.LivenessProviderType.NotSpecified) + if (this.Globals.LivenessEnabled && + this.Globals.LivenessType == GlobalConfiguration.LivenessProviderType.NotSpecified) { - if (Globals.UseSqlSystemStore) + if (this.Globals.UseSqlSystemStore) { - Globals.LivenessType = GlobalConfiguration.LivenessProviderType.SqlServer; + this.Globals.LivenessType = GlobalConfiguration.LivenessProviderType.SqlServer; } - else if (Globals.UseAzureSystemStore) + else if (this.Globals.UseAzureSystemStore) { - Globals.LivenessType = GlobalConfiguration.LivenessProviderType.AzureTable; + this.Globals.LivenessType = GlobalConfiguration.LivenessProviderType.AzureTable; } - else if (Globals.UseZooKeeperSystemStore) + else if (this.Globals.UseZooKeeperSystemStore) { - Globals.LivenessType = GlobalConfiguration.LivenessProviderType.ZooKeeper; + this.Globals.LivenessType = GlobalConfiguration.LivenessProviderType.ZooKeeper; } else { - Globals.LivenessType = GlobalConfiguration.LivenessProviderType.MembershipTableGrain; + this.Globals.LivenessType = GlobalConfiguration.LivenessProviderType.MembershipTableGrain; } } - if (Globals.UseMockReminderTable) + if (this.Globals.UseMockReminderTable) { - Globals.SetReminderServiceType(GlobalConfiguration.ReminderServiceProviderType.MockTable); + this.Globals.SetReminderServiceType(GlobalConfiguration.ReminderServiceProviderType.MockTable); } - else if (Globals.ReminderServiceType == GlobalConfiguration.ReminderServiceProviderType.NotSpecified) + else if (this.Globals.ReminderServiceType == GlobalConfiguration.ReminderServiceProviderType.NotSpecified) { - if (Globals.UseSqlSystemStore) + if (this.Globals.UseSqlSystemStore) { - Globals.SetReminderServiceType(GlobalConfiguration.ReminderServiceProviderType.SqlServer); + this.Globals.SetReminderServiceType(GlobalConfiguration.ReminderServiceProviderType.SqlServer); } - else if (Globals.UseAzureSystemStore) + else if (this.Globals.UseAzureSystemStore) { - Globals.SetReminderServiceType(GlobalConfiguration.ReminderServiceProviderType.AzureTable); + this.Globals.SetReminderServiceType(GlobalConfiguration.ReminderServiceProviderType.AzureTable); } - else if (Globals.UseZooKeeperSystemStore) + else if (this.Globals.UseZooKeeperSystemStore) { - Globals.SetReminderServiceType(GlobalConfiguration.ReminderServiceProviderType.Disabled); + this.Globals.SetReminderServiceType(GlobalConfiguration.ReminderServiceProviderType.Disabled); } else { - Globals.SetReminderServiceType(GlobalConfiguration.ReminderServiceProviderType.ReminderTableGrain); + this.Globals.SetReminderServiceType(GlobalConfiguration.ReminderServiceProviderType.ReminderTableGrain); } } - foreach (var p in overrideXml) + foreach (var p in this.overrideXml) { - var n = new NodeConfiguration(Defaults); + var n = new NodeConfiguration(this.Defaults); n.Load(ParseXml(new StringReader(p.Value))); n.InitNodeSettingsFromGlobals(this); - Overrides[n.SiloName] = n; + this.Overrides[n.SiloName] = n; } } @@ -197,7 +197,7 @@ public void LoadFromFile(string fileName) using (TextReader input = File.OpenText(fileName)) { Load(input); - SourceFile = fileName; + this.SourceFile = fileName; } } @@ -209,7 +209,7 @@ public void LoadFromFile(string fileName) /// true if node was found public bool TryGetNodeConfigurationForSilo(string siloName, out NodeConfiguration siloNode) { - return Overrides.TryGetValue(siloName, out siloNode); + return this.Overrides.TryGetValue(siloName, out siloNode); } /// @@ -219,9 +219,9 @@ public bool TryGetNodeConfigurationForSilo(string siloName, out NodeConfiguratio /// NodeConfiguration associated with the specified silo. public NodeConfiguration CreateNodeConfigurationForSilo(string siloName) { - var siloNode = new NodeConfiguration(Defaults) { SiloName = siloName }; + var siloNode = new NodeConfiguration(this.Defaults) { SiloName = siloName }; siloNode.InitNodeSettingsFromGlobals(this); - Overrides[siloName] = siloNode; + this.Overrides[siloName] = siloNode; return siloNode; } @@ -238,8 +238,8 @@ public NodeConfiguration GetOrCreateNodeConfigurationForSilo(string siloName) private void SetPrimaryNode(IPEndPoint primary) { - primaryNode = primary; - foreach (NodeConfiguration node in Overrides.Values) + this.primaryNode = primary; + foreach (NodeConfiguration node in this.Overrides.Values) { if (node.Endpoint.Equals(primary)) { @@ -261,7 +261,7 @@ public void StandardLoad() /// /// Subset of XML configuration file that is updatable at runtime /// - private static readonly XmlElement updatableXml = ParseXml(new StringReader(@" + private static readonly XmlElement UpdatableXml = ParseXml(new StringReader(@" @@ -284,14 +284,14 @@ public void Update(string input) { var xml = ParseXml(new StringReader(input)); var disallowed = new List(); - CheckSubtree(updatableXml, xml, "", disallowed); + CheckSubtree(UpdatableXml, xml, "", disallowed); if (disallowed.Count > 0) throw new ArgumentException("Cannot update configuration with" + disallowed.ToStrings()); var dict = ToChildDictionary(xml); XmlElement globals; if (dict.TryGetValue("Globals", out globals)) { - Globals.Load(globals); + this.Globals.Load(globals); ConfigChanged("Globals"); foreach (var key in ToChildDictionary(globals).Keys) { @@ -301,7 +301,7 @@ public void Update(string input) XmlElement defaults; if (dict.TryGetValue("Defaults", out defaults)) { - Defaults.Load(defaults); + this.Defaults.Load(defaults); CalculateOverrides(); ConfigChanged("Defaults"); foreach (var key in ToChildDictionary(defaults).Keys) @@ -370,10 +370,10 @@ private static IEnumerable AttributeNames(XmlElement element) internal void OnConfigChange(string path, Action action, bool invokeNow = true) { List list; - if (listeners.TryGetValue(path, out list)) + if (this.listeners.TryGetValue(path, out list)) list.Add(action); else - listeners.Add(path, new List { action }); + this.listeners.Add(path, new List { action }); if (invokeNow) action(); } @@ -381,7 +381,7 @@ internal void OnConfigChange(string path, Action action, bool invokeNow = true) internal void ConfigChanged(string path) { List list; - if (!listeners.TryGetValue(path, out list)) return; + if (!this.listeners.TryGetValue(path, out list)) return; foreach (var action in list) action(); @@ -395,12 +395,12 @@ internal void ConfigChanged(string path) public string ToString(string siloName) { var sb = new StringBuilder(); - sb.Append("Config File Name: ").AppendLine(string.IsNullOrEmpty(SourceFile) ? "" : Path.GetFullPath(SourceFile)); + sb.Append("Config File Name: ").AppendLine(string.IsNullOrEmpty(this.SourceFile) ? "" : Path.GetFullPath(this.SourceFile)); sb.Append("Host: ").AppendLine(Dns.GetHostName()); sb.Append("Start time: ").AppendLine(LogFormatter.PrintDate(DateTime.UtcNow)); - sb.Append("Primary node: ").AppendLine(PrimaryNode == null ? "null" : PrimaryNode.ToString()); + sb.Append("Primary node: ").AppendLine(this.PrimaryNode == null ? "null" : this.PrimaryNode.ToString()); sb.AppendLine("Platform version info:").Append(ConfigUtilities.RuntimeVersionInfo()); - sb.AppendLine("Global configuration:").Append(Globals.ToString()); + sb.AppendLine("Global configuration:").Append(this.Globals.ToString()); NodeConfiguration nc; if (TryGetNodeConfigurationForSilo(siloName, out nc)) { @@ -410,144 +410,6 @@ public string ToString(string siloName) return sb.ToString(); } - internal static async Task ResolveIPAddress(string addrOrHost, byte[] subnet, AddressFamily family) - { - var loopback = family == AddressFamily.InterNetwork ? IPAddress.Loopback : IPAddress.IPv6Loopback; - - // IF the address is an empty string, default to the local machine - if (string.IsNullOrEmpty(addrOrHost)) - { - addrOrHost = Dns.GetHostName(); - } - - // Fix StreamFilteringTests_SMS tests - if (addrOrHost.Equals("loopback", StringComparison.OrdinalIgnoreCase)) - { - return loopback; - } - - // check if addrOrHost is a valid IP address including loopback (127.0.0.0/8, ::1) and any (0.0.0.0/0, ::) addresses - IPAddress address; - if (IPAddress.TryParse(addrOrHost, out address)) - { - return address; - } - - var candidates = new List(); - - // Get IP address from DNS. If addrOrHost is localhost will - // return loopback IPv4 address (or IPv4 and IPv6 addresses if OS is supported IPv6) - var nodeIps = await Dns.GetHostAddressesAsync(addrOrHost); - foreach (var nodeIp in nodeIps.Where(x => x.AddressFamily == family)) - { - // If the subnet does not match - we can't resolve this address. - // If subnet is not specified - pick smallest address deterministically. - if (subnet == null) - { - candidates.Add(nodeIp); - } - else - { - var ip = nodeIp; - if (subnet.Select((b, i) => ip.GetAddressBytes()[i] == b).All(x => x)) - { - candidates.Add(nodeIp); - } - } - } - if (candidates.Count > 0) - { - return PickIPAddress(candidates); - } - var subnetStr = Utils.EnumerableToString(subnet, null, ".", false); - throw new ArgumentException("Hostname '" + addrOrHost + "' with subnet " + subnetStr + " and family " + family + " is not a valid IP address or DNS name"); - } - - private static IPAddress PickIPAddress(IReadOnlyList candidates) - { - IPAddress chosen = null; - foreach (IPAddress addr in candidates) - { - if (chosen == null) - { - chosen = addr; - } - else - { - if (CompareIPAddresses(addr, chosen)) // pick smallest address deterministically - chosen = addr; - } - } - return chosen; - } - - // returns true if lhs is "less" (in some repeatable sense) than rhs - private static bool CompareIPAddresses(IPAddress lhs, IPAddress rhs) - { - byte[] lbytes = lhs.GetAddressBytes(); - byte[] rbytes = rhs.GetAddressBytes(); - - if (lbytes.Length != rbytes.Length) return lbytes.Length < rbytes.Length; - - // compare starting from most significant octet. - // 10.68.20.21 < 10.98.05.04 - for (int i = 0; i < lbytes.Length; i++) - { - if (lbytes[i] != rbytes[i]) - { - return lbytes[i] < rbytes[i]; - } - } - // They're equal - return false; - } - - /// - /// Gets the address of the local server. - /// If there are multiple addresses in the correct family in the server's DNS record, the first will be returned. - /// - /// The server's IPv4 address. - internal static IPAddress GetLocalIPAddress(AddressFamily family = AddressFamily.InterNetwork, string interfaceName = null) - { - var loopback = (family == AddressFamily.InterNetwork) ? IPAddress.Loopback : IPAddress.IPv6Loopback; - // get list of all network interfaces - NetworkInterface[] netInterfaces = NetworkInterface.GetAllNetworkInterfaces(); - - var candidates = new List(); - // loop through interfaces - for (int i = 0; i < netInterfaces.Length; i++) - { - NetworkInterface netInterface = netInterfaces[i]; - - if (netInterface.OperationalStatus != OperationalStatus.Up) - { - // Skip network interfaces that are not operational - continue; - } - if (!string.IsNullOrWhiteSpace(interfaceName) && - !netInterface.Name.StartsWith(interfaceName, StringComparison.Ordinal)) continue; - - bool isLoopbackInterface = (netInterface.NetworkInterfaceType == NetworkInterfaceType.Loopback); - // get list of all unicast IPs from current interface - UnicastIPAddressInformationCollection ipAddresses = netInterface.GetIPProperties().UnicastAddresses; - - // loop through IP address collection - foreach (UnicastIPAddressInformation ip in ipAddresses) - { - if (ip.Address.AddressFamily == family) // Picking the first address of the requested family for now. Will need to revisit later - { - //don't pick loopback address, unless we were asked for a loopback interface - if (!(isLoopbackInterface && ip.Address.Equals(loopback))) - { - candidates.Add(ip.Address); // collect all candidates. - } - } - } - } - if (candidates.Count > 0) return PickIPAddress(candidates); - throw new OrleansException("Failed to get a local IP address."); - } - private static XmlElement ParseXml(TextReader input) { var doc = new XmlDocument(); diff --git a/src/Orleans.Core.Legacy/Configuration/ConfigurationExtensions.cs b/src/Orleans.Core.Legacy/Configuration/ConfigurationExtensions.cs new file mode 100644 index 0000000000..34b74f9e29 --- /dev/null +++ b/src/Orleans.Core.Legacy/Configuration/ConfigurationExtensions.cs @@ -0,0 +1,60 @@ +using System; +using System.Collections.Generic; +using Orleans.Providers.Streams.SimpleMessageStream; +using Orleans.Streams; + +namespace Orleans.Runtime.Configuration +{ + /// + /// Extension methods for configuration classes specific to Orleans.dll + /// + public static class ConfigurationExtensions + { + /// + /// Adds a stream provider of type + /// + /// The cluster configuration object to add provider to. + /// The provider name. + /// Specifies whether the producer waits for the consumer to process the event before continuing. Setting this to false is useful for troubleshooting serialization issues. + /// If set to true items transfered via the stream are always wrapped in Immutable for delivery. + /// Specifies how can grains subscribe to this stream. + public static void AddSimpleMessageStreamProvider(this ClusterConfiguration config, string providerName, + bool fireAndForgetDelivery = SimpleMessageStreamProvider.DEFAULT_VALUE_FIRE_AND_FORGET_DELIVERY, + bool optimizeForImmutableData = SimpleMessageStreamProvider.DEFAULT_VALUE_OPTIMIZE_FOR_IMMUTABLE_DATA, + StreamPubSubType pubSubType = SimpleMessageStreamProvider.DEFAULT_STREAM_PUBSUB_TYPE) + { + var properties = GetSimpleMessageStreamProviderConfiguration(providerName, fireAndForgetDelivery, optimizeForImmutableData, pubSubType); + config.Globals.RegisterStreamProvider(providerName, properties); + } + + /// + /// Configures all cluster nodes to use the specified startup class for dependency injection. + /// + /// Startup type + [Obsolete("Using ISiloHostBuilder.ConfigureServices(Action configureServices) or ISiloHostBuilder.UseServiceProviderFactory(IServiceProviderFactory factory)")] + public static void UseStartupType(this ClusterConfiguration config) + { + var startupName = typeof(TStartup).AssemblyQualifiedName; + + foreach(var nodeConfig in config.Overrides.Values) { + nodeConfig.StartupTypeName = startupName; + } + + config.Defaults.StartupTypeName = startupName; + } + + private static Dictionary GetSimpleMessageStreamProviderConfiguration(string providerName, bool fireAndForgetDelivery, bool optimizeForImmutableData, StreamPubSubType pubSubType) + { + if (string.IsNullOrWhiteSpace(providerName)) throw new ArgumentNullException(nameof(providerName)); + + var properties = new Dictionary + { + { SimpleMessageStreamProvider.FIRE_AND_FORGET_DELIVERY, fireAndForgetDelivery.ToString() }, + { SimpleMessageStreamProvider.OPTIMIZE_FOR_IMMUTABLE_DATA, optimizeForImmutableData.ToString() }, + { SimpleMessageStreamProvider.STREAM_PUBSUB_TYPE, pubSubType.ToString() }, + }; + + return properties; + } + } +} \ No newline at end of file diff --git a/src/Orleans.Core/Configuration/GlobalConfiguration.cs b/src/Orleans.Core.Legacy/Configuration/GlobalConfiguration.cs similarity index 67% rename from src/Orleans.Core/Configuration/GlobalConfiguration.cs rename to src/Orleans.Core.Legacy/Configuration/GlobalConfiguration.cs index 5423a2bca3..93b9497ece 100644 --- a/src/Orleans.Core/Configuration/GlobalConfiguration.cs +++ b/src/Orleans.Core.Legacy/Configuration/GlobalConfiguration.cs @@ -13,6 +13,7 @@ using Orleans.LogConsistency; using Orleans.Versions.Compatibility; using Orleans.Versions.Selector; +using Orleans.Hosting; namespace Orleans.Runtime.Configuration { @@ -25,8 +26,8 @@ internal class ConfigValue public ConfigValue(T val, bool isDefaultValue) { - Value = val; - IsDefaultValue = isDefaultValue; + this.Value = val; + this.IsDefaultValue = isDefaultValue; } } @@ -85,6 +86,28 @@ public enum ReminderServiceProviderType Custom } + public static string Remap(ReminderServiceProviderType type) + { + switch(type) + { + case ReminderServiceProviderType.NotSpecified: + return ReminderOptions.BuiltIn.NotSpecified; + case ReminderServiceProviderType.ReminderTableGrain: + return ReminderOptions.BuiltIn.ReminderTableGrain; + case ReminderServiceProviderType.AzureTable: + return ReminderOptions.BuiltIn.AzureTable; + case ReminderServiceProviderType.SqlServer: + return ReminderOptions.BuiltIn.SqlServer; + case ReminderServiceProviderType.MockTable: + return ReminderOptions.BuiltIn.MockTable; + case ReminderServiceProviderType.Disabled: + return ReminderOptions.BuiltIn.Disabled; + case ReminderServiceProviderType.Custom: + return ReminderOptions.BuiltIn.Custom; + } + throw new NotSupportedException($"ReminderServiceProviderType {type} is not supported"); + } + /// /// Configuration for Gossip Channels /// @@ -97,6 +120,19 @@ public enum GossipChannelType AzureTable, } + public static string Remap(GossipChannelType type) + { + switch (type) + { + case GossipChannelType.NotSpecified: + return MultiClusterOptions.BuiltIn.NotSpecified; + case GossipChannelType.AzureTable: + return MultiClusterOptions.BuiltIn.AzureTable; + default: + throw new NotSupportedException($"GossipChannelType {type} is not supported"); + } + } + /// /// Gossip channel configuration. /// @@ -123,6 +159,35 @@ public enum DirectoryCachingStrategyType Adaptive } + private static DirectoryCachingStrategyType Remap(GrainDirectoryOptions.CachingStrategyType type) + { + switch(type) + { + case GrainDirectoryOptions.CachingStrategyType.None: + return DirectoryCachingStrategyType.None; + case GrainDirectoryOptions.CachingStrategyType.LRU: + return DirectoryCachingStrategyType.LRU; + case GrainDirectoryOptions.CachingStrategyType.Adaptive: + return DirectoryCachingStrategyType.Adaptive; + default: + throw new NotSupportedException($"CachingStrategyType {type} is not supported"); + } + } + public static GrainDirectoryOptions.CachingStrategyType Remap(DirectoryCachingStrategyType type) + { + switch (type) + { + case DirectoryCachingStrategyType.None: + return GrainDirectoryOptions.CachingStrategyType.None; + case DirectoryCachingStrategyType.LRU: + return GrainDirectoryOptions.CachingStrategyType.LRU; + case DirectoryCachingStrategyType.Adaptive: + return GrainDirectoryOptions.CachingStrategyType.Adaptive; + default: + throw new NotSupportedException($"DirectoryCachingStrategyType {type} is not supported"); + } + } + public ApplicationConfiguration Application { get; private set; } /// @@ -143,7 +208,7 @@ public enum DirectoryCachingStrategyType /// public bool PrimaryNodeIsRequired { - get { return LivenessType == LivenessProviderType.MembershipTableGrain; } + get { return this.LivenessType == LivenessProviderType.MembershipTableGrain; } } /// @@ -183,7 +248,7 @@ public bool PrimaryNodeIsRequired /// /// The expected size of a cluster. Need not be very accurate, can be an overestimate. /// - public int ExpectedClusterSize { get { return ExpectedClusterSizeConfigValue.Value; } set { ExpectedClusterSizeConfigValue = new ConfigValue(value, false); } } + public int ExpectedClusterSize { get { return this.ExpectedClusterSizeConfigValue.Value; } set { this.ExpectedClusterSizeConfigValue = new ConfigValue(value, false); } } /// /// The number of missed "I am alive" heartbeat messages from a silo or number of un-replied probes that lead to suspecting this silo as dead. /// @@ -298,9 +363,9 @@ public string DataConnectionStringForReminders { get { - return string.IsNullOrWhiteSpace(dataConnectionStringForReminders) ? DataConnectionString : dataConnectionStringForReminders; + return string.IsNullOrWhiteSpace(this.dataConnectionStringForReminders) ? this.DataConnectionString : this.dataConnectionStringForReminders; } - set { dataConnectionStringForReminders = value; } + set { this.dataConnectionStringForReminders = value; } } /// @@ -310,12 +375,12 @@ public string AdoInvariantForReminders { get { - return string.IsNullOrWhiteSpace(adoInvariantForReminders) ? AdoInvariant : adoInvariantForReminders; + return string.IsNullOrWhiteSpace(this.adoInvariantForReminders) ? this.AdoInvariant : this.adoInvariantForReminders; } - set { adoInvariantForReminders = value; } + set { this.adoInvariantForReminders = value; } } - internal TimeSpan CollectionQuantum { get; set; } + public TimeSpan CollectionQuantum { get; set; } /// /// Specifies the maximum time that a request can take before the activation is reported as "blocked" @@ -363,14 +428,14 @@ public LivenessProviderType LivenessType { get { - return livenessServiceType; + return this.livenessServiceType; } set { if (value == LivenessProviderType.NotSpecified) throw new ArgumentException("Cannot set LivenessType to " + LivenessProviderType.NotSpecified, "LivenessType"); - livenessServiceType = value; + this.livenessServiceType = value; } } @@ -392,7 +457,7 @@ public ReminderServiceProviderType ReminderServiceType { get { - return reminderServiceType; + return this.reminderServiceType; } set { @@ -407,7 +472,7 @@ internal void SetReminderServiceType(ReminderServiceProviderType reminderType) if (reminderType == ReminderServiceProviderType.NotSpecified) throw new ArgumentException("Cannot set ReminderServiceType to " + ReminderServiceProviderType.NotSpecified, "ReminderServiceType"); - reminderServiceType = reminderType; + this.reminderServiceType = reminderType; } public TimeSpan MockReminderTableTimeout { get; set; } @@ -434,7 +499,7 @@ internal void SetReminderServiceType(ReminderServiceProviderType reminderType) public TimeSpan ClientRegistrationRefresh { get; set; } - internal bool PerformDeadlockDetection { get; set; } + public bool PerformDeadlockDetection { get; set; } public bool AllowCallChainReentrancy { get; set; } @@ -456,13 +521,13 @@ internal void SetReminderServiceType(ReminderServiceProviderType reminderType) /// Determines if ADO should be used for storage of Membership and Reminders info. /// True if either or both of LivenessType and ReminderServiceType are set to SqlServer, false otherwise. /// - internal bool UseSqlSystemStore + public bool UseSqlSystemStore { get { - return !String.IsNullOrWhiteSpace(DataConnectionString) && ( - (LivenessEnabled && LivenessType == LivenessProviderType.SqlServer) - || ReminderServiceType == ReminderServiceProviderType.SqlServer); + return !string.IsNullOrWhiteSpace(this.DataConnectionString) && ( + (this.LivenessEnabled && this.LivenessType == LivenessProviderType.SqlServer) + || this.ReminderServiceType == ReminderServiceProviderType.SqlServer); } } @@ -474,8 +539,8 @@ internal bool UseZooKeeperSystemStore { get { - return !String.IsNullOrWhiteSpace(DataConnectionString) && ( - (LivenessEnabled && LivenessType == LivenessProviderType.ZooKeeper)); + return !string.IsNullOrWhiteSpace(this.DataConnectionString) && ( + (this.LivenessEnabled && this.LivenessType == LivenessProviderType.ZooKeeper)); } } @@ -483,131 +548,103 @@ internal bool UseZooKeeperSystemStore /// Determines if Azure Storage should be used for storage of Membership and Reminders info. /// True if either or both of LivenessType and ReminderServiceType are set to AzureTable, false otherwise. /// - internal bool UseAzureSystemStore + public bool UseAzureSystemStore { get { - return !String.IsNullOrWhiteSpace(DataConnectionString) - && !UseSqlSystemStore && !UseZooKeeperSystemStore; + return !string.IsNullOrWhiteSpace(this.DataConnectionString) + && !this.UseSqlSystemStore && !this.UseZooKeeperSystemStore; } } - internal bool RunsInAzure { get { return UseAzureSystemStore && !String.IsNullOrWhiteSpace(this.ClusterId); } } - - private static readonly TimeSpan DEFAULT_LIVENESS_PROBE_TIMEOUT = TimeSpan.FromSeconds(10); - private static readonly TimeSpan DEFAULT_LIVENESS_TABLE_REFRESH_TIMEOUT = TimeSpan.FromSeconds(60); - private static readonly TimeSpan DEFAULT_LIVENESS_DEATH_VOTE_EXPIRATION_TIMEOUT = TimeSpan.FromSeconds(120); - private static readonly TimeSpan DEFAULT_LIVENESS_I_AM_ALIVE_TABLE_PUBLISH_TIMEOUT = TimeSpan.FromMinutes(5); - private static readonly TimeSpan DEFAULT_LIVENESS_MAX_JOIN_ATTEMPT_TIME = TimeSpan.FromMinutes(5); // 5 min - private static readonly TimeSpan DEFAULT_REFRESH_CLUSTER_INTERFACEMAP_TIME = TimeSpan.FromMinutes(1); - private const int DEFAULT_LIVENESS_NUM_MISSED_PROBES_LIMIT = 3; - private const int DEFAULT_LIVENESS_NUM_PROBED_SILOS = 3; - private const int DEFAULT_LIVENESS_NUM_VOTES_FOR_DEATH_DECLARATION = 2; - private const int DEFAULT_LIVENESS_NUM_TABLE_I_AM_ALIVE_LIMIT = 2; - private const bool DEFAULT_LIVENESS_USE_LIVENESS_GOSSIP = true; - private const bool DEFAULT_VALIDATE_INITIAL_CONNECTIVITY = true; + internal bool RunsInAzure { get { return this.UseAzureSystemStore && !string.IsNullOrWhiteSpace(this.ClusterId); } } + private const int DEFAULT_MAX_MULTICLUSTER_GATEWAYS = 10; private const bool DEFAULT_USE_GLOBAL_SINGLE_INSTANCE = true; private static readonly TimeSpan DEFAULT_BACKGROUND_GOSSIP_INTERVAL = TimeSpan.FromSeconds(30); - private static readonly TimeSpan DEFAULT_GLOBAL_SINGLE_INSTANCE_RETRY_INTERVAL = TimeSpan.FromSeconds(30); private const int DEFAULT_GLOBAL_SINGLE_INSTANCE_NUMBER_RETRIES = 10; private const int DEFAULT_LIVENESS_EXPECTED_CLUSTER_SIZE = 20; - private const int DEFAULT_CACHE_SIZE = 1000000; - private static readonly TimeSpan DEFAULT_INITIAL_CACHE_TTL = TimeSpan.FromSeconds(30); - private static readonly TimeSpan DEFAULT_MAXIMUM_CACHE_TTL = TimeSpan.FromSeconds(240); - private const double DEFAULT_TTL_EXTENSION_FACTOR = 2.0; - private const DirectoryCachingStrategyType DEFAULT_DIRECTORY_CACHING_STRATEGY = DirectoryCachingStrategyType.Adaptive; - internal static readonly TimeSpan DEFAULT_COLLECTION_QUANTUM = TimeSpan.FromMinutes(1); - internal static readonly TimeSpan DEFAULT_COLLECTION_AGE_LIMIT = TimeSpan.FromHours(2); public static bool ENFORCE_MINIMUM_REQUIREMENT_FOR_AGE_LIMIT = true; - private static readonly TimeSpan DEFAULT_UNREGISTER_RACE_DELAY = TimeSpan.FromMinutes(1); - private static readonly TimeSpan DEFAULT_CLIENT_REGISTRATION_REFRESH = TimeSpan.FromMinutes(5); public const bool DEFAULT_PERFORM_DEADLOCK_DETECTION = false; public const bool DEFAULT_ALLOW_CALL_CHAIN_REENTRANCY = false; - public static readonly string DEFAULT_PLACEMENT_STRATEGY = typeof(RandomPlacement).Name; public static readonly string DEFAULT_MULTICLUSTER_REGISTRATION_STRATEGY = typeof(GlobalSingleInstanceRegistration).Name; - private static readonly TimeSpan DEFAULT_DEPLOYMENT_LOAD_PUBLISHER_REFRESH_TIME = TimeSpan.FromSeconds(1); - private const int DEFAULT_ACTIVATION_COUNT_BASED_PLACEMENT_CHOOSE_OUT_OF = 2; - private const bool DEFAULT_USE_VIRTUAL_RING_BUCKETS = true; - private const int DEFAULT_NUM_VIRTUAL_RING_BUCKETS = 30; - private static readonly TimeSpan DEFAULT_MOCK_REMINDER_TABLE_TIMEOUT = TimeSpan.FromMilliseconds(50); private string dataConnectionStringForReminders; private string adoInvariantForReminders; - internal GlobalConfiguration() + public GlobalConfiguration() : base(true) { - Application = new ApplicationConfiguration(); - SeedNodes = new List(); - livenessServiceType = LivenessProviderType.NotSpecified; - LivenessEnabled = true; - ProbeTimeout = DEFAULT_LIVENESS_PROBE_TIMEOUT; - TableRefreshTimeout = DEFAULT_LIVENESS_TABLE_REFRESH_TIMEOUT; - DeathVoteExpirationTimeout = DEFAULT_LIVENESS_DEATH_VOTE_EXPIRATION_TIMEOUT; - IAmAliveTablePublishTimeout = DEFAULT_LIVENESS_I_AM_ALIVE_TABLE_PUBLISH_TIMEOUT; - NumMissedProbesLimit = DEFAULT_LIVENESS_NUM_MISSED_PROBES_LIMIT; - NumProbedSilos = DEFAULT_LIVENESS_NUM_PROBED_SILOS; - NumVotesForDeathDeclaration = DEFAULT_LIVENESS_NUM_VOTES_FOR_DEATH_DECLARATION; - NumMissedTableIAmAliveLimit = DEFAULT_LIVENESS_NUM_TABLE_I_AM_ALIVE_LIMIT; - UseLivenessGossip = DEFAULT_LIVENESS_USE_LIVENESS_GOSSIP; - ValidateInitialConnectivity = DEFAULT_VALIDATE_INITIAL_CONNECTIVITY; - MaxJoinAttemptTime = DEFAULT_LIVENESS_MAX_JOIN_ATTEMPT_TIME; - TypeMapRefreshInterval = DEFAULT_REFRESH_CLUSTER_INTERFACEMAP_TIME; - MaxMultiClusterGateways = DEFAULT_MAX_MULTICLUSTER_GATEWAYS; - BackgroundGossipInterval = DEFAULT_BACKGROUND_GOSSIP_INTERVAL; - UseGlobalSingleInstanceByDefault = DEFAULT_USE_GLOBAL_SINGLE_INSTANCE; - GlobalSingleInstanceRetryInterval = DEFAULT_GLOBAL_SINGLE_INSTANCE_RETRY_INTERVAL; - GlobalSingleInstanceNumberRetries = DEFAULT_GLOBAL_SINGLE_INSTANCE_NUMBER_RETRIES; - ExpectedClusterSizeConfigValue = new ConfigValue(DEFAULT_LIVENESS_EXPECTED_CLUSTER_SIZE, true); - ServiceId = Guid.Empty; + this.Application = new ApplicationConfiguration(); + this.SeedNodes = new List(); + this.livenessServiceType = LivenessProviderType.NotSpecified; + this.LivenessEnabled = MembershipOptions.DEFAULT_LIVENESS_ENABLED; + this.ProbeTimeout = MembershipOptions.DEFAULT_LIVENESS_PROBE_TIMEOUT; + this.TableRefreshTimeout = MembershipOptions.DEFAULT_LIVENESS_TABLE_REFRESH_TIMEOUT; + this.DeathVoteExpirationTimeout = MembershipOptions.DEFAULT_LIVENESS_DEATH_VOTE_EXPIRATION_TIMEOUT; + this.IAmAliveTablePublishTimeout = MembershipOptions.DEFAULT_LIVENESS_I_AM_ALIVE_TABLE_PUBLISH_TIMEOUT; + this.NumMissedProbesLimit = MembershipOptions.DEFAULT_LIVENESS_NUM_MISSED_PROBES_LIMIT; + this.NumProbedSilos = MembershipOptions.DEFAULT_LIVENESS_NUM_PROBED_SILOS; + this.NumVotesForDeathDeclaration = MembershipOptions.DEFAULT_LIVENESS_NUM_VOTES_FOR_DEATH_DECLARATION; + this.NumMissedTableIAmAliveLimit = MembershipOptions.DEFAULT_LIVENESS_NUM_TABLE_I_AM_ALIVE_LIMIT; + this.UseLivenessGossip = MembershipOptions.DEFAULT_LIVENESS_USE_LIVENESS_GOSSIP; + this.ValidateInitialConnectivity = MembershipOptions.DEFAULT_VALIDATE_INITIAL_CONNECTIVITY; + this.MaxJoinAttemptTime = MembershipOptions.DEFAULT_LIVENESS_MAX_JOIN_ATTEMPT_TIME; + this.TypeMapRefreshInterval = TypeManagementOptions.DEFAULT_REFRESH_CLUSTER_INTERFACEMAP_TIME; + this.MaxMultiClusterGateways = DEFAULT_MAX_MULTICLUSTER_GATEWAYS; + this.BackgroundGossipInterval = DEFAULT_BACKGROUND_GOSSIP_INTERVAL; + this.UseGlobalSingleInstanceByDefault = DEFAULT_USE_GLOBAL_SINGLE_INSTANCE; + this.GlobalSingleInstanceRetryInterval = MultiClusterOptions.DEFAULT_GLOBAL_SINGLE_INSTANCE_RETRY_INTERVAL; + this.GlobalSingleInstanceNumberRetries = DEFAULT_GLOBAL_SINGLE_INSTANCE_NUMBER_RETRIES; + this.ExpectedClusterSizeConfigValue = new ConfigValue(DEFAULT_LIVENESS_EXPECTED_CLUSTER_SIZE, true); + this.ServiceId = Guid.Empty; this.ClusterId = ""; - DataConnectionString = ""; + this.DataConnectionString = ""; // Assume the ado invariant is for sql server storage if not explicitly specified - AdoInvariant = Constants.INVARIANT_NAME_SQL_SERVER; - - MaxRequestProcessingTime = DEFAULT_COLLECTION_AGE_LIMIT; - CollectionQuantum = DEFAULT_COLLECTION_QUANTUM; - - CacheSize = DEFAULT_CACHE_SIZE; - InitialCacheTTL = DEFAULT_INITIAL_CACHE_TTL; - MaximumCacheTTL = DEFAULT_MAXIMUM_CACHE_TTL; - CacheTTLExtensionFactor = DEFAULT_TTL_EXTENSION_FACTOR; - DirectoryCachingStrategy = DEFAULT_DIRECTORY_CACHING_STRATEGY; - DirectoryLazyDeregistrationDelay = DEFAULT_UNREGISTER_RACE_DELAY; - ClientRegistrationRefresh = DEFAULT_CLIENT_REGISTRATION_REFRESH; - - PerformDeadlockDetection = DEFAULT_PERFORM_DEADLOCK_DETECTION; - AllowCallChainReentrancy = DEFAULT_ALLOW_CALL_CHAIN_REENTRANCY; - reminderServiceType = ReminderServiceProviderType.NotSpecified; - DefaultPlacementStrategy = DEFAULT_PLACEMENT_STRATEGY; - DeploymentLoadPublisherRefreshTime = DEFAULT_DEPLOYMENT_LOAD_PUBLISHER_REFRESH_TIME; - ActivationCountBasedPlacementChooseOutOf = DEFAULT_ACTIVATION_COUNT_BASED_PLACEMENT_CHOOSE_OUT_OF; - UseVirtualBucketsConsistentRing = DEFAULT_USE_VIRTUAL_RING_BUCKETS; - NumVirtualBucketsConsistentRing = DEFAULT_NUM_VIRTUAL_RING_BUCKETS; - UseMockReminderTable = false; - MockReminderTableTimeout = DEFAULT_MOCK_REMINDER_TABLE_TIMEOUT; - AssumeHomogenousSilosForTesting = false; - - ProviderConfigurations = new Dictionary(); - GrainServiceConfigurations = new GrainServiceConfigurations(); - DefaultCompatibilityStrategy = BackwardCompatible.Singleton; - DefaultVersionSelectorStrategy = AllCompatibleVersions.Singleton; - - FastKillOnCancelKeyPress = true; + this.AdoInvariant = Constants.INVARIANT_NAME_SQL_SERVER; + + this.MaxRequestProcessingTime = SiloMessagingOptions.DEFAULT_MAX_REQUEST_PROCESSING_TIME; + this.CollectionQuantum = GrainCollectionOptions.DEFAULT_COLLECTION_QUANTUM; + + this.CacheSize = GrainDirectoryOptions.DEFAULT_CACHE_SIZE; + this.InitialCacheTTL = GrainDirectoryOptions.DEFAULT_INITIAL_CACHE_TTL; + this.MaximumCacheTTL = GrainDirectoryOptions.DEFAULT_MAXIMUM_CACHE_TTL; + this.CacheTTLExtensionFactor = GrainDirectoryOptions.DEFAULT_TTL_EXTENSION_FACTOR; + this.DirectoryCachingStrategy = Remap(GrainDirectoryOptions.DEFAULT_CACHING_STRATEGY); + this.DirectoryLazyDeregistrationDelay = GrainDirectoryOptions.DEFAULT_UNREGISTER_RACE_DELAY; + this.ClientRegistrationRefresh = SiloMessagingOptions.DEFAULT_CLIENT_REGISTRATION_REFRESH; + + this.PerformDeadlockDetection = DEFAULT_PERFORM_DEADLOCK_DETECTION; + this.AllowCallChainReentrancy = DEFAULT_ALLOW_CALL_CHAIN_REENTRANCY; + this.reminderServiceType = ReminderServiceProviderType.NotSpecified; + this.DefaultPlacementStrategy = GrainPlacementOptions.DEFAULT_PLACEMENT_STRATEGY; + this.DeploymentLoadPublisherRefreshTime = SiloStatisticsOptions.DEFAULT_DEPLOYMENT_LOAD_PUBLISHER_REFRESH_TIME; + this.ActivationCountBasedPlacementChooseOutOf = GrainPlacementOptions.DEFAULT_ACTIVATION_COUNT_PLACEMENT_CHOOSE_OUT_OF; + this.UseVirtualBucketsConsistentRing = ConsistentRingOptions.DEFAULT_USE_VIRTUAL_RING_BUCKETS; + this.NumVirtualBucketsConsistentRing = ConsistentRingOptions.DEFAULT_NUM_VIRTUAL_RING_BUCKETS; + this.UseMockReminderTable = false; + this.MockReminderTableTimeout = ReminderOptions.DEFAULT_MOCK_REMINDER_TABLE_TIMEOUT; + this.AssumeHomogenousSilosForTesting = false; + + this.ProviderConfigurations = new Dictionary(); + this.GrainServiceConfigurations = new GrainServiceConfigurations(); + this.DefaultCompatibilityStrategy = BackwardCompatible.Singleton; + this.DefaultVersionSelectorStrategy = AllCompatibleVersions.Singleton; + + this.FastKillOnCancelKeyPress = true; } public override string ToString() { var sb = new StringBuilder(); sb.AppendFormat(" System Ids:").AppendLine(); - sb.AppendFormat(" ServiceId: {0}", ServiceId).AppendLine(); + sb.AppendFormat(" ServiceId: {0}", this.ServiceId).AppendLine(); sb.AppendFormat(" ClusterId: {0}", this.ClusterId).AppendLine(); - sb.Append(" Subnet: ").Append(Subnet == null ? "" : Subnet.ToStrings(x => x.ToString(CultureInfo.InvariantCulture), ".")).AppendLine(); + sb.Append(" Subnet: ").Append(this.Subnet == null ? "" : this.Subnet.ToStrings(x => x.ToString(CultureInfo.InvariantCulture), ".")).AppendLine(); sb.Append(" Seed nodes: "); bool first = true; - foreach (IPEndPoint node in SeedNodes) + foreach (IPEndPoint node in this.SeedNodes) { if (!first) { @@ -619,32 +656,32 @@ public override string ToString() sb.AppendLine(); sb.AppendFormat(base.ToString()); sb.AppendFormat(" Liveness:").AppendLine(); - sb.AppendFormat(" LivenessEnabled: {0}", LivenessEnabled).AppendLine(); - sb.AppendFormat(" LivenessType: {0}", LivenessType).AppendLine(); - sb.AppendFormat(" ProbeTimeout: {0}", ProbeTimeout).AppendLine(); - sb.AppendFormat(" TableRefreshTimeout: {0}", TableRefreshTimeout).AppendLine(); - sb.AppendFormat(" DeathVoteExpirationTimeout: {0}", DeathVoteExpirationTimeout).AppendLine(); - sb.AppendFormat(" NumMissedProbesLimit: {0}", NumMissedProbesLimit).AppendLine(); - sb.AppendFormat(" NumProbedSilos: {0}", NumProbedSilos).AppendLine(); - sb.AppendFormat(" NumVotesForDeathDeclaration: {0}", NumVotesForDeathDeclaration).AppendLine(); - sb.AppendFormat(" UseLivenessGossip: {0}", UseLivenessGossip).AppendLine(); - sb.AppendFormat(" ValidateInitialConnectivity: {0}", ValidateInitialConnectivity).AppendLine(); - sb.AppendFormat(" IAmAliveTablePublishTimeout: {0}", IAmAliveTablePublishTimeout).AppendLine(); - sb.AppendFormat(" NumMissedTableIAmAliveLimit: {0}", NumMissedTableIAmAliveLimit).AppendLine(); - sb.AppendFormat(" MaxJoinAttemptTime: {0}", MaxJoinAttemptTime).AppendLine(); - sb.AppendFormat(" ExpectedClusterSize: {0}", ExpectedClusterSize).AppendLine(); - - if (HasMultiClusterNetwork) + sb.AppendFormat(" LivenessEnabled: {0}", this.LivenessEnabled).AppendLine(); + sb.AppendFormat(" LivenessType: {0}", this.LivenessType).AppendLine(); + sb.AppendFormat(" ProbeTimeout: {0}", this.ProbeTimeout).AppendLine(); + sb.AppendFormat(" TableRefreshTimeout: {0}", this.TableRefreshTimeout).AppendLine(); + sb.AppendFormat(" DeathVoteExpirationTimeout: {0}", this.DeathVoteExpirationTimeout).AppendLine(); + sb.AppendFormat(" NumMissedProbesLimit: {0}", this.NumMissedProbesLimit).AppendLine(); + sb.AppendFormat(" NumProbedSilos: {0}", this.NumProbedSilos).AppendLine(); + sb.AppendFormat(" NumVotesForDeathDeclaration: {0}", this.NumVotesForDeathDeclaration).AppendLine(); + sb.AppendFormat(" UseLivenessGossip: {0}", this.UseLivenessGossip).AppendLine(); + sb.AppendFormat(" ValidateInitialConnectivity: {0}", this.ValidateInitialConnectivity).AppendLine(); + sb.AppendFormat(" IAmAliveTablePublishTimeout: {0}", this.IAmAliveTablePublishTimeout).AppendLine(); + sb.AppendFormat(" NumMissedTableIAmAliveLimit: {0}", this.NumMissedTableIAmAliveLimit).AppendLine(); + sb.AppendFormat(" MaxJoinAttemptTime: {0}", this.MaxJoinAttemptTime).AppendLine(); + sb.AppendFormat(" ExpectedClusterSize: {0}", this.ExpectedClusterSize).AppendLine(); + + if (this.HasMultiClusterNetwork) { sb.AppendLine(" MultiClusterNetwork:"); - sb.AppendFormat(" ClusterId: {0}", ClusterId ?? "").AppendLine(); - sb.AppendFormat(" DefaultMultiCluster: {0}", DefaultMultiCluster != null ? string.Join(",", DefaultMultiCluster) : "null").AppendLine(); - sb.AppendFormat(" MaxMultiClusterGateways: {0}", MaxMultiClusterGateways).AppendLine(); - sb.AppendFormat(" BackgroundGossipInterval: {0}", BackgroundGossipInterval).AppendLine(); - sb.AppendFormat(" UseGlobalSingleInstanceByDefault: {0}", UseGlobalSingleInstanceByDefault).AppendLine(); - sb.AppendFormat(" GlobalSingleInstanceRetryInterval: {0}", GlobalSingleInstanceRetryInterval).AppendLine(); - sb.AppendFormat(" GlobalSingleInstanceNumberRetries: {0}", GlobalSingleInstanceNumberRetries).AppendLine(); - sb.AppendFormat(" GossipChannels: {0}", string.Join(",", GossipChannels.Select(conf => conf.ChannelType.ToString() + ":" + conf.ConnectionString))).AppendLine(); + sb.AppendFormat(" ClusterId: {0}", this.ClusterId ?? "").AppendLine(); + sb.AppendFormat(" DefaultMultiCluster: {0}", this.DefaultMultiCluster != null ? string.Join(",", this.DefaultMultiCluster) : "null").AppendLine(); + sb.AppendFormat(" MaxMultiClusterGateways: {0}", this.MaxMultiClusterGateways).AppendLine(); + sb.AppendFormat(" BackgroundGossipInterval: {0}", this.BackgroundGossipInterval).AppendLine(); + sb.AppendFormat(" UseGlobalSingleInstanceByDefault: {0}", this.UseGlobalSingleInstanceByDefault).AppendLine(); + sb.AppendFormat(" GlobalSingleInstanceRetryInterval: {0}", this.GlobalSingleInstanceRetryInterval).AppendLine(); + sb.AppendFormat(" GlobalSingleInstanceNumberRetries: {0}", this.GlobalSingleInstanceNumberRetries).AppendLine(); + sb.AppendFormat(" GossipChannels: {0}", string.Join(",", this.GossipChannels.Select(conf => conf.ChannelType.ToString() + ":" + conf.ConnectionString))).AppendLine(); } else { @@ -653,42 +690,42 @@ public override string ToString() sb.AppendFormat(" SystemStore:").AppendLine(); // Don't print connection credentials in log files, so pass it through redactment filter - string connectionStringForLog = ConfigUtilities.RedactConnectionStringInfo(DataConnectionString); + string connectionStringForLog = ConfigUtilities.RedactConnectionStringInfo(this.DataConnectionString); sb.AppendFormat(" SystemStore ConnectionString: {0}", connectionStringForLog).AppendLine(); - string remindersConnectionStringForLog = ConfigUtilities.RedactConnectionStringInfo(DataConnectionStringForReminders); + string remindersConnectionStringForLog = ConfigUtilities.RedactConnectionStringInfo(this.DataConnectionStringForReminders); sb.AppendFormat(" Reminders ConnectionString: {0}", remindersConnectionStringForLog).AppendLine(); - sb.Append(Application.ToString()).AppendLine(); + sb.Append(this.Application.ToString()).AppendLine(); sb.Append(" PlacementStrategy: ").AppendLine(); - sb.Append(" ").Append(" Default Placement Strategy: ").Append(DefaultPlacementStrategy).AppendLine(); - sb.Append(" ").Append(" Deployment Load Publisher Refresh Time: ").Append(DeploymentLoadPublisherRefreshTime).AppendLine(); - sb.Append(" ").Append(" Activation CountBased Placement Choose Out Of: ").Append(ActivationCountBasedPlacementChooseOutOf).AppendLine(); + sb.Append(" ").Append(" Default Placement Strategy: ").Append(this.DefaultPlacementStrategy).AppendLine(); + sb.Append(" ").Append(" Deployment Load Publisher Refresh Time: ").Append(this.DeploymentLoadPublisherRefreshTime).AppendLine(); + sb.Append(" ").Append(" Activation CountBased Placement Choose Out Of: ").Append(this.ActivationCountBasedPlacementChooseOutOf).AppendLine(); sb.AppendFormat(" Grain directory cache:").AppendLine(); - sb.AppendFormat(" Maximum size: {0} grains", CacheSize).AppendLine(); - sb.AppendFormat(" Initial TTL: {0}", InitialCacheTTL).AppendLine(); - sb.AppendFormat(" Maximum TTL: {0}", MaximumCacheTTL).AppendLine(); - sb.AppendFormat(" TTL extension factor: {0:F2}", CacheTTLExtensionFactor).AppendLine(); - sb.AppendFormat(" Directory Caching Strategy: {0}", DirectoryCachingStrategy).AppendLine(); + sb.AppendFormat(" Maximum size: {0} grains", this.CacheSize).AppendLine(); + sb.AppendFormat(" Initial TTL: {0}", this.InitialCacheTTL).AppendLine(); + sb.AppendFormat(" Maximum TTL: {0}", this.MaximumCacheTTL).AppendLine(); + sb.AppendFormat(" TTL extension factor: {0:F2}", this.CacheTTLExtensionFactor).AppendLine(); + sb.AppendFormat(" Directory Caching Strategy: {0}", this.DirectoryCachingStrategy).AppendLine(); sb.AppendFormat(" Grain directory:").AppendLine(); - sb.AppendFormat(" Lazy deregistration delay: {0}", DirectoryLazyDeregistrationDelay).AppendLine(); - sb.AppendFormat(" Client registration refresh: {0}", ClientRegistrationRefresh).AppendLine(); + sb.AppendFormat(" Lazy deregistration delay: {0}", this.DirectoryLazyDeregistrationDelay).AppendLine(); + sb.AppendFormat(" Client registration refresh: {0}", this.ClientRegistrationRefresh).AppendLine(); sb.AppendFormat(" Reminder Service:").AppendLine(); - sb.AppendFormat(" ReminderServiceType: {0}", ReminderServiceType).AppendLine(); - if (ReminderServiceType == ReminderServiceProviderType.MockTable) + sb.AppendFormat(" ReminderServiceType: {0}", this.ReminderServiceType).AppendLine(); + if (this.ReminderServiceType == ReminderServiceProviderType.MockTable) { - sb.AppendFormat(" MockReminderTableTimeout: {0}ms", MockReminderTableTimeout.TotalMilliseconds).AppendLine(); + sb.AppendFormat(" MockReminderTableTimeout: {0}ms", this.MockReminderTableTimeout.TotalMilliseconds).AppendLine(); } sb.AppendFormat(" Consistent Ring:").AppendLine(); - sb.AppendFormat(" Use Virtual Buckets Consistent Ring: {0}", UseVirtualBucketsConsistentRing).AppendLine(); - sb.AppendFormat(" Num Virtual Buckets Consistent Ring: {0}", NumVirtualBucketsConsistentRing).AppendLine(); + sb.AppendFormat(" Use Virtual Buckets Consistent Ring: {0}", this.UseVirtualBucketsConsistentRing).AppendLine(); + sb.AppendFormat(" Num Virtual Buckets Consistent Ring: {0}", this.NumVirtualBucketsConsistentRing).AppendLine(); sb.AppendFormat(" Providers:").AppendLine(); - sb.Append(ProviderConfigurationUtility.PrintProviderConfigurations(ProviderConfigurations)); + sb.Append(ProviderConfigurationUtility.PrintProviderConfigurations(this.ProviderConfigurations)); return sb.ToString(); } internal override void Load(XmlElement root) { - SeedNodes = new List(); + this.SeedNodes = new List(); XmlElement child; foreach (XmlNode c in root.ChildNodes) @@ -696,7 +733,7 @@ internal override void Load(XmlElement root) child = c as XmlElement; if (child != null && child.LocalName == "Networking") { - Subnet = child.HasAttribute("Subnet") + this.Subnet = child.HasAttribute("Subnet") ? ConfigUtilities.ParseSubnet(child.GetAttribute("Subnet"), "Invalid Subnet") : null; } @@ -711,69 +748,69 @@ internal override void Load(XmlElement root) case "Liveness": if (child.HasAttribute("LivenessEnabled")) { - LivenessEnabled = ConfigUtilities.ParseBool(child.GetAttribute("LivenessEnabled"), + this.LivenessEnabled = ConfigUtilities.ParseBool(child.GetAttribute("LivenessEnabled"), "Invalid boolean value for the LivenessEnabled attribute on the Liveness element"); } if (child.HasAttribute("ProbeTimeout")) { - ProbeTimeout = ConfigUtilities.ParseTimeSpan(child.GetAttribute("ProbeTimeout"), + this.ProbeTimeout = ConfigUtilities.ParseTimeSpan(child.GetAttribute("ProbeTimeout"), "Invalid time value for the ProbeTimeout attribute on the Liveness element"); } if (child.HasAttribute("TableRefreshTimeout")) { - TableRefreshTimeout = ConfigUtilities.ParseTimeSpan(child.GetAttribute("TableRefreshTimeout"), + this.TableRefreshTimeout = ConfigUtilities.ParseTimeSpan(child.GetAttribute("TableRefreshTimeout"), "Invalid time value for the TableRefreshTimeout attribute on the Liveness element"); } if (child.HasAttribute("DeathVoteExpirationTimeout")) { - DeathVoteExpirationTimeout = ConfigUtilities.ParseTimeSpan(child.GetAttribute("DeathVoteExpirationTimeout"), + this.DeathVoteExpirationTimeout = ConfigUtilities.ParseTimeSpan(child.GetAttribute("DeathVoteExpirationTimeout"), "Invalid time value for the DeathVoteExpirationTimeout attribute on the Liveness element"); } if (child.HasAttribute("NumMissedProbesLimit")) { - NumMissedProbesLimit = ConfigUtilities.ParseInt(child.GetAttribute("NumMissedProbesLimit"), + this.NumMissedProbesLimit = ConfigUtilities.ParseInt(child.GetAttribute("NumMissedProbesLimit"), "Invalid integer value for the NumMissedIAmAlive attribute on the Liveness element"); } if (child.HasAttribute("NumProbedSilos")) { - NumProbedSilos = ConfigUtilities.ParseInt(child.GetAttribute("NumProbedSilos"), + this.NumProbedSilos = ConfigUtilities.ParseInt(child.GetAttribute("NumProbedSilos"), "Invalid integer value for the NumProbedSilos attribute on the Liveness element"); } if (child.HasAttribute("NumVotesForDeathDeclaration")) { - NumVotesForDeathDeclaration = ConfigUtilities.ParseInt(child.GetAttribute("NumVotesForDeathDeclaration"), + this.NumVotesForDeathDeclaration = ConfigUtilities.ParseInt(child.GetAttribute("NumVotesForDeathDeclaration"), "Invalid integer value for the NumVotesForDeathDeclaration attribute on the Liveness element"); } if (child.HasAttribute("UseLivenessGossip")) { - UseLivenessGossip = ConfigUtilities.ParseBool(child.GetAttribute("UseLivenessGossip"), + this.UseLivenessGossip = ConfigUtilities.ParseBool(child.GetAttribute("UseLivenessGossip"), "Invalid boolean value for the UseLivenessGossip attribute on the Liveness element"); } if (child.HasAttribute("ValidateInitialConnectivity")) { - ValidateInitialConnectivity = ConfigUtilities.ParseBool(child.GetAttribute("ValidateInitialConnectivity"), + this.ValidateInitialConnectivity = ConfigUtilities.ParseBool(child.GetAttribute("ValidateInitialConnectivity"), "Invalid boolean value for the ValidateInitialConnectivity attribute on the Liveness element"); } if (child.HasAttribute("IAmAliveTablePublishTimeout")) { - IAmAliveTablePublishTimeout = ConfigUtilities.ParseTimeSpan(child.GetAttribute("IAmAliveTablePublishTimeout"), + this.IAmAliveTablePublishTimeout = ConfigUtilities.ParseTimeSpan(child.GetAttribute("IAmAliveTablePublishTimeout"), "Invalid time value for the IAmAliveTablePublishTimeout attribute on the Liveness element"); } if (child.HasAttribute("NumMissedTableIAmAliveLimit")) { - NumMissedTableIAmAliveLimit = ConfigUtilities.ParseInt(child.GetAttribute("NumMissedTableIAmAliveLimit"), + this.NumMissedTableIAmAliveLimit = ConfigUtilities.ParseInt(child.GetAttribute("NumMissedTableIAmAliveLimit"), "Invalid integer value for the NumMissedTableIAmAliveLimit attribute on the Liveness element"); } if (child.HasAttribute("MaxJoinAttemptTime")) { - MaxJoinAttemptTime = ConfigUtilities.ParseTimeSpan(child.GetAttribute("MaxJoinAttemptTime"), + this.MaxJoinAttemptTime = ConfigUtilities.ParseTimeSpan(child.GetAttribute("MaxJoinAttemptTime"), "Invalid time value for the MaxJoinAttemptTime attribute on the Liveness element"); } if (child.HasAttribute("ExpectedClusterSize")) { int expectedClusterSize = ConfigUtilities.ParseInt(child.GetAttribute("ExpectedClusterSize"), "Invalid integer value for the ExpectedClusterSize attribute on the Liveness element"); - ExpectedClusterSizeConfigValue = new ConfigValue(expectedClusterSize, false); + this.ExpectedClusterSizeConfigValue = new ConfigValue(expectedClusterSize, false); } break; @@ -785,9 +822,9 @@ internal override void Load(XmlElement root) var sst = child.GetAttribute("SystemStoreType"); if (!"None".Equals(sst, StringComparison.OrdinalIgnoreCase)) { - LivenessType = (LivenessProviderType)Enum.Parse(typeof(LivenessProviderType), sst); + this.LivenessType = (LivenessProviderType)Enum.Parse(typeof(LivenessProviderType), sst); ReminderServiceProviderType reminderServiceProviderType; - if (LivenessType == LivenessProviderType.MembershipTableGrain) + if (this.LivenessType == LivenessProviderType.MembershipTableGrain) { // Special case for MembershipTableGrain -> ReminderTableGrain since we use the same setting // for LivenessType and ReminderServiceType even if the enum are not 100% compatible @@ -805,30 +842,30 @@ internal override void Load(XmlElement root) } if (child.HasAttribute("MembershipTableAssembly")) { - MembershipTableAssembly = child.GetAttribute("MembershipTableAssembly"); - if (LivenessType != LivenessProviderType.Custom) + this.MembershipTableAssembly = child.GetAttribute("MembershipTableAssembly"); + if (this.LivenessType != LivenessProviderType.Custom) throw new FormatException("SystemStoreType should be \"Custom\" when MembershipTableAssembly is specified"); - if (MembershipTableAssembly.EndsWith(".dll")) + if (this.MembershipTableAssembly.EndsWith(".dll")) throw new FormatException("Use fully qualified assembly name for \"MembershipTableAssembly\""); } if (child.HasAttribute("ReminderTableAssembly")) { - ReminderTableAssembly = child.GetAttribute("ReminderTableAssembly"); - if (ReminderServiceType != ReminderServiceProviderType.Custom) + this.ReminderTableAssembly = child.GetAttribute("ReminderTableAssembly"); + if (this.ReminderServiceType != ReminderServiceProviderType.Custom) throw new FormatException("ReminderServiceType should be \"Custom\" when ReminderTableAssembly is specified"); - if (ReminderTableAssembly.EndsWith(".dll")) + if (this.ReminderTableAssembly.EndsWith(".dll")) throw new FormatException("Use fully qualified assembly name for \"ReminderTableAssembly\""); } - if (LivenessType == LivenessProviderType.Custom && string.IsNullOrEmpty(MembershipTableAssembly)) + if (this.LivenessType == LivenessProviderType.Custom && string.IsNullOrEmpty(this.MembershipTableAssembly)) throw new FormatException("MembershipTableAssembly should be set when SystemStoreType is \"Custom\""); - if (ReminderServiceType == ReminderServiceProviderType.Custom && String.IsNullOrEmpty(ReminderTableAssembly)) + if (this.ReminderServiceType == ReminderServiceProviderType.Custom && string.IsNullOrEmpty(this.ReminderTableAssembly)) { SetReminderServiceType(ReminderServiceProviderType.Disabled); } if (child.HasAttribute("ServiceId")) { - ServiceId = ConfigUtilities.ParseGuid(child.GetAttribute("ServiceId"), + this.ServiceId = ConfigUtilities.ParseGuid(child.GetAttribute("ServiceId"), "Invalid Guid value for the ServiceId attribute on the Azure element"); } if (child.HasAttribute("DeploymentId")) @@ -837,16 +874,16 @@ internal override void Load(XmlElement root) } if (child.HasAttribute(Constants.DATA_CONNECTION_STRING_NAME)) { - DataConnectionString = child.GetAttribute(Constants.DATA_CONNECTION_STRING_NAME); - if (String.IsNullOrWhiteSpace(DataConnectionString)) + this.DataConnectionString = child.GetAttribute(Constants.DATA_CONNECTION_STRING_NAME); + if (string.IsNullOrWhiteSpace(this.DataConnectionString)) { throw new FormatException("SystemStore.DataConnectionString cannot be blank"); } } if (child.HasAttribute(Constants.DATA_CONNECTION_FOR_REMINDERS_STRING_NAME)) { - DataConnectionStringForReminders = child.GetAttribute(Constants.DATA_CONNECTION_FOR_REMINDERS_STRING_NAME); - if (String.IsNullOrWhiteSpace(DataConnectionStringForReminders)) + this.DataConnectionStringForReminders = child.GetAttribute(Constants.DATA_CONNECTION_FOR_REMINDERS_STRING_NAME); + if (string.IsNullOrWhiteSpace(this.DataConnectionStringForReminders)) { throw new FormatException("SystemStore.DataConnectionStringForReminders cannot be blank"); } @@ -854,83 +891,83 @@ internal override void Load(XmlElement root) if (child.HasAttribute(Constants.ADO_INVARIANT_NAME)) { var adoInvariant = child.GetAttribute(Constants.ADO_INVARIANT_NAME); - if (String.IsNullOrWhiteSpace(adoInvariant)) + if (string.IsNullOrWhiteSpace(adoInvariant)) { throw new FormatException("SystemStore.AdoInvariant cannot be blank"); } - AdoInvariant = adoInvariant; + this.AdoInvariant = adoInvariant; } if (child.HasAttribute(Constants.ADO_INVARIANT_FOR_REMINDERS_NAME)) { var adoInvariantForReminders = child.GetAttribute(Constants.ADO_INVARIANT_FOR_REMINDERS_NAME); - if (String.IsNullOrWhiteSpace(adoInvariantForReminders)) + if (string.IsNullOrWhiteSpace(adoInvariantForReminders)) { throw new FormatException("SystemStore.adoInvariantForReminders cannot be blank"); } - AdoInvariantForReminders = adoInvariantForReminders; + this.AdoInvariantForReminders = adoInvariantForReminders; } if (child.HasAttribute("MaxStorageBusyRetries")) { - MaxStorageBusyRetries = ConfigUtilities.ParseInt(child.GetAttribute("MaxStorageBusyRetries"), + this.MaxStorageBusyRetries = ConfigUtilities.ParseInt(child.GetAttribute("MaxStorageBusyRetries"), "Invalid integer value for the MaxStorageBusyRetries attribute on the SystemStore element"); } if (child.HasAttribute("UseMockReminderTable")) { - MockReminderTableTimeout = ConfigUtilities.ParseTimeSpan(child.GetAttribute("UseMockReminderTable"), "Invalid timeout value"); - UseMockReminderTable = true; + this.MockReminderTableTimeout = ConfigUtilities.ParseTimeSpan(child.GetAttribute("UseMockReminderTable"), "Invalid timeout value"); + this.UseMockReminderTable = true; } break; case "MultiClusterNetwork": - HasMultiClusterNetwork = true; - ClusterId = child.GetAttribute("ClusterId"); + this.HasMultiClusterNetwork = true; + this.ClusterId = child.GetAttribute("ClusterId"); // we always trim cluster ids to avoid surprises when parsing comma-separated lists - if (ClusterId != null) - ClusterId = ClusterId.Trim(); + if (this.ClusterId != null) + this.ClusterId = this.ClusterId.Trim(); - if (string.IsNullOrEmpty(ClusterId)) + if (string.IsNullOrEmpty(this.ClusterId)) throw new FormatException("MultiClusterNetwork.ClusterId cannot be blank"); - if (ClusterId.Contains(",")) - throw new FormatException("MultiClusterNetwork.ClusterId cannot contain commas: " + ClusterId); + if (this.ClusterId.Contains(",")) + throw new FormatException("MultiClusterNetwork.ClusterId cannot contain commas: " + this.ClusterId); if (child.HasAttribute("DefaultMultiCluster")) { var toparse = child.GetAttribute("DefaultMultiCluster").Trim(); if (string.IsNullOrEmpty(toparse)) { - DefaultMultiCluster = new List(); // empty cluster + this.DefaultMultiCluster = new List(); // empty cluster } else { - DefaultMultiCluster = toparse.Split(',').Select(id => id.Trim()).ToList(); - foreach (var id in DefaultMultiCluster) + this.DefaultMultiCluster = toparse.Split(',').Select(id => id.Trim()).ToList(); + foreach (var id in this.DefaultMultiCluster) if (string.IsNullOrEmpty(id)) throw new FormatException("MultiClusterNetwork.DefaultMultiCluster cannot contain blank cluster ids: " + toparse); } } if (child.HasAttribute("BackgroundGossipInterval")) { - BackgroundGossipInterval = ConfigUtilities.ParseTimeSpan(child.GetAttribute("BackgroundGossipInterval"), + this.BackgroundGossipInterval = ConfigUtilities.ParseTimeSpan(child.GetAttribute("BackgroundGossipInterval"), "Invalid time value for the BackgroundGossipInterval attribute on the MultiClusterNetwork element"); } if (child.HasAttribute("UseGlobalSingleInstanceByDefault")) { - UseGlobalSingleInstanceByDefault = ConfigUtilities.ParseBool(child.GetAttribute("UseGlobalSingleInstanceByDefault"), + this.UseGlobalSingleInstanceByDefault = ConfigUtilities.ParseBool(child.GetAttribute("UseGlobalSingleInstanceByDefault"), "Invalid boolean for the UseGlobalSingleInstanceByDefault attribute on the MultiClusterNetwork element"); } if (child.HasAttribute("GlobalSingleInstanceRetryInterval")) { - GlobalSingleInstanceRetryInterval = ConfigUtilities.ParseTimeSpan(child.GetAttribute("GlobalSingleInstanceRetryInterval"), + this.GlobalSingleInstanceRetryInterval = ConfigUtilities.ParseTimeSpan(child.GetAttribute("GlobalSingleInstanceRetryInterval"), "Invalid time value for the GlobalSingleInstanceRetryInterval attribute on the MultiClusterNetwork element"); } if (child.HasAttribute("GlobalSingleInstanceNumberRetries")) { - GlobalSingleInstanceNumberRetries = ConfigUtilities.ParseInt(child.GetAttribute("GlobalSingleInstanceNumberRetries"), + this.GlobalSingleInstanceNumberRetries = ConfigUtilities.ParseInt(child.GetAttribute("GlobalSingleInstanceNumberRetries"), "Invalid value for the GlobalSingleInstanceRetryInterval attribute on the MultiClusterNetwork element"); } if (child.HasAttribute("MaxMultiClusterGateways")) { - MaxMultiClusterGateways = ConfigUtilities.ParseInt(child.GetAttribute("MaxMultiClusterGateways"), + this.MaxMultiClusterGateways = ConfigUtilities.ParseInt(child.GetAttribute("MaxMultiClusterGateways"), "Invalid value for the MaxMultiClusterGateways attribute on the MultiClusterNetwork element"); } var channels = new List(); @@ -946,10 +983,10 @@ internal override void Load(XmlElement root) ConnectionString = channelspec.GetAttribute("ConnectionString") }); } - GossipChannels = channels; + this.GossipChannels = channels; break; case "SeedNode": - SeedNodes.Add(ConfigUtilities.ParseIPEndPoint(child, Subnet).GetResult()); + this.SeedNodes.Add(ConfigUtilities.ParseIPEndPoint(child, this.Subnet).GetResult()); break; case "Messaging": @@ -957,43 +994,43 @@ internal override void Load(XmlElement root) break; case "Application": - Application.Load(child); + this.Application.Load(child); break; case "PlacementStrategy": if (child.HasAttribute("DefaultPlacementStrategy")) - DefaultPlacementStrategy = child.GetAttribute("DefaultPlacementStrategy"); + this.DefaultPlacementStrategy = child.GetAttribute("DefaultPlacementStrategy"); if (child.HasAttribute("DeploymentLoadPublisherRefreshTime")) - DeploymentLoadPublisherRefreshTime = ConfigUtilities.ParseTimeSpan(child.GetAttribute("DeploymentLoadPublisherRefreshTime"), + this.DeploymentLoadPublisherRefreshTime = ConfigUtilities.ParseTimeSpan(child.GetAttribute("DeploymentLoadPublisherRefreshTime"), "Invalid time span value for PlacementStrategy.DeploymentLoadPublisherRefreshTime"); if (child.HasAttribute("ActivationCountBasedPlacementChooseOutOf")) - ActivationCountBasedPlacementChooseOutOf = ConfigUtilities.ParseInt(child.GetAttribute("ActivationCountBasedPlacementChooseOutOf"), + this.ActivationCountBasedPlacementChooseOutOf = ConfigUtilities.ParseInt(child.GetAttribute("ActivationCountBasedPlacementChooseOutOf"), "Invalid ActivationCountBasedPlacementChooseOutOf setting"); break; case "Caching": if (child.HasAttribute("CacheSize")) - CacheSize = ConfigUtilities.ParseInt(child.GetAttribute("CacheSize"), + this.CacheSize = ConfigUtilities.ParseInt(child.GetAttribute("CacheSize"), "Invalid integer value for Caching.CacheSize"); if (child.HasAttribute("InitialTTL")) - InitialCacheTTL = ConfigUtilities.ParseTimeSpan(child.GetAttribute("InitialTTL"), + this.InitialCacheTTL = ConfigUtilities.ParseTimeSpan(child.GetAttribute("InitialTTL"), "Invalid time value for Caching.InitialTTL"); if (child.HasAttribute("MaximumTTL")) - MaximumCacheTTL = ConfigUtilities.ParseTimeSpan(child.GetAttribute("MaximumTTL"), + this.MaximumCacheTTL = ConfigUtilities.ParseTimeSpan(child.GetAttribute("MaximumTTL"), "Invalid time value for Caching.MaximumTTL"); if (child.HasAttribute("TTLExtensionFactor")) - CacheTTLExtensionFactor = ConfigUtilities.ParseDouble(child.GetAttribute("TTLExtensionFactor"), + this.CacheTTLExtensionFactor = ConfigUtilities.ParseDouble(child.GetAttribute("TTLExtensionFactor"), "Invalid double value for Caching.TTLExtensionFactor"); - if (CacheTTLExtensionFactor <= 1.0) + if (this.CacheTTLExtensionFactor <= 1.0) { throw new FormatException("Caching.TTLExtensionFactor must be greater than 1.0"); } if (child.HasAttribute("DirectoryCachingStrategy")) - DirectoryCachingStrategy = ConfigUtilities.ParseEnum(child.GetAttribute("DirectoryCachingStrategy"), + this.DirectoryCachingStrategy = ConfigUtilities.ParseEnum(child.GetAttribute("DirectoryCachingStrategy"), "Invalid value for Caching.Strategy"); break; @@ -1001,12 +1038,12 @@ internal override void Load(XmlElement root) case "Directory": if (child.HasAttribute("DirectoryLazyDeregistrationDelay")) { - DirectoryLazyDeregistrationDelay = ConfigUtilities.ParseTimeSpan(child.GetAttribute("DirectoryLazyDeregistrationDelay"), + this.DirectoryLazyDeregistrationDelay = ConfigUtilities.ParseTimeSpan(child.GetAttribute("DirectoryLazyDeregistrationDelay"), "Invalid time span value for Directory.DirectoryLazyDeregistrationDelay"); } if (child.HasAttribute("ClientRegistrationRefresh")) { - ClientRegistrationRefresh = ConfigUtilities.ParseTimeSpan(child.GetAttribute("ClientRegistrationRefresh"), + this.ClientRegistrationRefresh = ConfigUtilities.ParseTimeSpan(child.GetAttribute("ClientRegistrationRefresh"), "Invalid time span value for Directory.ClientRegistrationRefresh"); } break; @@ -1014,21 +1051,21 @@ internal override void Load(XmlElement root) default: if (child.LocalName.Equals("GrainServices", StringComparison.Ordinal)) { - GrainServiceConfigurations = GrainServiceConfigurations.Load(child); + this.GrainServiceConfigurations = GrainServiceConfigurations.Load(child); } if (child.LocalName.EndsWith("Providers", StringComparison.Ordinal)) { var providerCategory = ProviderCategoryConfiguration.Load(child); - if (ProviderConfigurations.ContainsKey(providerCategory.Name)) + if (this.ProviderConfigurations.ContainsKey(providerCategory.Name)) { - var existingCategory = ProviderConfigurations[providerCategory.Name]; + var existingCategory = this.ProviderConfigurations[providerCategory.Name]; existingCategory.Merge(providerCategory); } else { - ProviderConfigurations.Add(providerCategory.Name, providerCategory); + this.ProviderConfigurations.Add(providerCategory.Name, providerCategory); } } break; @@ -1051,7 +1088,7 @@ internal override void Load(XmlElement root) !typeof(Orleans.Streams.IStreamProvider).IsAssignableFrom(providerType)) throw new ArgumentException("Expected non-generic, non-abstract type which implements IStreamProvider interface", "typeof(T)"); - ProviderConfigurationUtility.RegisterProvider(ProviderConfigurations, ProviderCategoryConfiguration.STREAM_PROVIDER_CATEGORY_NAME, providerType.FullName, providerName, properties); + ProviderConfigurationUtility.RegisterProvider(this.ProviderConfigurations, ProviderCategoryConfiguration.STREAM_PROVIDER_CATEGORY_NAME, providerType.FullName, providerName, properties); } /// @@ -1062,7 +1099,7 @@ internal override void Load(XmlElement root) /// Properties that will be passed to the stream provider upon initialization public void RegisterStreamProvider(string providerTypeFullName, string providerName, IDictionary properties = null) { - ProviderConfigurationUtility.RegisterProvider(ProviderConfigurations, ProviderCategoryConfiguration.STREAM_PROVIDER_CATEGORY_NAME, providerTypeFullName, providerName, properties); + ProviderConfigurationUtility.RegisterProvider(this.ProviderConfigurations, ProviderCategoryConfiguration.STREAM_PROVIDER_CATEGORY_NAME, providerTypeFullName, providerName, properties); } /// @@ -1080,7 +1117,7 @@ public void RegisterStreamProvider(string providerTypeFullName, string providerN !typeof(IStorageProvider).IsAssignableFrom(providerType)) throw new ArgumentException("Expected non-generic, non-abstract type which implements IStorageProvider interface", "typeof(T)"); - ProviderConfigurationUtility.RegisterProvider(ProviderConfigurations, ProviderCategoryConfiguration.STORAGE_PROVIDER_CATEGORY_NAME, providerTypeInfo.FullName, providerName, properties); + ProviderConfigurationUtility.RegisterProvider(this.ProviderConfigurations, ProviderCategoryConfiguration.STORAGE_PROVIDER_CATEGORY_NAME, providerTypeInfo.FullName, providerName, properties); } /// @@ -1091,7 +1128,7 @@ public void RegisterStreamProvider(string providerTypeFullName, string providerN /// Properties that will be passed to the storage provider upon initialization public void RegisterStorageProvider(string providerTypeFullName, string providerName, IDictionary properties = null) { - ProviderConfigurationUtility.RegisterProvider(ProviderConfigurations, ProviderCategoryConfiguration.STORAGE_PROVIDER_CATEGORY_NAME, providerTypeFullName, providerName, properties); + ProviderConfigurationUtility.RegisterProvider(this.ProviderConfigurations, ProviderCategoryConfiguration.STORAGE_PROVIDER_CATEGORY_NAME, providerTypeFullName, providerName, properties); } public void RegisterStatisticsProvider(string providerName, IDictionary properties = null) where T : IStatisticsPublisher, ISiloMetricsDataPublisher @@ -1106,12 +1143,12 @@ public void RegisterStorageProvider(string providerTypeFullName, string provider )) throw new ArgumentException("Expected non-generic, non-abstract type which implements IStatisticsPublisher, ISiloMetricsDataPublisher interface", "typeof(T)"); - ProviderConfigurationUtility.RegisterProvider(ProviderConfigurations, ProviderCategoryConfiguration.STATISTICS_PROVIDER_CATEGORY_NAME, providerTypeInfo.FullName, providerName, properties); + ProviderConfigurationUtility.RegisterProvider(this.ProviderConfigurations, ProviderCategoryConfiguration.STATISTICS_PROVIDER_CATEGORY_NAME, providerTypeInfo.FullName, providerName, properties); } public void RegisterStatisticsProvider(string providerTypeFullName, string providerName, IDictionary properties = null) { - ProviderConfigurationUtility.RegisterProvider(ProviderConfigurations, ProviderCategoryConfiguration.STATISTICS_PROVIDER_CATEGORY_NAME, providerTypeFullName, providerName, properties); + ProviderConfigurationUtility.RegisterProvider(this.ProviderConfigurations, ProviderCategoryConfiguration.STATISTICS_PROVIDER_CATEGORY_NAME, providerTypeFullName, providerName, properties); } /// @@ -1122,7 +1159,7 @@ public void RegisterStatisticsProvider(string providerTypeFullName, string provi /// Properties that will be passed to the log-consistency provider upon initialization public void RegisterLogConsistencyProvider(string providerTypeFullName, string providerName, IDictionary properties = null) { - ProviderConfigurationUtility.RegisterProvider(ProviderConfigurations, ProviderCategoryConfiguration.LOG_CONSISTENCY_PROVIDER_CATEGORY_NAME, providerTypeFullName, providerName, properties); + ProviderConfigurationUtility.RegisterProvider(this.ProviderConfigurations, ProviderCategoryConfiguration.LOG_CONSISTENCY_PROVIDER_CATEGORY_NAME, providerTypeFullName, providerName, properties); } @@ -1141,7 +1178,7 @@ public void RegisterLogConsistencyProvider(string providerTypeFullName, string p !typeof(ILogConsistencyProvider).IsAssignableFrom(providerType)) throw new ArgumentException("Expected non-generic, non-abstract type which implements ILogConsistencyProvider interface", "typeof(T)"); - ProviderConfigurationUtility.RegisterProvider(ProviderConfigurations, ProviderCategoryConfiguration.LOG_CONSISTENCY_PROVIDER_CATEGORY_NAME, providerType.FullName, providerName, properties); + ProviderConfigurationUtility.RegisterProvider(this.ProviderConfigurations, ProviderCategoryConfiguration.LOG_CONSISTENCY_PROVIDER_CATEGORY_NAME, providerType.FullName, providerName, properties); } @@ -1154,7 +1191,7 @@ public void RegisterLogConsistencyProvider(string providerTypeFullName, string p /// True if a configuration for this provider already exists, false otherwise. public bool TryGetProviderConfiguration(string providerTypeFullName, string providerName, out IProviderConfiguration config) { - return ProviderConfigurationUtility.TryGetProviderConfiguration(ProviderConfigurations, providerTypeFullName, providerName, out config); + return ProviderConfigurationUtility.TryGetProviderConfiguration(this.ProviderConfigurations, providerTypeFullName, providerName, out config); } /// @@ -1163,12 +1200,12 @@ public bool TryGetProviderConfiguration(string providerTypeFullName, string prov /// An enumeration of all currently configured provider configurations. public IEnumerable GetAllProviderConfigurations() { - return ProviderConfigurationUtility.GetAllProviderConfigurations(ProviderConfigurations); + return ProviderConfigurationUtility.GetAllProviderConfigurations(this.ProviderConfigurations); } public void RegisterGrainService(string serviceName, string serviceType, IDictionary properties = null) { - GrainServiceConfigurationsUtility.RegisterGrainService(GrainServiceConfigurations, serviceName, serviceType, properties); + GrainServiceConfigurationsUtility.RegisterGrainService(this.GrainServiceConfigurations, serviceName, serviceType, properties); } } } diff --git a/src/Orleans.Core/Configuration/GrainServiceConfiguration.cs b/src/Orleans.Core.Legacy/Configuration/GrainServiceConfiguration.cs similarity index 87% rename from src/Orleans.Core/Configuration/GrainServiceConfiguration.cs rename to src/Orleans.Core.Legacy/Configuration/GrainServiceConfiguration.cs index 6b3e826118..5c61123834 100644 --- a/src/Orleans.Core/Configuration/GrainServiceConfiguration.cs +++ b/src/Orleans.Core.Legacy/Configuration/GrainServiceConfiguration.cs @@ -11,7 +11,7 @@ public class GrainServiceConfigurations public GrainServiceConfigurations() { - GrainServices = new Dictionary(); + this.GrainServices = new Dictionary(); } internal static GrainServiceConfigurations Load(XmlElement child) @@ -64,9 +64,9 @@ public class GrainServiceConfiguration : IGrainServiceConfiguration public GrainServiceConfiguration(IDictionary properties, string serviceName, string serviceType) { - Properties = properties; - Name = serviceName; - ServiceType = serviceType; + this.Properties = properties; + this.Name = serviceName; + this.ServiceType = serviceType; } internal void Load(XmlElement child, IDictionary alreadyLoaded, XmlNamespaceManager nsManager) @@ -79,36 +79,36 @@ internal void Load(XmlElement child, IDictionary(); + this.Properties = new Dictionary(); for (int i = 0; i < child.Attributes.Count; i++) { var key = child.Attributes[i].LocalName; var val = child.Attributes[i].Value; if ((key != "Type") && (key != "Name")) { - Properties[key] = val; + this.Properties[key] = val; } } } diff --git a/src/Orleans.Core/Configuration/NodeConfiguration.cs b/src/Orleans.Core.Legacy/Configuration/NodeConfiguration.cs similarity index 58% rename from src/Orleans.Core/Configuration/NodeConfiguration.cs rename to src/Orleans.Core.Legacy/Configuration/NodeConfiguration.cs index 646490c6d7..a702601d4c 100644 --- a/src/Orleans.Core/Configuration/NodeConfiguration.cs +++ b/src/Orleans.Core.Legacy/Configuration/NodeConfiguration.cs @@ -1,3 +1,4 @@ +using Orleans.Hosting; using System; using System.Collections.Generic; using System.IO; @@ -24,10 +25,10 @@ public class NodeConfiguration :IStatisticsConfiguration /// public string SiloName { - get { return siloName; } + get { return this.siloName; } set { - siloName = value; + this.siloName = value; } } @@ -42,7 +43,7 @@ public string SiloName /// This is a configurable IP address or Hostname. /// public string HostNameOrIPAddress { get; set; } - private IPAddress Address { get { return ClusterConfiguration.ResolveIPAddress(HostNameOrIPAddress, Subnet, AddressType).GetResult(); } } + private IPAddress Address { get { return ConfigUtilities.ResolveIPAddress(this.HostNameOrIPAddress, this.Subnet, this.AddressType).GetResult(); } } /// /// The port this silo uses for silo-to-silo communication. @@ -59,7 +60,7 @@ public string SiloName /// public IPEndPoint Endpoint { - get { return new IPEndPoint(Address, Port); } + get { return new IPEndPoint(this.Address, this.Port); } } /// /// The AddressFamilyof the IP address of this silo. @@ -70,20 +71,20 @@ public IPEndPoint Endpoint /// public IPEndPoint ProxyGatewayEndpoint { get; set; } - internal byte[] Subnet { get; set; } // from global + public byte[] Subnet { get; set; } // from global /// /// Whether this is a primary silo (applies for dev settings only). /// - public bool IsPrimaryNode { get; internal set; } + public bool IsPrimaryNode { get; set; } /// /// Whether this is one of the seed silos (applies for dev settings only). /// - public bool IsSeedNode { get; internal set; } + public bool IsSeedNode { get; set; } /// /// Whether this is silo is a proxying gateway silo. /// - public bool IsGatewayNode { get { return ProxyGatewayEndpoint != null; } } + public bool IsGatewayNode { get { return this.ProxyGatewayEndpoint != null; } } /// /// The MaxActiveThreads attribute specifies the maximum number of simultaneous active threads the scheduler will allow. @@ -190,131 +191,122 @@ public IPEndPoint Endpoint public string SiloShutdownEventName { get; set; } internal const string DEFAULT_NODE_NAME = "default"; - private static readonly TimeSpan DEFAULT_STATS_METRICS_TABLE_WRITE_PERIOD = TimeSpan.FromSeconds(30); - private static readonly TimeSpan DEFAULT_STATS_PERF_COUNTERS_WRITE_PERIOD = TimeSpan.FromSeconds(30); - private static readonly TimeSpan DEFAULT_STATS_LOG_WRITE_PERIOD = TimeSpan.FromMinutes(5); - internal static readonly StatisticsLevel DEFAULT_STATS_COLLECTION_LEVEL = StatisticsLevel.Info; - private static readonly int DEFAULT_MAX_ACTIVE_THREADS = Math.Max(4, System.Environment.ProcessorCount); - private const int DEFAULT_MIN_DOT_NET_THREAD_POOL_SIZE = 200; - private static readonly int DEFAULT_MIN_DOT_NET_CONNECTION_LIMIT = DEFAULT_MIN_DOT_NET_THREAD_POOL_SIZE; - private static readonly TimeSpan DEFAULT_ACTIVATION_SCHEDULING_QUANTUM = TimeSpan.FromMilliseconds(100); - internal const bool ENABLE_WORKER_THREAD_INJECTION = false; public NodeConfiguration() { - creationTimestamp = DateTime.UtcNow; + this.creationTimestamp = DateTime.UtcNow; - SiloName = ""; - HostNameOrIPAddress = ""; - DNSHostName = Dns.GetHostName(); - Port = 0; - Generation = 0; - AddressType = AddressFamily.InterNetwork; - ProxyGatewayEndpoint = null; + this.SiloName = ""; + this.HostNameOrIPAddress = ""; + this.DNSHostName = Dns.GetHostName(); + this.Port = 0; + this.Generation = 0; + this.AddressType = AddressFamily.InterNetwork; + this.ProxyGatewayEndpoint = null; - MaxActiveThreads = DEFAULT_MAX_ACTIVE_THREADS; - DelayWarningThreshold = TimeSpan.FromMilliseconds(10000); // 10,000 milliseconds - ActivationSchedulingQuantum = DEFAULT_ACTIVATION_SCHEDULING_QUANTUM; - TurnWarningLengthThreshold = TimeSpan.FromMilliseconds(200); - EnableWorkerThreadInjection = ENABLE_WORKER_THREAD_INJECTION; + this.MaxActiveThreads = SchedulingOptions.DEFAULT_MAX_ACTIVE_THREADS; + this.DelayWarningThreshold = SchedulingOptions.DEFAULT_DELAY_WARNING_THRESHOLD; + this.ActivationSchedulingQuantum = SchedulingOptions.DEFAULT_ACTIVATION_SCHEDULING_QUANTUM; + this.TurnWarningLengthThreshold = SchedulingOptions.DEFAULT_DELAY_WARNING_THRESHOLD; + this.EnableWorkerThreadInjection = SchedulingOptions.DEFAULT_ENABLE_WORKER_THREAD_INJECTION; - LoadSheddingEnabled = false; - LoadSheddingLimit = 95; - - PropagateActivityId = Constants.DEFAULT_PROPAGATE_E2E_ACTIVITY_ID; + this.LoadSheddingEnabled = false; + this.LoadSheddingLimit = SiloStatisticsOptions.DEFAULT_LOAD_SHEDDING_LIMIT; - StatisticsMetricsTableWriteInterval = DEFAULT_STATS_METRICS_TABLE_WRITE_PERIOD; - StatisticsPerfCountersWriteInterval = DEFAULT_STATS_PERF_COUNTERS_WRITE_PERIOD; - StatisticsLogWriteInterval = DEFAULT_STATS_LOG_WRITE_PERIOD; - StatisticsWriteLogStatisticsToTable = true; - StatisticsCollectionLevel = DEFAULT_STATS_COLLECTION_LEVEL; + this.PropagateActivityId = SiloMessagingOptions.DEFAULT_PROPAGATE_ACTIVITY_ID; - LimitManager = new LimitManager(); + this.StatisticsMetricsTableWriteInterval = SiloStatisticsOptions.DEFAULT_METRICS_TABLE_WRITE_PERIOD; + this.StatisticsPerfCountersWriteInterval = SiloStatisticsOptions.SILO_DEFAULT_PERF_COUNTERS_WRITE_PERIOD; + this.StatisticsLogWriteInterval = SiloStatisticsOptions.DEFAULT_LOG_WRITE_PERIOD; + this.StatisticsWriteLogStatisticsToTable = SiloStatisticsOptions.DEFAULT_LOG_TO_TABLE; + this.StatisticsCollectionLevel = SiloStatisticsOptions.DEFAULT_COLLECTION_LEVEL; - MinDotNetThreadPoolSize = DEFAULT_MIN_DOT_NET_THREAD_POOL_SIZE; + this.LimitManager = new LimitManager(); + + this.MinDotNetThreadPoolSize = ThreadPoolOptions.DEFAULT_MIN_DOT_NET_THREAD_POOL_SIZE; // .NET ServicePointManager settings / optimizations - Expect100Continue = false; - DefaultConnectionLimit = DEFAULT_MIN_DOT_NET_CONNECTION_LIMIT; - UseNagleAlgorithm = false; + this.Expect100Continue = false; + this.DefaultConnectionLimit = ServicePointOptions.DEFAULT_MIN_DOT_NET_CONNECTION_LIMIT; + this.UseNagleAlgorithm = false; - AdditionalAssemblyDirectories = new Dictionary(); - ExcludedGrainTypes = new List(); + this.AdditionalAssemblyDirectories = new Dictionary(); + this.ExcludedGrainTypes = new List(); } public NodeConfiguration(NodeConfiguration other) { - creationTimestamp = other.creationTimestamp; - - SiloName = other.SiloName; - HostNameOrIPAddress = other.HostNameOrIPAddress; - DNSHostName = other.DNSHostName; - Port = other.Port; - Generation = other.Generation; - AddressType = other.AddressType; - ProxyGatewayEndpoint = other.ProxyGatewayEndpoint; - - MaxActiveThreads = other.MaxActiveThreads; - DelayWarningThreshold = other.DelayWarningThreshold; - ActivationSchedulingQuantum = other.ActivationSchedulingQuantum; - TurnWarningLengthThreshold = other.TurnWarningLengthThreshold; - EnableWorkerThreadInjection = other.EnableWorkerThreadInjection; - - LoadSheddingEnabled = other.LoadSheddingEnabled; - LoadSheddingLimit = other.LoadSheddingLimit; - - PropagateActivityId = other.PropagateActivityId; - - StatisticsProviderName = other.StatisticsProviderName; - StatisticsMetricsTableWriteInterval = other.StatisticsMetricsTableWriteInterval; - StatisticsPerfCountersWriteInterval = other.StatisticsPerfCountersWriteInterval; - StatisticsLogWriteInterval = other.StatisticsLogWriteInterval; - StatisticsWriteLogStatisticsToTable = other.StatisticsWriteLogStatisticsToTable; - StatisticsCollectionLevel = other.StatisticsCollectionLevel; - - LimitManager = new LimitManager(other.LimitManager); // Shallow copy - - Subnet = other.Subnet; - - MinDotNetThreadPoolSize = other.MinDotNetThreadPoolSize; - Expect100Continue = other.Expect100Continue; - DefaultConnectionLimit = other.DefaultConnectionLimit; - UseNagleAlgorithm = other.UseNagleAlgorithm; - - StartupTypeName = other.StartupTypeName; - AdditionalAssemblyDirectories = new Dictionary(other.AdditionalAssemblyDirectories); - ExcludedGrainTypes = other.ExcludedGrainTypes.ToList(); - TelemetryConfiguration = other.TelemetryConfiguration.Clone(); + this.creationTimestamp = other.creationTimestamp; + + this.SiloName = other.SiloName; + this.HostNameOrIPAddress = other.HostNameOrIPAddress; + this.DNSHostName = other.DNSHostName; + this.Port = other.Port; + this.Generation = other.Generation; + this.AddressType = other.AddressType; + this.ProxyGatewayEndpoint = other.ProxyGatewayEndpoint; + + this.MaxActiveThreads = other.MaxActiveThreads; + this.DelayWarningThreshold = other.DelayWarningThreshold; + this.ActivationSchedulingQuantum = other.ActivationSchedulingQuantum; + this.TurnWarningLengthThreshold = other.TurnWarningLengthThreshold; + this.EnableWorkerThreadInjection = other.EnableWorkerThreadInjection; + + this.LoadSheddingEnabled = other.LoadSheddingEnabled; + this.LoadSheddingLimit = other.LoadSheddingLimit; + + this.PropagateActivityId = other.PropagateActivityId; + + this.StatisticsProviderName = other.StatisticsProviderName; + this.StatisticsMetricsTableWriteInterval = other.StatisticsMetricsTableWriteInterval; + this.StatisticsPerfCountersWriteInterval = other.StatisticsPerfCountersWriteInterval; + this.StatisticsLogWriteInterval = other.StatisticsLogWriteInterval; + this.StatisticsWriteLogStatisticsToTable = other.StatisticsWriteLogStatisticsToTable; + this.StatisticsCollectionLevel = other.StatisticsCollectionLevel; + + this.LimitManager = new LimitManager(other.LimitManager); // Shallow copy + + this.Subnet = other.Subnet; + + this.MinDotNetThreadPoolSize = other.MinDotNetThreadPoolSize; + this.Expect100Continue = other.Expect100Continue; + this.DefaultConnectionLimit = other.DefaultConnectionLimit; + this.UseNagleAlgorithm = other.UseNagleAlgorithm; + + this.StartupTypeName = other.StartupTypeName; + this.AdditionalAssemblyDirectories = new Dictionary(other.AdditionalAssemblyDirectories); + this.ExcludedGrainTypes = other.ExcludedGrainTypes.ToList(); + this.TelemetryConfiguration = other.TelemetryConfiguration.Clone(); } public override string ToString() { var sb = new StringBuilder(); - sb.Append(" Silo Name: ").AppendLine(SiloName); - sb.Append(" Generation: ").Append(Generation).AppendLine(); - sb.Append(" Host Name or IP Address: ").AppendLine(HostNameOrIPAddress); - sb.Append(" DNS Host Name: ").AppendLine(DNSHostName); - sb.Append(" Port: ").Append(Port).AppendLine(); - sb.Append(" Subnet: ").Append(Subnet == null ? "" : Subnet.ToStrings(x => x.ToString(), ".")).AppendLine(); - sb.Append(" Preferred Address Family: ").Append(AddressType).AppendLine(); - if (IsGatewayNode) + sb.Append(" Silo Name: ").AppendLine(this.SiloName); + sb.Append(" Generation: ").Append(this.Generation).AppendLine(); + sb.Append(" Host Name or IP Address: ").AppendLine(this.HostNameOrIPAddress); + sb.Append(" DNS Host Name: ").AppendLine(this.DNSHostName); + sb.Append(" Port: ").Append(this.Port).AppendLine(); + sb.Append(" Subnet: ").Append(this.Subnet == null ? "" : this.Subnet.ToStrings(x => x.ToString(), ".")).AppendLine(); + sb.Append(" Preferred Address Family: ").Append(this.AddressType).AppendLine(); + if (this.IsGatewayNode) { - sb.Append(" Proxy Gateway: ").Append(ProxyGatewayEndpoint.ToString()).AppendLine(); + sb.Append(" Proxy Gateway: ").Append(this.ProxyGatewayEndpoint.ToString()).AppendLine(); } else { - sb.Append(" IsGatewayNode: ").Append(IsGatewayNode).AppendLine(); + sb.Append(" IsGatewayNode: ").Append(this.IsGatewayNode).AppendLine(); } - sb.Append(" IsPrimaryNode: ").Append(IsPrimaryNode).AppendLine(); + sb.Append(" IsPrimaryNode: ").Append(this.IsPrimaryNode).AppendLine(); sb.Append(" Scheduler: ").AppendLine(); - sb.Append(" ").Append(" Max Active Threads: ").Append(MaxActiveThreads).AppendLine(); + sb.Append(" ").Append(" Max Active Threads: ").Append(this.MaxActiveThreads).AppendLine(); sb.Append(" ").Append(" Processor Count: ").Append(System.Environment.ProcessorCount).AppendLine(); - sb.Append(" ").Append(" Delay Warning Threshold: ").Append(DelayWarningThreshold).AppendLine(); - sb.Append(" ").Append(" Activation Scheduling Quantum: ").Append(ActivationSchedulingQuantum).AppendLine(); - sb.Append(" ").Append(" Turn Warning Length Threshold: ").Append(TurnWarningLengthThreshold).AppendLine(); - sb.Append(" ").Append(" Inject More Worker Threads: ").Append(EnableWorkerThreadInjection).AppendLine(); - sb.Append(" ").Append(" MinDotNetThreadPoolSize: ").Append(MinDotNetThreadPoolSize).AppendLine(); + sb.Append(" ").Append(" Delay Warning Threshold: ").Append(this.DelayWarningThreshold).AppendLine(); + sb.Append(" ").Append(" Activation Scheduling Quantum: ").Append(this.ActivationSchedulingQuantum).AppendLine(); + sb.Append(" ").Append(" Turn Warning Length Threshold: ").Append(this.TurnWarningLengthThreshold).AppendLine(); + sb.Append(" ").Append(" Inject More Worker Threads: ").Append(this.EnableWorkerThreadInjection).AppendLine(); + sb.Append(" ").Append(" MinDotNetThreadPoolSize: ").Append(this.MinDotNetThreadPoolSize).AppendLine(); int workerThreads; int completionPortThreads; @@ -323,13 +315,13 @@ public override string ToString() ThreadPool.GetMaxThreads(out workerThreads, out completionPortThreads); sb.Append(" ").AppendFormat(" .NET thread pool sizes - Max: Worker Threads={0} Completion Port Threads={1}", workerThreads, completionPortThreads).AppendLine(); - sb.Append(" ").AppendFormat(" .NET ServicePointManager - DefaultConnectionLimit={0} Expect100Continue={1} UseNagleAlgorithm={2}", DefaultConnectionLimit, Expect100Continue, UseNagleAlgorithm).AppendLine(); - sb.Append(" Load Shedding Enabled: ").Append(LoadSheddingEnabled).AppendLine(); - sb.Append(" Load Shedding Limit: ").Append(LoadSheddingLimit).AppendLine(); - sb.Append(" SiloShutdownEventName: ").Append(SiloShutdownEventName).AppendLine(); + sb.Append(" ").AppendFormat(" .NET ServicePointManager - DefaultConnectionLimit={0} Expect100Continue={1} UseNagleAlgorithm={2}", this.DefaultConnectionLimit, this.Expect100Continue, this.UseNagleAlgorithm).AppendLine(); + sb.Append(" Load Shedding Enabled: ").Append(this.LoadSheddingEnabled).AppendLine(); + sb.Append(" Load Shedding Limit: ").Append(this.LoadSheddingLimit).AppendLine(); + sb.Append(" SiloShutdownEventName: ").Append(this.SiloShutdownEventName).AppendLine(); sb.Append(" Debug: ").AppendLine(); sb.Append(ConfigUtilities.IStatisticsConfigurationToString(this)); - sb.Append(LimitManager); + sb.Append(this.LimitManager); return sb.ToString(); } @@ -341,7 +333,7 @@ internal void InitNodeSettingsFromGlobals(ClusterConfiguration clusterConfigurat internal void Load(XmlElement root) { - SiloName = root.LocalName.Equals("Override") ? root.GetAttribute("Node") : DEFAULT_NODE_NAME; + this.SiloName = root.LocalName.Equals("Override") ? root.GetAttribute("Node") : DEFAULT_NODE_NAME; foreach (XmlNode c in root.ChildNodes) { @@ -354,109 +346,109 @@ internal void Load(XmlElement root) case "Networking": if (child.HasAttribute("Address")) { - HostNameOrIPAddress = child.GetAttribute("Address"); + this.HostNameOrIPAddress = child.GetAttribute("Address"); } if (child.HasAttribute("Port")) { - Port = ConfigUtilities.ParseInt(child.GetAttribute("Port"), - "Non-numeric Port attribute value on Networking element for " + SiloName); + this.Port = ConfigUtilities.ParseInt(child.GetAttribute("Port"), + "Non-numeric Port attribute value on Networking element for " + this.SiloName); } if (child.HasAttribute("PreferredFamily")) { - AddressType = ConfigUtilities.ParseEnum(child.GetAttribute("PreferredFamily"), + this.AddressType = ConfigUtilities.ParseEnum(child.GetAttribute("PreferredFamily"), "Invalid preferred address family on Networking node. Valid choices are 'InterNetwork' and 'InterNetworkV6'"); } break; case "ProxyingGateway": - ProxyGatewayEndpoint = ConfigUtilities.ParseIPEndPoint(child, Subnet).GetResult(); + this.ProxyGatewayEndpoint = ConfigUtilities.ParseIPEndPoint(child, this.Subnet).GetResult(); break; case "Scheduler": if (child.HasAttribute("MaxActiveThreads")) { - MaxActiveThreads = ConfigUtilities.ParseInt(child.GetAttribute("MaxActiveThreads"), - "Non-numeric MaxActiveThreads attribute value on Scheduler element for " + SiloName); - if (MaxActiveThreads < 1) + this.MaxActiveThreads = ConfigUtilities.ParseInt(child.GetAttribute("MaxActiveThreads"), + "Non-numeric MaxActiveThreads attribute value on Scheduler element for " + this.SiloName); + if (this.MaxActiveThreads < 1) { - MaxActiveThreads = DEFAULT_MAX_ACTIVE_THREADS; + this.MaxActiveThreads = SchedulingOptions.DEFAULT_MAX_ACTIVE_THREADS; } } if (child.HasAttribute("DelayWarningThreshold")) { - DelayWarningThreshold = ConfigUtilities.ParseTimeSpan(child.GetAttribute("DelayWarningThreshold"), - "Non-numeric DelayWarningThreshold attribute value on Scheduler element for " + SiloName); + this.DelayWarningThreshold = ConfigUtilities.ParseTimeSpan(child.GetAttribute("DelayWarningThreshold"), + "Non-numeric DelayWarningThreshold attribute value on Scheduler element for " + this.SiloName); } if (child.HasAttribute("ActivationSchedulingQuantum")) { - ActivationSchedulingQuantum = ConfigUtilities.ParseTimeSpan(child.GetAttribute("ActivationSchedulingQuantum"), - "Non-numeric ActivationSchedulingQuantum attribute value on Scheduler element for " + SiloName); + this.ActivationSchedulingQuantum = ConfigUtilities.ParseTimeSpan(child.GetAttribute("ActivationSchedulingQuantum"), + "Non-numeric ActivationSchedulingQuantum attribute value on Scheduler element for " + this.SiloName); } if (child.HasAttribute("TurnWarningLengthThreshold")) { - TurnWarningLengthThreshold = ConfigUtilities.ParseTimeSpan(child.GetAttribute("TurnWarningLengthThreshold"), - "Non-numeric TurnWarningLengthThreshold attribute value on Scheduler element for " + SiloName); + this.TurnWarningLengthThreshold = ConfigUtilities.ParseTimeSpan(child.GetAttribute("TurnWarningLengthThreshold"), + "Non-numeric TurnWarningLengthThreshold attribute value on Scheduler element for " + this.SiloName); } if (child.HasAttribute("MinDotNetThreadPoolSize")) { - MinDotNetThreadPoolSize = ConfigUtilities.ParseInt(child.GetAttribute("MinDotNetThreadPoolSize"), - "Invalid ParseInt MinDotNetThreadPoolSize value on Scheduler element for " + SiloName); + this.MinDotNetThreadPoolSize = ConfigUtilities.ParseInt(child.GetAttribute("MinDotNetThreadPoolSize"), + "Invalid ParseInt MinDotNetThreadPoolSize value on Scheduler element for " + this.SiloName); } if (child.HasAttribute("Expect100Continue")) { - Expect100Continue = ConfigUtilities.ParseBool(child.GetAttribute("Expect100Continue"), - "Invalid ParseBool Expect100Continue value on Scheduler element for " + SiloName); + this.Expect100Continue = ConfigUtilities.ParseBool(child.GetAttribute("Expect100Continue"), + "Invalid ParseBool Expect100Continue value on Scheduler element for " + this.SiloName); } if (child.HasAttribute("DefaultConnectionLimit")) { - DefaultConnectionLimit = ConfigUtilities.ParseInt(child.GetAttribute("DefaultConnectionLimit"), - "Invalid ParseInt DefaultConnectionLimit value on Scheduler element for " + SiloName); + this.DefaultConnectionLimit = ConfigUtilities.ParseInt(child.GetAttribute("DefaultConnectionLimit"), + "Invalid ParseInt DefaultConnectionLimit value on Scheduler element for " + this.SiloName); } if (child.HasAttribute("UseNagleAlgorithm ")) { - UseNagleAlgorithm = ConfigUtilities.ParseBool(child.GetAttribute("UseNagleAlgorithm "), - "Invalid ParseBool UseNagleAlgorithm value on Scheduler element for " + SiloName); + this.UseNagleAlgorithm = ConfigUtilities.ParseBool(child.GetAttribute("UseNagleAlgorithm "), + "Invalid ParseBool UseNagleAlgorithm value on Scheduler element for " + this.SiloName); } break; case "LoadShedding": if (child.HasAttribute("Enabled")) { - LoadSheddingEnabled = ConfigUtilities.ParseBool(child.GetAttribute("Enabled"), - "Invalid boolean value for Enabled attribute on LoadShedding attribute for " + SiloName); + this.LoadSheddingEnabled = ConfigUtilities.ParseBool(child.GetAttribute("Enabled"), + "Invalid boolean value for Enabled attribute on LoadShedding attribute for " + this.SiloName); } if (child.HasAttribute("LoadLimit")) { - LoadSheddingLimit = ConfigUtilities.ParseInt(child.GetAttribute("LoadLimit"), - "Invalid integer value for LoadLimit attribute on LoadShedding attribute for " + SiloName); - if (LoadSheddingLimit < 0) + this.LoadSheddingLimit = ConfigUtilities.ParseInt(child.GetAttribute("LoadLimit"), + "Invalid integer value for LoadLimit attribute on LoadShedding attribute for " + this.SiloName); + if (this.LoadSheddingLimit < 0) { - LoadSheddingLimit = 0; + this.LoadSheddingLimit = 0; } - if (LoadSheddingLimit > 100) + if (this.LoadSheddingLimit > 100) { - LoadSheddingLimit = 100; + this.LoadSheddingLimit = 100; } } break; case "Tracing": - if (ConfigUtilities.TryParsePropagateActivityId(child, siloName, out var propagateActivityId)) + if (ConfigUtilities.TryParsePropagateActivityId(child, this.siloName, out var propagateActivityId)) this.PropagateActivityId = propagateActivityId; break; case "Statistics": - ConfigUtilities.ParseStatistics(this, child, SiloName); + ConfigUtilities.ParseStatistics(this, child, this.SiloName); break; case "Limits": - ConfigUtilities.ParseLimitValues(LimitManager, child, SiloName); + ConfigUtilities.ParseLimitValues(this.LimitManager, child, this.SiloName); break; case "Startup": if (child.HasAttribute("Type")) { - StartupTypeName = child.GetAttribute("Type"); + this.StartupTypeName = child.GetAttribute("Type"); } break; case "Telemetry": ConfigUtilities.ParseTelemetry(child, this.TelemetryConfiguration); break; case "AdditionalAssemblyDirectories": - ConfigUtilities.ParseAdditionalAssemblyDirectories(AdditionalAssemblyDirectories, child); + ConfigUtilities.ParseAdditionalAssemblyDirectories(this.AdditionalAssemblyDirectories, child); break; } } diff --git a/src/Orleans.Core.Legacy/Properties/AssemblyInfo.cs b/src/Orleans.Core.Legacy/Properties/AssemblyInfo.cs new file mode 100644 index 0000000000..dc3d4edd82 --- /dev/null +++ b/src/Orleans.Core.Legacy/Properties/AssemblyInfo.cs @@ -0,0 +1,3 @@ +using System.Runtime.CompilerServices; + +[assembly: InternalsVisibleTo("Orleans.Runtime.Legacy")] diff --git a/src/Orleans.Core/Configuration/ClientConfiguration.cs b/src/Orleans.Core/Configuration/ClientConfiguration.cs index 583921a203..4b6e3dbb9c 100644 --- a/src/Orleans.Core/Configuration/ClientConfiguration.cs +++ b/src/Orleans.Core/Configuration/ClientConfiguration.cs @@ -7,6 +7,7 @@ using System.Text; using System.Threading; using System.Xml; +using Orleans.Hosting; using Orleans.Providers; namespace Orleans.Runtime.Configuration @@ -138,9 +139,7 @@ public string DeploymentId public LimitManager LimitManager { get; private set; } private static readonly TimeSpan DEFAULT_GATEWAY_LIST_REFRESH_PERIOD = TimeSpan.FromMinutes(1); - private static readonly TimeSpan DEFAULT_STATS_METRICS_TABLE_WRITE_PERIOD = TimeSpan.FromSeconds(30); private static readonly TimeSpan DEFAULT_STATS_PERF_COUNTERS_WRITE_PERIOD = Constants.INFINITE_TIMESPAN; - private static readonly TimeSpan DEFAULT_STATS_LOG_WRITE_PERIOD = TimeSpan.FromMinutes(5); /// /// @@ -191,11 +190,11 @@ public ClientConfiguration() GatewayListRefreshPeriod = DEFAULT_GATEWAY_LIST_REFRESH_PERIOD; StatisticsProviderName = null; - StatisticsMetricsTableWriteInterval = DEFAULT_STATS_METRICS_TABLE_WRITE_PERIOD; + StatisticsMetricsTableWriteInterval = StatisticsOptions.DEFAULT_METRICS_TABLE_WRITE_PERIOD; StatisticsPerfCountersWriteInterval = DEFAULT_STATS_PERF_COUNTERS_WRITE_PERIOD; - StatisticsLogWriteInterval = DEFAULT_STATS_LOG_WRITE_PERIOD; - StatisticsWriteLogStatisticsToTable = true; - StatisticsCollectionLevel = NodeConfiguration.DEFAULT_STATS_COLLECTION_LEVEL; + StatisticsLogWriteInterval = StatisticsOptions.DEFAULT_LOG_WRITE_PERIOD; + StatisticsWriteLogStatisticsToTable = StatisticsOptions.DEFAULT_LOG_TO_TABLE; + StatisticsCollectionLevel = StatisticsOptions.DEFAULT_COLLECTION_LEVEL; LimitManager = new LimitManager(); ProviderConfigurations = new Dictionary(); } diff --git a/src/Orleans.Core/Configuration/ConfigUtilities.cs b/src/Orleans.Core/Configuration/ConfigUtilities.cs index 37be913b2a..eb5f723554 100644 --- a/src/Orleans.Core/Configuration/ConfigUtilities.cs +++ b/src/Orleans.Core/Configuration/ConfigUtilities.cs @@ -4,6 +4,7 @@ using System.IO; using System.Linq; using System.Net; +using System.Net.NetworkInformation; using System.Net.Sockets; using System.Reflection; using System.Runtime; @@ -346,11 +347,128 @@ internal static async Task ParseIPEndPoint(XmlElement root, byte[] s family = ParseEnum(root.GetAttribute("PreferredFamily"), "Invalid preferred addressing family for " + root.LocalName + " element"); } - IPAddress addr = await ClusterConfiguration.ResolveIPAddress(root.GetAttribute("Address"), subnet, family); + IPAddress addr = await ResolveIPAddress(root.GetAttribute("Address"), subnet, family); int port = ParseInt(root.GetAttribute("Port"), "Invalid Port attribute for " + root.LocalName + " element"); return new IPEndPoint(addr, port); } + internal static async Task ResolveIPAddress(string addrOrHost, byte[] subnet, AddressFamily family) + { + var loopback = family == AddressFamily.InterNetwork ? IPAddress.Loopback : IPAddress.IPv6Loopback; + + // IF the address is an empty string, default to the local machine + if (string.IsNullOrEmpty(addrOrHost)) + { + addrOrHost = Dns.GetHostName(); + } + + // Fix StreamFilteringTests_SMS tests + if (addrOrHost.Equals("loopback", StringComparison.OrdinalIgnoreCase)) + { + return loopback; + } + + // check if addrOrHost is a valid IP address including loopback (127.0.0.0/8, ::1) and any (0.0.0.0/0, ::) addresses + IPAddress address; + if (IPAddress.TryParse(addrOrHost, out address)) + { + return address; + } + + var candidates = new List(); + + // Get IP address from DNS. If addrOrHost is localhost will + // return loopback IPv4 address (or IPv4 and IPv6 addresses if OS is supported IPv6) + var nodeIps = await Dns.GetHostAddressesAsync(addrOrHost); + foreach (var nodeIp in nodeIps.Where(x => x.AddressFamily == family)) + { + // If the subnet does not match - we can't resolve this address. + // If subnet is not specified - pick smallest address deterministically. + if (subnet == null) + { + candidates.Add(nodeIp); + } + else + { + var ip = nodeIp; + if (subnet.Select((b, i) => ip.GetAddressBytes()[i] == b).All(x => x)) + { + candidates.Add(nodeIp); + } + } + } + if (candidates.Count > 0) + { + return PickIPAddress(candidates); + } + var subnetStr = Utils.EnumerableToString(subnet, null, ".", false); + throw new ArgumentException("Hostname '" + addrOrHost + "' with subnet " + subnetStr + " and family " + family + " is not a valid IP address or DNS name"); + } + + internal static IPAddress PickIPAddress(IReadOnlyList candidates) + { + IPAddress chosen = null; + foreach (IPAddress addr in candidates) + { + if (chosen == null) + { + chosen = addr; + } + else + { + if (CompareIPAddresses(addr, chosen)) // pick smallest address deterministically + chosen = addr; + } + } + return chosen; + } + + /// + /// Gets the address of the local server. + /// If there are multiple addresses in the correct family in the server's DNS record, the first will be returned. + /// + /// The server's IPv4 address. + internal static IPAddress GetLocalIPAddress(AddressFamily family = AddressFamily.InterNetwork, string interfaceName = null) + { + var loopback = (family == AddressFamily.InterNetwork) ? IPAddress.Loopback : IPAddress.IPv6Loopback; + // get list of all network interfaces + NetworkInterface[] netInterfaces = NetworkInterface.GetAllNetworkInterfaces(); + + var candidates = new List(); + // loop through interfaces + for (int i = 0; i < netInterfaces.Length; i++) + { + NetworkInterface netInterface = netInterfaces[i]; + + if (netInterface.OperationalStatus != OperationalStatus.Up) + { + // Skip network interfaces that are not operational + continue; + } + if (!string.IsNullOrWhiteSpace(interfaceName) && + !netInterface.Name.StartsWith(interfaceName, StringComparison.Ordinal)) continue; + + bool isLoopbackInterface = (netInterface.NetworkInterfaceType == NetworkInterfaceType.Loopback); + // get list of all unicast IPs from current interface + UnicastIPAddressInformationCollection ipAddresses = netInterface.GetIPProperties().UnicastAddresses; + + // loop through IP address collection + foreach (UnicastIPAddressInformation ip in ipAddresses) + { + if (ip.Address.AddressFamily == family) // Picking the first address of the requested family for now. Will need to revisit later + { + //don't pick loopback address, unless we were asked for a loopback interface + if (!(isLoopbackInterface && ip.Address.Equals(loopback))) + { + candidates.Add(ip.Address); // collect all candidates. + } + } + } + } + if (candidates.Count > 0) return PickIPAddress(candidates); + throw new OrleansException("Failed to get a local IP address."); + } + internal static string IStatisticsConfigurationToString(IStatisticsConfiguration config) { var sb = new StringBuilder(); @@ -471,5 +589,26 @@ public static string RuntimeVersionInfo() .AppendLine(); return sb.ToString(); } + + // returns true if lhs is "less" (in some repeatable sense) than rhs + private static bool CompareIPAddresses(IPAddress lhs, IPAddress rhs) + { + byte[] lbytes = lhs.GetAddressBytes(); + byte[] rbytes = rhs.GetAddressBytes(); + + if (lbytes.Length != rbytes.Length) return lbytes.Length < rbytes.Length; + + // compare starting from most significant octet. + // 10.68.20.21 < 10.98.05.04 + for (int i = 0; i < lbytes.Length; i++) + { + if (lbytes[i] != rbytes[i]) + { + return lbytes[i] < rbytes[i]; + } + } + // They're equal + return false; + } } } \ No newline at end of file diff --git a/src/Orleans.Core/Configuration/ConfigurationExtensions.cs b/src/Orleans.Core/Configuration/ConfigurationExtensions.cs index 7c8f769307..6974aa0514 100644 --- a/src/Orleans.Core/Configuration/ConfigurationExtensions.cs +++ b/src/Orleans.Core/Configuration/ConfigurationExtensions.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using Orleans.Providers.Streams.SimpleMessageStream; using Orleans.Streams; @@ -10,23 +10,6 @@ namespace Orleans.Runtime.Configuration /// public static class ConfigurationExtensions { - /// - /// Adds a stream provider of type - /// - /// The cluster configuration object to add provider to. - /// The provider name. - /// Specifies whether the producer waits for the consumer to process the event before continuing. Setting this to false is useful for troubleshooting serialization issues. - /// If set to true items transfered via the stream are always wrapped in Immutable for delivery. - /// Specifies how can grains subscribe to this stream. - public static void AddSimpleMessageStreamProvider(this ClusterConfiguration config, string providerName, - bool fireAndForgetDelivery = SimpleMessageStreamProvider.DEFAULT_VALUE_FIRE_AND_FORGET_DELIVERY, - bool optimizeForImmutableData = SimpleMessageStreamProvider.DEFAULT_VALUE_OPTIMIZE_FOR_IMMUTABLE_DATA, - StreamPubSubType pubSubType = SimpleMessageStreamProvider.DEFAULT_STREAM_PUBSUB_TYPE) - { - var properties = GetSimpleMessageStreamProviderConfiguration(providerName, fireAndForgetDelivery, optimizeForImmutableData, pubSubType); - config.Globals.RegisterStreamProvider(providerName, properties); - } - /// /// Adds a stream provider of type /// @@ -57,23 +40,5 @@ public static class ConfigurationExtensions return properties; } - - - /// - /// Configures all cluster nodes to use the specified startup class for dependency injection. - /// - /// Startup type - [Obsolete("Using ISiloHostBuilder.ConfigureServices(Action configureServices) or ISiloHostBuilder.UseServiceProviderFactory(IServiceProviderFactory factory)")] - public static void UseStartupType(this ClusterConfiguration config) - { - var startupName = typeof(TStartup).AssemblyQualifiedName; - - foreach(var nodeConfig in config.Overrides.Values) { - nodeConfig.StartupTypeName = startupName; - } - - config.Defaults.StartupTypeName = startupName; - } - } } \ No newline at end of file diff --git a/src/Orleans.Core/Configuration/Legacy/LegacyConfigurationExtensions.cs b/src/Orleans.Core/Configuration/Legacy/LegacyConfigurationExtensions.cs index 8654b8766e..a9c275634e 100644 --- a/src/Orleans.Core/Configuration/Legacy/LegacyConfigurationExtensions.cs +++ b/src/Orleans.Core/Configuration/Legacy/LegacyConfigurationExtensions.cs @@ -52,7 +52,7 @@ public static IServiceCollection AddLegacyClientConfigurationSupport(this IServi services.Configure(options => { CopyCommonMessagingOptions(configuration, options); - + options.PropagateActivityId = configuration.PropagateActivityId; options.ClientSenderBuckets = configuration.ClientSenderBuckets; }); @@ -65,7 +65,7 @@ public static IServiceCollection AddLegacyClientConfigurationSupport(this IServi options.FallbackSerializationProvider = configuration.FallbackSerializationProvider; }); - services.Configure((options) => + services.Configure((options) => { CopyStatisticsOptions(configuration, options); }); diff --git a/src/Orleans.Core/Configuration/Options/AdoNetOptions.cs b/src/Orleans.Core/Configuration/Options/AdoNetOptions.cs new file mode 100644 index 0000000000..3208271f90 --- /dev/null +++ b/src/Orleans.Core/Configuration/Options/AdoNetOptions.cs @@ -0,0 +1,19 @@ + +namespace Orleans.Hosting +{ + public class AdoNetOptions + { + /// + /// When using ADO, identifies the underlying data provider for liveness and reminders. This three-part naming syntax is also used + /// when creating a new factory and for identifying the provider in an application configuration file so that the provider name, + /// along with its associated connection string, can be retrieved at run time. https://msdn.microsoft.com/en-us/library/dd0w4a2z%28v=vs.110%29.aspx + /// In order to override this value for reminders set + /// + public string Invariant { get; set; } + + /// + /// Set this property to override for reminders. + /// + public string InvariantForReminders { get; set; } + } +} diff --git a/src/Orleans.Core/Configuration/Options/ClientStatisticsOptions.cs b/src/Orleans.Core/Configuration/Options/ClientStatisticsOptions.cs new file mode 100644 index 0000000000..5229dc99db --- /dev/null +++ b/src/Orleans.Core/Configuration/Options/ClientStatisticsOptions.cs @@ -0,0 +1,31 @@ + +using System.Collections.Generic; +using Microsoft.Extensions.Options; + +namespace Orleans.Hosting +{ + public class ClientStatisticsOptions : StatisticsOptions + { + } + + public class ClientStatisticsOptionsFormatter : StatisticsOptionsFormatter, IOptionFormatter + { + public string Category { get; } + + public string Name => nameof(ClientStatisticsOptions); + + private ClientStatisticsOptions options; + + public ClientStatisticsOptionsFormatter(IOptions options) + : base(options.Value) + { + this.options = options.Value; + } + + public IEnumerable Format() + { + return base.FormatStatisticsOptions(); + } + } + +} diff --git a/src/Orleans.Core/Configuration/Options/ConsistentRingOptions.cs b/src/Orleans.Core/Configuration/Options/ConsistentRingOptions.cs new file mode 100644 index 0000000000..f16c1c6efe --- /dev/null +++ b/src/Orleans.Core/Configuration/Options/ConsistentRingOptions.cs @@ -0,0 +1,12 @@ + +namespace Orleans.Hosting +{ + public class ConsistentRingOptions + { + public int NumVirtualBucketsConsistentRing { get; set; } = DEFAULT_NUM_VIRTUAL_RING_BUCKETS; + public const int DEFAULT_NUM_VIRTUAL_RING_BUCKETS = 30; + + public bool UseVirtualBucketsConsistentRing { get; set; } = DEFAULT_USE_VIRTUAL_RING_BUCKETS; + public const bool DEFAULT_USE_VIRTUAL_RING_BUCKETS = true; + } +} diff --git a/src/Orleans.Core/Configuration/Options/GrainCollectionOptions.cs b/src/Orleans.Core/Configuration/Options/GrainCollectionOptions.cs new file mode 100644 index 0000000000..db9ec9774c --- /dev/null +++ b/src/Orleans.Core/Configuration/Options/GrainCollectionOptions.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; + +namespace Orleans.Hosting +{ + /// + /// Silo options for grain garbage collection. + /// + public class GrainCollectionOptions + { + public TimeSpan CollectionQuantum { get; set; } = DEFAULT_COLLECTION_QUANTUM; + public static readonly TimeSpan DEFAULT_COLLECTION_QUANTUM = TimeSpan.FromMinutes(1); + + public TimeSpan CollectionAge { get; set; } = DEFAULT_COLLECTION_AGE_LIMIT; + public static readonly TimeSpan DEFAULT_COLLECTION_AGE_LIMIT = TimeSpan.FromHours(2); + + public Dictionary ClassSpecificCollectionAge { get; set; } = new Dictionary(); + } +} diff --git a/src/Orleans.Core/Configuration/Options/GrainDirectoryOptions.cs b/src/Orleans.Core/Configuration/Options/GrainDirectoryOptions.cs new file mode 100644 index 0000000000..da7f58647c --- /dev/null +++ b/src/Orleans.Core/Configuration/Options/GrainDirectoryOptions.cs @@ -0,0 +1,65 @@ + +using System; + +namespace Orleans.Hosting +{ + public class GrainDirectoryOptions + { + /// + /// Configuration type that controls the type of the grain directory caching algorithm that silo use. + /// + public enum CachingStrategyType + { + /// Don't cache. + None, + /// Standard fixed-size LRU. + LRU, + /// Adaptive caching with fixed maximum size and refresh. This option should be used in production. + Adaptive + } + + /// + /// The DirectoryCachingStrategy attribute specifies the caching strategy to use. + /// The options are None, which means don't cache directory entries locally; + /// LRU, which indicates that a standard fixed-size least recently used strategy should be used; and + /// Adaptive, which indicates that an adaptive strategy with a fixed maximum size should be used. + /// The Adaptive strategy is used by default. + /// + public CachingStrategyType CachingStrategy { get; set; } = DEFAULT_CACHING_STRATEGY; + public const CachingStrategyType DEFAULT_CACHING_STRATEGY = CachingStrategyType.Adaptive; + + /// + /// The CacheSize attribute specifies the maximum number of grains to cache directory information for. + /// + public int CacheSize { get; set; } = DEFAULT_CACHE_SIZE; + public const int DEFAULT_CACHE_SIZE = 1000000; + + /// + /// The InitialTTL attribute specifies the initial (minimum) time, in seconds, to keep a cache entry before revalidating. + /// + public TimeSpan InitialCacheTTL { get; set; } = DEFAULT_INITIAL_CACHE_TTL; + public static readonly TimeSpan DEFAULT_INITIAL_CACHE_TTL = TimeSpan.FromSeconds(30); + + /// + /// The MaximumTTL attribute specifies the maximum time, in seconds, to keep a cache entry before revalidating. + /// + public TimeSpan MaximumCacheTTL { get; set; } = DEFAULT_MAXIMUM_CACHE_TTL; + public static readonly TimeSpan DEFAULT_MAXIMUM_CACHE_TTL = TimeSpan.FromSeconds(240); + + /// + /// The TTLExtensionFactor attribute specifies the factor by which cache entry TTLs should be extended when they are found to be stable. + /// + public double CacheTTLExtensionFactor { get; set; } = DEFAULT_TTL_EXTENSION_FACTOR; + public const double DEFAULT_TTL_EXTENSION_FACTOR = 2.0; + + /// + /// The time span between when we have added an entry for an activation to the grain directory and when we are allowed + /// to conditionally remove that entry. + /// Conditional deregistration is used for lazy clean-up of activations whose prompt deregistration failed for some reason (e.g., message failure). + /// This should always be at least one minute, since we compare the times on the directory partition, so message delays and clcks skues have + /// to be allowed. + /// + public TimeSpan LazyDeregistrationDelay { get; set; } = DEFAULT_UNREGISTER_RACE_DELAY; + public static readonly TimeSpan DEFAULT_UNREGISTER_RACE_DELAY = TimeSpan.FromMinutes(1); + } +} diff --git a/src/Orleans.Core/Configuration/Options/GrainPlacementOptions.cs b/src/Orleans.Core/Configuration/Options/GrainPlacementOptions.cs new file mode 100644 index 0000000000..fd5a9d989b --- /dev/null +++ b/src/Orleans.Core/Configuration/Options/GrainPlacementOptions.cs @@ -0,0 +1,13 @@ +using Orleans.Runtime; + +namespace Orleans.Hosting +{ + public class GrainPlacementOptions + { + public string DefaultPlacementStrategy { get; set; } = DEFAULT_PLACEMENT_STRATEGY; + public static readonly string DEFAULT_PLACEMENT_STRATEGY = nameof(RandomPlacement); + + public int ActivationCountPlacementChooseOutOf { get; set; } = DEFAULT_ACTIVATION_COUNT_PLACEMENT_CHOOSE_OUT_OF; + public const int DEFAULT_ACTIVATION_COUNT_PLACEMENT_CHOOSE_OUT_OF = 2; + } +} diff --git a/src/Orleans.Core/Configuration/Options/GrainServiceOptions.cs b/src/Orleans.Core/Configuration/Options/GrainServiceOptions.cs new file mode 100644 index 0000000000..cfb75b2e66 --- /dev/null +++ b/src/Orleans.Core/Configuration/Options/GrainServiceOptions.cs @@ -0,0 +1,10 @@ +using System; +using System.Collections.Generic; + +namespace Orleans.Hosting +{ + public class GrainServiceOptions + { + public List> GrainServices { get; set; } = new List>(); + } +} diff --git a/src/Orleans.Core/Configuration/Options/MembershipOptions.cs b/src/Orleans.Core/Configuration/Options/MembershipOptions.cs new file mode 100644 index 0000000000..3b98400d9a --- /dev/null +++ b/src/Orleans.Core/Configuration/Options/MembershipOptions.cs @@ -0,0 +1,95 @@ + +using System; + +namespace Orleans.Hosting +{ + public class MembershipOptions + { + /// + /// The number of missed "I am alive" updates in the table from a silo that causes warning to be logged. Does not impact the liveness protocol. + /// + public int NumMissedTableIAmAliveLimit { get; set; } = DEFAULT_LIVENESS_NUM_TABLE_I_AM_ALIVE_LIMIT; + public const int DEFAULT_LIVENESS_NUM_TABLE_I_AM_ALIVE_LIMIT = 2; + + /// + /// Global switch to disable silo liveness protocol (should be used only for testing). + /// The LivenessEnabled attribute, if provided and set to "false", suppresses liveness enforcement. + /// If a silo is suspected to be dead, but this attribute is set to "false", the suspicions will not propagated to the system and enforced, + /// This parameter is intended for use only for testing and troubleshooting. + /// In production, liveness should always be enabled. + /// Default is true (eanabled) + /// + public bool LivenessEnabled { get; set; } = DEFAULT_LIVENESS_ENABLED; + public const bool DEFAULT_LIVENESS_ENABLED = true; + + /// + /// The number of seconds to periodically probe other silos for their liveness or for the silo to send "I am alive" heartbeat messages about itself. + /// + public TimeSpan ProbeTimeout { get; set; } + public static readonly TimeSpan DEFAULT_LIVENESS_PROBE_TIMEOUT = TimeSpan.FromSeconds(10); + + /// + /// The number of seconds to periodically fetch updates from the membership table. + /// + public TimeSpan TableRefreshTimeout { get; set; } + public static readonly TimeSpan DEFAULT_LIVENESS_TABLE_REFRESH_TIMEOUT = TimeSpan.FromSeconds(60); + + /// + /// Expiration time in seconds for death vote in the membership table. + /// + public TimeSpan DeathVoteExpirationTimeout { get; set; } + public static readonly TimeSpan DEFAULT_LIVENESS_DEATH_VOTE_EXPIRATION_TIMEOUT = TimeSpan.FromSeconds(120); + + /// + /// The number of seconds to periodically write in the membership table that this silo is alive. Used ony for diagnostics. + /// + public TimeSpan IAmAliveTablePublishTimeout { get; set; } + public static readonly TimeSpan DEFAULT_LIVENESS_I_AM_ALIVE_TABLE_PUBLISH_TIMEOUT = TimeSpan.FromMinutes(5); + + /// + /// The number of seconds to attempt to join a cluster of silos before giving up. + /// + public TimeSpan MaxJoinAttemptTime { get; set; } + public static readonly TimeSpan DEFAULT_LIVENESS_MAX_JOIN_ATTEMPT_TIME = TimeSpan.FromMinutes(5); // 5 min + + /// + /// The expected size of a cluster. Need not be very accurate, can be an overestimate. + /// + public int ExpectedClusterSize { get; set; } + + /// + /// Whether new silo that joins the cluster has to validate the initial connectivity with all other Active silos. + /// + public bool ValidateInitialConnectivity { get; set; } = DEFAULT_VALIDATE_INITIAL_CONNECTIVITY; + public const bool DEFAULT_VALIDATE_INITIAL_CONNECTIVITY = true; + + /// + /// Whether to use the gossip optimization to speed up spreading liveness information. + /// + public bool UseLivenessGossip { get; set; } = DEFAULT_LIVENESS_USE_LIVENESS_GOSSIP; + public const bool DEFAULT_LIVENESS_USE_LIVENESS_GOSSIP = true; + + /// + /// The number of silos each silo probes for liveness. + /// + public int NumProbedSilos { get; set; } = DEFAULT_LIVENESS_NUM_PROBED_SILOS; + public const int DEFAULT_LIVENESS_NUM_PROBED_SILOS = 3; + + /// + /// The number of missed "I am alive" heartbeat messages from a silo or number of un-replied probes that lead to suspecting this silo as dead. + /// + public int NumMissedProbesLimit { get; set; } = DEFAULT_LIVENESS_NUM_MISSED_PROBES_LIMIT; + public const int DEFAULT_LIVENESS_NUM_MISSED_PROBES_LIMIT = 3; + + /// + /// The number of non-expired votes that are needed to declare some silo as dead (should be at most NumMissedProbesLimit) + /// + public int NumVotesForDeathDeclaration { get; set; } = DEFAULT_LIVENESS_NUM_VOTES_FOR_DEATH_DECLARATION; + public const int DEFAULT_LIVENESS_NUM_VOTES_FOR_DEATH_DECLARATION = 2; + + /// + /// TEST ONLY - Do not modify in production environments + /// + public bool IsRunningAsUnitTest { get; set; } = false; + } +} diff --git a/src/Orleans.Core/Configuration/Options/MessagingOptions.cs b/src/Orleans.Core/Configuration/Options/MessagingOptions.cs index 213f452ebb..efc121ee2b 100644 --- a/src/Orleans.Core/Configuration/Options/MessagingOptions.cs +++ b/src/Orleans.Core/Configuration/Options/MessagingOptions.cs @@ -8,7 +8,7 @@ namespace Orleans.Hosting /// /// Specifies global messaging options that are common to client and silo. /// - public class MessagingOptions + public abstract class MessagingOptions { /// /// The ResponseTimeout attribute specifies the default timeout before a request is assumed to have failed. @@ -47,5 +47,11 @@ public class MessagingOptions /// The initial size of the messaging buffer pool that is pre-allocated. /// public int BufferPoolPreallocationSize { get; set; } = 250; + + /// + /// Whether Trace.CorrelationManager.ActivityId settings should be propagated into grain calls. + /// + public bool PropagateActivityId { get; set; } = DEFAULT_PROPAGATE_ACTIVITY_ID; + public const bool DEFAULT_PROPAGATE_ACTIVITY_ID = Constants.DEFAULT_PROPAGATE_E2E_ACTIVITY_ID; } } diff --git a/src/Orleans.Core/Configuration/Options/MultiClusterOptions.cs b/src/Orleans.Core/Configuration/Options/MultiClusterOptions.cs index 042a0f7b51..d4e47bc6e3 100644 --- a/src/Orleans.Core/Configuration/Options/MultiClusterOptions.cs +++ b/src/Orleans.Core/Configuration/Options/MultiClusterOptions.cs @@ -8,6 +8,15 @@ namespace Orleans.Hosting /// public class MultiClusterOptions { + public static class BuiltIn + { + /// Default value to allow discrimination of override values. + public const string NotSpecified = "NotSpecified"; + + /// An Azure Table serving as a channel. + public const string AzureTable = "AzureTable"; + } + /// /// Whether this cluster is configured to be part of a multi-cluster network /// @@ -42,6 +51,9 @@ public class MultiClusterOptions /// /// The time between the slow retries for DOUBTFUL activations. /// - public TimeSpan GlobalSingleInstanceRetryInterval { get; set; } = TimeSpan.FromSeconds(30); + public TimeSpan GlobalSingleInstanceRetryInterval { get; set; } = DEFAULT_GLOBAL_SINGLE_INSTANCE_RETRY_INTERVAL; + public static readonly TimeSpan DEFAULT_GLOBAL_SINGLE_INSTANCE_RETRY_INTERVAL = TimeSpan.FromSeconds(30); + + public Dictionary GossipChannels { get; set; } = new Dictionary(); } } diff --git a/src/Orleans.Core/Configuration/Options/ReminderOptions.cs b/src/Orleans.Core/Configuration/Options/ReminderOptions.cs new file mode 100644 index 0000000000..0a5a84885c --- /dev/null +++ b/src/Orleans.Core/Configuration/Options/ReminderOptions.cs @@ -0,0 +1,56 @@ + +using System; + +namespace Orleans.Hosting +{ + public class ReminderOptions + { + public static class BuiltIn + { + public const string NotSpecified = "NotSpecified"; + + /// Grain is used to store reminders information. + /// This option is not reliable and thus should only be used in local development setting. + public const string ReminderTableGrain = "ReminderTableGrain"; + + /// AzureTable is used to store reminders information. + /// This option can be used in production. + public const string AzureTable = "AzureTable"; + + /// SQL Server is used to store reminders information. + /// This option can be used in production. + public const string SqlServer = "SqlServer"; + + /// Used for benchmarking; it simply delays for a specified delay during each operation. + public const string MockTable = "MockTable"; + + /// Reminder Service is disabled. + public const string Disabled = "Disabled"; + + /// Use custom Reminder Service from third-party assembly + public const string Custom = "Custom"; + } + + /// + /// The ReminderService attribute controls the type of the reminder service implementation used by silos. + /// + public string ReminderService { get; set; } + + /// + /// Assembly to use for custom ReminderTable implementation + /// + public string ReminderTableAssembly { get; set; } + + #region TEST + /// + /// For TEST - Not for use in production environments. + /// + public bool UseMockReminderTable { get; set; } = false; + /// + /// For TEST - Not for use in production environments. + /// + public TimeSpan MockReminderTableTimeout { get; set; } = DEFAULT_MOCK_REMINDER_TABLE_TIMEOUT; + public static readonly TimeSpan DEFAULT_MOCK_REMINDER_TABLE_TIMEOUT = TimeSpan.FromMilliseconds(50); + #endregion TEST + } +} diff --git a/src/Orleans.Core/Configuration/Options/SchedulingOptions.cs b/src/Orleans.Core/Configuration/Options/SchedulingOptions.cs new file mode 100644 index 0000000000..38dba0c253 --- /dev/null +++ b/src/Orleans.Core/Configuration/Options/SchedulingOptions.cs @@ -0,0 +1,60 @@ +using System; + +namespace Orleans.Hosting +{ + /// + /// Options for configuring scheduler behavior. + /// + public class SchedulingOptions + { + /// + /// Whether or not to perform deadlock detection. + /// + public bool PerformDeadlockDetection { get; set; } + + /// + /// Whether or not to allow reentrancy for calls within the same call chain. + /// + public bool AllowCallChainReentrancy { get; set; } + + /// + /// The MaxActiveThreads attribute specifies the maximum number of simultaneous active threads the scheduler will allow. + /// Generally this number should be roughly equal to the number of cores on the node. + /// + public int MaxActiveThreads { get; set; } = DEFAULT_MAX_ACTIVE_THREADS; + public static readonly int DEFAULT_MAX_ACTIVE_THREADS = Math.Max(4, System.Environment.ProcessorCount); + + /// + /// The DelayWarningThreshold attribute specifies the work item queuing delay threshold, at which a warning log message is written. + /// That is, if the delay between enqueuing the work item and executing the work item is greater than DelayWarningThreshold, a warning log is written. + /// + public TimeSpan DelayWarningThreshold { get; set; } = DEFAULT_DELAY_WARNING_THRESHOLD; + public static readonly TimeSpan DEFAULT_DELAY_WARNING_THRESHOLD = TimeSpan.FromMilliseconds(10000); // 10 seconds + + /// + /// ActivationSchedulingQuantum is a soft time limit on the duration of activation macro-turn (a number of micro-turns). + /// If a activation was running its micro-turns longer than this, we will give up the thread. + /// If this is set to zero or a negative number, then the full work queue is drained (MaxWorkItemsPerTurn allowing). + /// + public TimeSpan ActivationSchedulingQuantum { get; set; } = DEFAULT_ACTIVATION_SCHEDULING_QUANTUM; + public static readonly TimeSpan DEFAULT_ACTIVATION_SCHEDULING_QUANTUM = TimeSpan.FromMilliseconds(100); + + /// + /// TurnWarningLengthThreshold is a soft time limit to generate trace warning when the micro-turn executes longer then this period in CPU. + /// + public TimeSpan TurnWarningLengthThreshold { get; set; } = DEFAULT_TURN_WARNING_THRESHOLD; + public static readonly TimeSpan DEFAULT_TURN_WARNING_THRESHOLD = TimeSpan.FromMilliseconds(200); + + public int MaxPendingWorkItemsSoftLimit { get; set; } = DEFAULT_MAX_PENDING_ITEMS_SOFT_LIMIT; + public const int DEFAULT_MAX_PENDING_ITEMS_SOFT_LIMIT = 0; + + public int MaxPendingWorkItemsHardLimit { get; set; } = DEFAULT_MAX_PENDING_ITEMS_HARD_LIMIT; + public const int DEFAULT_MAX_PENDING_ITEMS_HARD_LIMIT = 0; + + /// + /// For test use only. Do not alter from default in production services + /// + public bool EnableWorkerThreadInjection { get; set; } = DEFAULT_ENABLE_WORKER_THREAD_INJECTION; + public const bool DEFAULT_ENABLE_WORKER_THREAD_INJECTION = false; + } +} \ No newline at end of file diff --git a/src/Orleans.Core/Configuration/Options/ServicePointOptions.cs b/src/Orleans.Core/Configuration/Options/ServicePointOptions.cs new file mode 100644 index 0000000000..7343110b27 --- /dev/null +++ b/src/Orleans.Core/Configuration/Options/ServicePointOptions.cs @@ -0,0 +1,13 @@ + +namespace Orleans.Hosting +{ + public class ServicePointOptions + { + public int DefaultConnectionLimit { get; set; } = DEFAULT_MIN_DOT_NET_CONNECTION_LIMIT; + public static readonly int DEFAULT_MIN_DOT_NET_CONNECTION_LIMIT = ThreadPoolOptions.DEFAULT_MIN_DOT_NET_THREAD_POOL_SIZE; + + public bool Expect100Continue { get; set; } + + public bool UseNagleAlgorithm { get; set; } + } +} diff --git a/src/Orleans.Core/Configuration/Options/SiloMessagingOptions.cs b/src/Orleans.Core/Configuration/Options/SiloMessagingOptions.cs index 83ea9ea771..da98a83bd6 100644 --- a/src/Orleans.Core/Configuration/Options/SiloMessagingOptions.cs +++ b/src/Orleans.Core/Configuration/Options/SiloMessagingOptions.cs @@ -35,6 +35,32 @@ public class SiloMessagingOptions : MessagingOptions /// This is the period of time a gateway will wait before dropping a disconnected client. /// public TimeSpan ClientDropTimeout { get; set; } = Constants.DEFAULT_CLIENT_DROP_TIMEOUT; + + public TimeSpan ClientRegistrationRefresh { get; set; } = DEFAULT_CLIENT_REGISTRATION_REFRESH; + public static readonly TimeSpan DEFAULT_CLIENT_REGISTRATION_REFRESH = TimeSpan.FromMinutes(5); + + public int MaxEnqueuedRequestsSoftLimit { get; set; } = DEFAULT_MAX_ENQUEUED_REQUESTS_SOFT_LIMIT; + public const int DEFAULT_MAX_ENQUEUED_REQUESTS_SOFT_LIMIT = 0; + + public int MaxEnqueuedRequestsHardLimit { get; set; } = DEFAULT_MAX_ENQUEUED_REQUESTS_HARD_LIMIT; + public const int DEFAULT_MAX_ENQUEUED_REQUESTS_HARD_LIMIT = 0; + + public int MaxEnqueuedRequestsSoftLimit_StatelessWorker { get; set; } = DEFAULT_MAX_ENQUEUED_REQUESTS_STATELESS_WORKER_SOFT_LIMIT; + public const int DEFAULT_MAX_ENQUEUED_REQUESTS_STATELESS_WORKER_SOFT_LIMIT = 0; + + public int MaxEnqueuedRequestsHardLimit_StatelessWorker { get; set; } = DEFAULT_MAX_ENQUEUED_REQUESTS_STATELESS_WORKER_HARD_LIMIT; + public const int DEFAULT_MAX_ENQUEUED_REQUESTS_STATELESS_WORKER_HARD_LIMIT = 0; + + /// + /// Specifies the maximum time that a request can take before the activation is reported as "blocked" + /// + public TimeSpan MaxRequestProcessingTime { get; set; } = DEFAULT_MAX_REQUEST_PROCESSING_TIME; + public static readonly TimeSpan DEFAULT_MAX_REQUEST_PROCESSING_TIME = GrainCollectionOptions.DEFAULT_COLLECTION_AGE_LIMIT; + + /// + /// For test only - Do not use in production + /// + public bool AssumeHomogenousSilosForTesting { get; set; } = false; } public class SiloMessageingOptionFormatter : IOptionFormatter diff --git a/src/Orleans.Core/Configuration/Options/SiloStatisticsOptions.cs b/src/Orleans.Core/Configuration/Options/SiloStatisticsOptions.cs new file mode 100644 index 0000000000..71b12d8ce7 --- /dev/null +++ b/src/Orleans.Core/Configuration/Options/SiloStatisticsOptions.cs @@ -0,0 +1,63 @@ +using System; +using System.Collections.Generic; +using Microsoft.Extensions.Options; + +namespace Orleans.Hosting +{ + public class SiloStatisticsOptions : StatisticsOptions + { + public static readonly TimeSpan SILO_DEFAULT_PERF_COUNTERS_WRITE_PERIOD = TimeSpan.FromSeconds(30); + + public SiloStatisticsOptions() + { + this.PerfCountersWriteInterval = SILO_DEFAULT_PERF_COUNTERS_WRITE_PERIOD; + } + + public TimeSpan DeploymentLoadPublisherRefreshTime { get; set; } = DEFAULT_DEPLOYMENT_LOAD_PUBLISHER_REFRESH_TIME; + public static readonly TimeSpan DEFAULT_DEPLOYMENT_LOAD_PUBLISHER_REFRESH_TIME = TimeSpan.FromSeconds(1); + + + /// + /// The LoadShedding element specifies the gateway load shedding configuration for the node. + /// If it does not appear, gateway load shedding is disabled. + /// + public bool LoadSheddingEnabled { get; set; } + + /// + /// The LoadLimit attribute specifies the system load, in CPU%, at which load begins to be shed. + /// Note that this value is in %, so valid values range from 1 to 100, and a reasonable value is + /// typically between 80 and 95. + /// This value is ignored if load shedding is disabled, which is the default. + /// If load shedding is enabled and this attribute does not appear, then the default limit is 95%. + /// + public int LoadSheddingLimit { get; set; } = DEFAULT_LOAD_SHEDDING_LIMIT; + public const int DEFAULT_LOAD_SHEDDING_LIMIT = 95; + } + + public class SiloStatisticsOptionsFormatter : StatisticsOptionsFormatter, IOptionFormatter + { + public string Category { get; } + + public string Name => nameof(SiloStatisticsOptions); + + private SiloStatisticsOptions options; + + public SiloStatisticsOptionsFormatter(IOptions options) + :base(options.Value) + { + this.options = options.Value; + } + + public IEnumerable Format() + { + List format = base.FormatStatisticsOptions(); + format.AddRange(new List + { + OptionFormattingUtilities.Format(nameof(this.options.DeploymentLoadPublisherRefreshTime), this.options.DeploymentLoadPublisherRefreshTime), + OptionFormattingUtilities.Format(nameof(this.options.LoadSheddingEnabled), this.options.LoadSheddingEnabled), + OptionFormattingUtilities.Format(nameof(this.options.LoadSheddingLimit), this.options.LoadSheddingLimit), + }); + return format; + } + } +} diff --git a/src/Orleans.Core/Configuration/Options/StatisticsOptions.cs b/src/Orleans.Core/Configuration/Options/StatisticsOptions.cs index ebad4700ce..8fb39d889f 100644 --- a/src/Orleans.Core/Configuration/Options/StatisticsOptions.cs +++ b/src/Orleans.Core/Configuration/Options/StatisticsOptions.cs @@ -1,65 +1,69 @@ +using System; +using System.Collections.Generic; using Microsoft.Extensions.Options; using Orleans.Runtime; using Orleans.Runtime.Configuration; -using System; -using System.Collections.Generic; namespace Orleans.Hosting { /// /// The StatisticsOptions type contains various statistics output related options. /// - public class StatisticsOptions + public abstract class StatisticsOptions { /// /// The MetricsTableWriteInterval property specifies the frequency of updating the metrics in Azure table. /// The default is 30 seconds. /// - public TimeSpan MetricsTableWriteInterval { get; set; } = TimeSpan.FromSeconds(30); + public TimeSpan MetricsTableWriteInterval { get; set; } = DEFAULT_METRICS_TABLE_WRITE_PERIOD; + public static readonly TimeSpan DEFAULT_METRICS_TABLE_WRITE_PERIOD = TimeSpan.FromSeconds(30); /// /// The PerfCounterWriteInterval property specifies the frequency of updating the windows performance counters. /// The default is 30 seconds. /// - public TimeSpan PerfCountersWriteInterval { get; set; } = Constants.INFINITE_TIMESPAN; + public TimeSpan PerfCountersWriteInterval { get; set; } = DEFAULT_PERF_COUNTERS_WRITE_PERIOD; + public static readonly TimeSpan DEFAULT_PERF_COUNTERS_WRITE_PERIOD = Constants.INFINITE_TIMESPAN; /// /// The LogWriteInterval property specifies the frequency of updating the statistics in the log file. /// The default is 5 minutes. /// - public TimeSpan LogWriteInterval { get; set; } = TimeSpan.FromMinutes(5); + public TimeSpan LogWriteInterval { get; set; } = DEFAULT_LOG_WRITE_PERIOD; + public static readonly TimeSpan DEFAULT_LOG_WRITE_PERIOD = TimeSpan.FromMinutes(5); /// /// The WriteLogStatisticsToTable property specifies whether log statistics should also be written into a separate, special Azure table. /// The default is yes. /// - public bool WriteLogStatisticsToTable { get; set; } = true; + public bool WriteLogStatisticsToTable { get; set; } = DEFAULT_LOG_TO_TABLE; + public const bool DEFAULT_LOG_TO_TABLE = true; /// /// The CollectionLevel property specifies the verbosity level of statistics to collect. The default is Info. /// - public StatisticsLevel CollectionLevel { get; set; } = StatisticsLevel.Info; + public StatisticsLevel CollectionLevel { get; set; } = DEFAULT_COLLECTION_LEVEL; + public static readonly StatisticsLevel DEFAULT_COLLECTION_LEVEL = StatisticsLevel.Info; } - public class StatisticOptionsFormatter : IOptionFormatter + public abstract class StatisticsOptionsFormatter { - public string Category { get; } - - public string Name => nameof(StatisticsOptions); private StatisticsOptions options; - public StatisticOptionsFormatter(IOptions options) + + protected StatisticsOptionsFormatter(StatisticsOptions options) { - this.options = options.Value; + this.options = options; } - public IEnumerable Format() + + protected List FormatStatisticsOptions() { return new List() { - OptionFormattingUtilities.Format(nameof(options.MetricsTableWriteInterval), options.MetricsTableWriteInterval), - OptionFormattingUtilities.Format(nameof(options.PerfCountersWriteInterval), options.PerfCountersWriteInterval), - OptionFormattingUtilities.Format(nameof(options.LogWriteInterval), options.LogWriteInterval), - OptionFormattingUtilities.Format(nameof(options.WriteLogStatisticsToTable), options.WriteLogStatisticsToTable), - OptionFormattingUtilities.Format(nameof(options.CollectionLevel), options.CollectionLevel), + OptionFormattingUtilities.Format(nameof(this.options.MetricsTableWriteInterval), this.options.MetricsTableWriteInterval), + OptionFormattingUtilities.Format(nameof(this.options.PerfCountersWriteInterval), this.options.PerfCountersWriteInterval), + OptionFormattingUtilities.Format(nameof(this.options.LogWriteInterval), this.options.LogWriteInterval), + OptionFormattingUtilities.Format(nameof(this.options.WriteLogStatisticsToTable), this.options.WriteLogStatisticsToTable), + OptionFormattingUtilities.Format(nameof(this.options.CollectionLevel), this.options.CollectionLevel), }; } } diff --git a/src/Orleans.Core/Configuration/Options/StorageOptions.cs b/src/Orleans.Core/Configuration/Options/StorageOptions.cs new file mode 100644 index 0000000000..26824e82d2 --- /dev/null +++ b/src/Orleans.Core/Configuration/Options/StorageOptions.cs @@ -0,0 +1,13 @@ + +namespace Orleans.Hosting +{ + public class StorageOptions + { + public string DataConnectionString { get; set; } + + /// + /// Set this property to override for reminders. + /// + public string DataConnectionStringForReminders { get; set; } + } +} diff --git a/src/Orleans.Core/Configuration/Options/ThreadPoolOptions.cs b/src/Orleans.Core/Configuration/Options/ThreadPoolOptions.cs new file mode 100644 index 0000000000..f6abb1e435 --- /dev/null +++ b/src/Orleans.Core/Configuration/Options/ThreadPoolOptions.cs @@ -0,0 +1,9 @@ + +namespace Orleans.Hosting +{ + public class ThreadPoolOptions + { + public int MinDotNetThreadPoolSize { get; set; } = DEFAULT_MIN_DOT_NET_THREAD_POOL_SIZE; + public const int DEFAULT_MIN_DOT_NET_THREAD_POOL_SIZE = 200; + } +} diff --git a/src/Orleans.Core/Configuration/Options/TypeManagementOptions.cs b/src/Orleans.Core/Configuration/Options/TypeManagementOptions.cs new file mode 100644 index 0000000000..884dee1010 --- /dev/null +++ b/src/Orleans.Core/Configuration/Options/TypeManagementOptions.cs @@ -0,0 +1,14 @@ +using System; + +namespace Orleans.Hosting +{ + public class TypeManagementOptions + { + /// + /// The number of seconds to refresh the cluster grain interface map + /// + public TimeSpan TypeMapRefreshInterval { get; set; } = DEFAULT_REFRESH_CLUSTER_INTERFACEMAP_TIME; + public static readonly TimeSpan DEFAULT_REFRESH_CLUSTER_INTERFACEMAP_TIME = TimeSpan.FromMinutes(1); + + } +} diff --git a/src/Orleans.Core/Configuration/Options/VersioningOptions.cs b/src/Orleans.Core/Configuration/Options/VersioningOptions.cs new file mode 100644 index 0000000000..ca1541df70 --- /dev/null +++ b/src/Orleans.Core/Configuration/Options/VersioningOptions.cs @@ -0,0 +1,15 @@ + +using Orleans.Versions.Compatibility; +using Orleans.Versions.Selector; + +namespace Orleans.Hosting +{ + public class VersioningOptions + { + public string DefaultCompatibilityStrategy { get; set; } = DEFAULT_COMPATABILITY_STRATEGY; + public const string DEFAULT_COMPATABILITY_STRATEGY = nameof(BackwardCompatible); + + public string DefaultVersionSelectorStrategy { get; set; } = DEFAULT_VERSION_SELECTOR_STRATEGY; + public const string DEFAULT_VERSION_SELECTOR_STRATEGY = nameof(AllCompatibleVersions); + } +} diff --git a/src/Orleans.Core/Core/DefaultClientServices.cs b/src/Orleans.Core/Core/DefaultClientServices.cs index b502cb2b62..90cf3fe804 100644 --- a/src/Orleans.Core/Core/DefaultClientServices.cs +++ b/src/Orleans.Core/Core/DefaultClientServices.cs @@ -68,7 +68,7 @@ public static void AddDefaultServices(IClientBuilder builder, IServiceCollection services.TryConfigureFormatter(); services.TryConfigureFormatter(); services.TryConfigureFormatter(); - services.TryConfigureFormatter(); + services.TryConfigureFormatter(); } } } \ No newline at end of file diff --git a/src/Orleans.Core/Messaging/BufferPool.cs b/src/Orleans.Core/Messaging/BufferPool.cs index 67f1238fdb..6012be7bea 100644 --- a/src/Orleans.Core/Messaging/BufferPool.cs +++ b/src/Orleans.Core/Messaging/BufferPool.cs @@ -39,11 +39,9 @@ public string Name private set; } - internal static void InitGlobalBufferPool(IOptions messagingOptions) + internal static void InitGlobalBufferPool(MessagingOptions messagingOptions) { - var messagingOptionsValue = messagingOptions.Value; - - GlobalPool = new BufferPool(messagingOptionsValue.BufferPoolBufferSize, messagingOptionsValue.BufferPoolMaxSize, messagingOptionsValue.BufferPoolPreallocationSize, "Global"); + GlobalPool = new BufferPool(messagingOptions.BufferPoolBufferSize, messagingOptions.BufferPoolMaxSize, messagingOptions.BufferPoolPreallocationSize, "Global"); } /// diff --git a/src/Orleans.Core/Messaging/Message.cs b/src/Orleans.Core/Messaging/Message.cs index ff79ae55b9..f4d406b484 100644 --- a/src/Orleans.Core/Messaging/Message.cs +++ b/src/Orleans.Core/Messaging/Message.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Text; using Orleans.CodeGeneration; +using Orleans.Hosting; using Orleans.Runtime.Configuration; using Orleans.Serialization; using Orleans.Transactions; @@ -349,9 +350,9 @@ public bool MayResend(int maxResendCount) // Forwardings are used by the receiver, usualy when it cannot process the message and forwars it to another silo to perform the processing // (got here due to outdated cache, silo is shutting down/overloaded, ...). - public bool MayForward(GlobalConfiguration config) + public bool MayForward(SiloMessagingOptions messagingOptions) { - return ForwardCount < config.MaxForwardCount; + return ForwardCount < messagingOptions.MaxForwardCount; } /// diff --git a/src/Orleans.Core/Placement/DefaultPlacementStrategy.cs b/src/Orleans.Core/Placement/DefaultPlacementStrategy.cs deleted file mode 100644 index 3cd0adc3b5..0000000000 --- a/src/Orleans.Core/Placement/DefaultPlacementStrategy.cs +++ /dev/null @@ -1,42 +0,0 @@ -using Orleans.Runtime.Configuration; - -namespace Orleans.Runtime -{ - internal class DefaultPlacementStrategy - { - public DefaultPlacementStrategy(GlobalConfiguration config) : this(config.DefaultPlacementStrategy) - { - } - - protected DefaultPlacementStrategy(string placement) - { - this.PlacementStrategy = GetDefaultStrategy(placement); - } - - /// - /// Gets the default placement strategy. - /// - public PlacementStrategy PlacementStrategy { get; } - - private static PlacementStrategy GetDefaultStrategy(string str) - { - if (str.Equals(typeof(RandomPlacement).Name)) - { - return RandomPlacement.Singleton; - } - else if (str.Equals(typeof(PreferLocalPlacement).Name)) - { - return PreferLocalPlacement.Singleton; - } - else if (str.Equals(typeof(SystemPlacement).Name)) - { - return SystemPlacement.Singleton; - } - else if (str.Equals(typeof(ActivationCountBasedPlacement).Name)) - { - return ActivationCountBasedPlacement.Singleton; - } - return null; - } - } -} \ No newline at end of file diff --git a/src/Orleans.Core/Placement/IPlacementDirector.cs b/src/Orleans.Core/Placement/IPlacementDirector.cs index ec2030d97c..0ea1ae3a3b 100644 --- a/src/Orleans.Core/Placement/IPlacementDirector.cs +++ b/src/Orleans.Core/Placement/IPlacementDirector.cs @@ -10,13 +10,4 @@ public interface IPlacementDirector Task OnAddActivation( PlacementStrategy strategy, PlacementTarget target, IPlacementContext context); } - - /// - /// Interface for placement directors implementing the specified strategy. - /// - /// The placement strategy which this director implements. - public interface IPlacementDirector : IPlacementDirector - where TStrategy : PlacementStrategy - { - } } diff --git a/src/Orleans.Core/Placement/SystemPlacement.cs b/src/Orleans.Core/Placement/SystemPlacement.cs index db9281356f..fc14672cd5 100644 --- a/src/Orleans.Core/Placement/SystemPlacement.cs +++ b/src/Orleans.Core/Placement/SystemPlacement.cs @@ -6,17 +6,5 @@ namespace Orleans.Runtime internal class SystemPlacement : PlacementStrategy { internal static SystemPlacement Singleton { get; } = new SystemPlacement(); - - private SystemPlacement() {} - - public override bool Equals(object obj) - { - return obj is SystemPlacement; - } - - public override int GetHashCode() - { - return GetType().GetHashCode(); - } } } diff --git a/src/Orleans.Core/Providers/LegacyProviderConfigurator.cs b/src/Orleans.Core/Providers/LegacyProviderConfigurator.cs index 51bef858e1..fe368d08c5 100644 --- a/src/Orleans.Core/Providers/LegacyProviderConfigurator.cs +++ b/src/Orleans.Core/Providers/LegacyProviderConfigurator.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Threading; using System.Threading.Tasks; using System.Diagnostics; @@ -111,9 +111,9 @@ public ProviderLifecycleParticipant(IProviderConfiguration config, IServiceProvi public virtual void Participate(TLifecycle lifecycle) { this.initStage = this.config.GetIntProperty(LegacyProviderConfigurator.InitStageName, this.defaultInitStage); - lifecycle.Subscribe(this.initStage, Init, Close); + lifecycle.Subscribe(this.initStage, this.Init, this.Close); this.startStage = this.config.GetIntProperty(LegacyProviderConfigurator.StartStageName, this.defaultStartStage); - lifecycle.Subscribe(this.startStage, Start); + lifecycle.Subscribe(this.startStage, this.Start); } @@ -162,7 +162,7 @@ private static void RegisterProvider(IProviderConfiguration config, IS return Activator.CreateInstance(providerType) as TService; }); services.AddSingletonNamedService>(config.Name, (s, n) => new ProviderLifecycleParticipant(config, s, s.GetRequiredService(), defaultInitStage, defaultStartStage)); - services.AddSingletonNamedService(config.Name, (s, n) => s.GetServiceByName(n) as IControllable); + services.AddSingletonNamedService(config.Name, (s, n) => s.GetServiceByName(n) as IControllable); } } } diff --git a/src/Orleans.Core/Runtime/OutsideRuntimeClient.cs b/src/Orleans.Core/Runtime/OutsideRuntimeClient.cs index 9af8762ea3..405f43b9ae 100644 --- a/src/Orleans.Core/Runtime/OutsideRuntimeClient.cs +++ b/src/Orleans.Core/Runtime/OutsideRuntimeClient.cs @@ -132,10 +132,10 @@ internal void ConsumeServices(IServiceProvider services) this.GrainReferenceRuntime = this.ServiceProvider.GetRequiredService(); - var statisticsOptions = this.ServiceProvider.GetRequiredService>(); - StatisticsCollector.Initialize(statisticsOptions.Value.CollectionLevel); + var statisticsOptions = this.ServiceProvider.GetRequiredService>().Value; + StatisticsCollector.Initialize(statisticsOptions.CollectionLevel); - BufferPool.InitGlobalBufferPool(resolvedClientMessagingOptions); + BufferPool.InitGlobalBufferPool(resolvedClientMessagingOptions.Value); try { @@ -144,7 +144,7 @@ internal void ConsumeServices(IServiceProvider services) clientProviderRuntime = this.ServiceProvider.GetRequiredService(); responseTimeout = Debugger.IsAttached ? Constants.DEFAULT_RESPONSE_TIMEOUT : config.ResponseTimeout; - this.localAddress = ClusterConfiguration.GetLocalIPAddress(config.PreferredFamily, config.NetInterface); + this.localAddress = ConfigUtilities.GetLocalIPAddress(config.PreferredFamily, config.NetInterface); // Client init / sign-on message logger.Info(ErrorCode.ClientInitializing, string.Format( diff --git a/src/Orleans.Core/Statistics/ClientStatisticsManager.cs b/src/Orleans.Core/Statistics/ClientStatisticsManager.cs index 4c1f4f53fd..92daf294f7 100644 --- a/src/Orleans.Core/Statistics/ClientStatisticsManager.cs +++ b/src/Orleans.Core/Statistics/ClientStatisticsManager.cs @@ -13,7 +13,7 @@ namespace Orleans.Runtime internal class ClientStatisticsManager : IDisposable { private readonly ClientConfiguration config; - private readonly StatisticsOptions statisticsOptions; + private readonly ClientStatisticsOptions statisticsOptions; private readonly IServiceProvider serviceProvider; private readonly IHostEnvironmentStatistics hostEnvironmentStatistics; private readonly IAppEnvironmentStatistics appEnvironmentStatistics; @@ -30,7 +30,7 @@ internal class ClientStatisticsManager : IDisposable IHostEnvironmentStatistics hostEnvironmentStatistics, IAppEnvironmentStatistics appEnvironmentStatistics, ILoggerFactory loggerFactory, - IOptions statisticsOptions, + IOptions statisticsOptions, IOptions clusterClientOptions) { this.config = config; diff --git a/src/Orleans.Core/SystemTargetInterfaces/IManagementGrain.cs b/src/Orleans.Core/SystemTargetInterfaces/IManagementGrain.cs index 1fe25b21e8..fa367a13b8 100644 --- a/src/Orleans.Core/SystemTargetInterfaces/IManagementGrain.cs +++ b/src/Orleans.Core/SystemTargetInterfaces/IManagementGrain.cs @@ -101,34 +101,6 @@ public interface IManagementGrain : IGrainWithIntegerKey, IVersionManager /// Completion promise for this operation. Task SendControlCommandToProvider(string providerTypeFullName, string providerName, int command, object arg = null); - /// - /// Update the configuration information dynamically. Only a subset of configuration information - /// can be updated - will throw an error (and make no config changes) if you specify attributes - /// or elements that cannot be changed. The configuration format is XML, in the same format - /// as the OrleansConfiguration.xml file. The allowed elements and attributes are: - ///
-        /// <OrleansConfiguration>
-        ///     <Globals>
-        ///         <Messaging ResponseTimeout="?"/>
-        ///         <Caching CacheSize="?"/>
-        ///         <Activation CollectionInterval="?" CollectionAmount="?" CollectionTotalMemoryLimit="?" CollectionActivationLimit="?"/>
-        ///         <Liveness ProbeTimeout="?" TableRefreshTimeout="?" NumMissedProbesLimit="?"/>
-        ///     </Globals>
-        ///     <Defaults>
-        ///         <LoadShedding Enabled="?" LoadLimit="?"/>
-        ///         <Tracing DefaultTraceLevel="?" PropagateActivityId="?">
-        ///             <TraceLevelOverride LogPrefix="?" TraceLevel="?"/>
-        ///         </Tracing>
-        ///     </Defaults>
-        /// </OrleansConfiguration>
-        /// 
- ///
- /// Silos to update, or null for all silos - /// XML elements and attributes to update - /// Tracing level settings - /// - Task UpdateConfiguration(SiloAddress[] hostIds, Dictionary configuration, Dictionary tracing); - /// /// Returns an array of all the active grain types in the system /// diff --git a/src/Orleans.Core/SystemTargetInterfaces/IReminderTable.cs b/src/Orleans.Core/SystemTargetInterfaces/IReminderTable.cs index 50dc81da1a..3ecc95fa29 100644 --- a/src/Orleans.Core/SystemTargetInterfaces/IReminderTable.cs +++ b/src/Orleans.Core/SystemTargetInterfaces/IReminderTable.cs @@ -14,7 +14,7 @@ namespace Orleans ///
public interface IReminderTable { - Task Init(GlobalConfiguration config); + Task Init(); Task ReadRows(GrainReference key); diff --git a/src/Orleans.Core/SystemTargetInterfaces/IRemoteGrainDirectory.cs b/src/Orleans.Core/SystemTargetInterfaces/IRemoteGrainDirectory.cs index 9334da967a..e4d5fdca01 100644 --- a/src/Orleans.Core/SystemTargetInterfaces/IRemoteGrainDirectory.cs +++ b/src/Orleans.Core/SystemTargetInterfaces/IRemoteGrainDirectory.cs @@ -12,7 +12,7 @@ internal interface IActivationInfo SiloAddress SiloAddress { get; } DateTime TimeCreated { get; } GrainDirectoryEntryStatus RegistrationStatus { get; set; } - bool OkToRemove(UnregistrationCause cause, GlobalConfiguration config); + bool OkToRemove(UnregistrationCause cause, TimeSpan lazyDeregistrationDelay); } internal interface IGrainInfo @@ -22,7 +22,7 @@ internal interface IGrainInfo bool SingleInstance { get; } bool AddActivation(ActivationId act, SiloAddress silo); ActivationAddress AddSingleActivation(GrainId grain, ActivationId act, SiloAddress silo, GrainDirectoryEntryStatus registrationStatus); - bool RemoveActivation(ActivationId act, UnregistrationCause cause, GlobalConfiguration config, out IActivationInfo entry, out bool wasRemoved); + bool RemoveActivation(ActivationId act, UnregistrationCause cause, TimeSpan lazyDeregistrationDelay, out IActivationInfo entry, out bool wasRemoved); /// /// Merges two grain directory infos, returning a map of activations which must be deactivated, grouped by silo. diff --git a/src/Orleans.Core/SystemTargetInterfaces/ISiloControl.cs b/src/Orleans.Core/SystemTargetInterfaces/ISiloControl.cs index f1bb7798cc..0fa36c8a75 100644 --- a/src/Orleans.Core/SystemTargetInterfaces/ISiloControl.cs +++ b/src/Orleans.Core/SystemTargetInterfaces/ISiloControl.cs @@ -19,8 +19,6 @@ internal interface ISiloControl : ISystemTarget, IVersionManager Task GetSimpleGrainStatistics(); Task GetDetailedGrainReport(GrainId grainId); - Task UpdateConfiguration(string configuration); - Task GetActivationCount(); Task SendControlCommandToProvider(string providerTypeFullName, string providerName, int command, object arg); diff --git a/src/Orleans.Core/Telemetry/ITelemetryConsumer.cs b/src/Orleans.Core/Telemetry/ITelemetryConsumer.cs index 1e92e6149e..121f75954c 100644 --- a/src/Orleans.Core/Telemetry/ITelemetryConsumer.cs +++ b/src/Orleans.Core/Telemetry/ITelemetryConsumer.cs @@ -1,4 +1,4 @@ -namespace Orleans.Runtime +namespace Orleans.Runtime { /// /// Marker interface for all Telemetry Consumers diff --git a/src/Orleans.Hosting.ServiceFabric/Orleans.Hosting.ServiceFabric.csproj b/src/Orleans.Hosting.ServiceFabric/Orleans.Hosting.ServiceFabric.csproj index 6082788ee4..74892cec61 100644 --- a/src/Orleans.Hosting.ServiceFabric/Orleans.Hosting.ServiceFabric.csproj +++ b/src/Orleans.Hosting.ServiceFabric/Orleans.Hosting.ServiceFabric.csproj @@ -20,6 +20,7 @@ + diff --git a/src/Orleans.Runtime.Abstractions/MembershipService/ILegacyMembershipConfigurator.cs b/src/Orleans.Runtime.Abstractions/MembershipService/ILegacyMembershipConfigurator.cs index 9691a6d406..cc8002843d 100644 --- a/src/Orleans.Runtime.Abstractions/MembershipService/ILegacyMembershipConfigurator.cs +++ b/src/Orleans.Runtime.Abstractions/MembershipService/ILegacyMembershipConfigurator.cs @@ -1,11 +1,6 @@ -using System; -using System.Collections.Generic; -using System.Linq; using Microsoft.Extensions.DependencyInjection; -using Orleans.Hosting; -using Orleans.Messaging; -using Orleans.Runtime.Configuration; -using LivenessProviderType = Orleans.Runtime.Configuration.GlobalConfiguration.LivenessProviderType; +using System; +using System.Reflection; namespace Orleans.Runtime.MembershipService { @@ -17,6 +12,28 @@ public interface ILegacyMembershipConfigurator /// /// Configure the membership table in the legacy way /// - void ConfigureServices(GlobalConfiguration configuration, IServiceCollection services); + void ConfigureServices(object configuration, IServiceCollection services); + } + + /// + /// Wapper for legacy config. Should not be used for any new developent, only adapting legacy systems. + /// + public class GlobalConfigurationReader + { + private readonly object configuration; + private readonly Type type; + + public GlobalConfigurationReader(object configuration) + { + this.configuration = configuration; + this.type = configuration.GetType(); + if(this.type.Name != "GlobalConfiguration") throw new ArgumentException($"GlobalConfiguration expected", nameof(configuration)); + } + + public T GetPropertyValue(string propertyName) + { + MethodInfo getMethod = this.type.GetProperty(propertyName).GetGetMethod(); + return (T)getMethod.Invoke(this.configuration, null); + } } } diff --git a/src/Orleans.Runtime.Abstractions/Silo/SiloOptions.cs b/src/Orleans.Runtime.Abstractions/Silo/SiloOptions.cs index b58fcbb904..a4c8c5e8b6 100644 --- a/src/Orleans.Runtime.Abstractions/Silo/SiloOptions.cs +++ b/src/Orleans.Runtime.Abstractions/Silo/SiloOptions.cs @@ -21,5 +21,8 @@ public class SiloOptions /// Gets or sets a unique identifier for this service, which should survive deployment and redeployment, where as might not. /// public Guid ServiceId { get; set; } + + public bool FastKillOnCancelKeyPress { get; set; } = DEFAULT_FAST_KILL_ON_CANCEL; + public const bool DEFAULT_FAST_KILL_ON_CANCEL = true; } } \ No newline at end of file diff --git a/src/OrleansProviders/BuiltInProvidersConfigurationExtensions.cs b/src/Orleans.Runtime.Legacy/Configuration/BuiltInProvidersConfigurationExtensions.cs similarity index 76% rename from src/OrleansProviders/BuiltInProvidersConfigurationExtensions.cs rename to src/Orleans.Runtime.Legacy/Configuration/BuiltInProvidersConfigurationExtensions.cs index a536d618c9..7b1887b0a9 100644 --- a/src/OrleansProviders/BuiltInProvidersConfigurationExtensions.cs +++ b/src/Orleans.Runtime.Legacy/Configuration/BuiltInProvidersConfigurationExtensions.cs @@ -1,6 +1,5 @@ -using System; +using System; using System.Collections.Generic; -using Orleans.Storage; namespace Orleans.Runtime.Configuration { @@ -18,16 +17,16 @@ public static class BuiltInProvidersConfigurationExtensions public static void AddMemoryStorageProvider( this ClusterConfiguration config, string providerName = "MemoryStore", - int numStorageGrains = MemoryStorage.NumStorageGrainsDefaultValue) + int numStorageGrains = 10) { if (string.IsNullOrWhiteSpace(providerName)) throw new ArgumentNullException(nameof(providerName)); var properties = new Dictionary { - { MemoryStorage.NumStorageGrainsPropertyName, numStorageGrains.ToString() }, + { "NumStorageGrains", numStorageGrains.ToString() }, }; - config.Globals.RegisterStorageProvider(providerName, properties); + config.Globals.RegisterStorageProvider("Orleans.Storage.MemoryStorage", providerName, properties); } } } \ No newline at end of file diff --git a/src/Orleans.Runtime.Legacy/Configuration/LegacyClusterConfigurationExtensions.cs b/src/Orleans.Runtime.Legacy/Configuration/LegacyClusterConfigurationExtensions.cs new file mode 100644 index 0000000000..ee153d6092 --- /dev/null +++ b/src/Orleans.Runtime.Legacy/Configuration/LegacyClusterConfigurationExtensions.cs @@ -0,0 +1,356 @@ +using System; +using System.Linq; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection.Extensions; +using Microsoft.Extensions.Options; +using Orleans.Configuration; +using Orleans.Runtime; +using Orleans.Runtime.Configuration; +using Orleans.Runtime.MembershipService; +using Orleans.Runtime.Scheduler; +using Orleans.Providers; +using Orleans.Configuration.Options; +using System.Collections.Generic; + +namespace Orleans.Hosting +{ + public static class LegacyClusterConfigurationExtensions + { + private const int SiloDefaultProviderInitStage = SiloLifecycleStage.RuntimeStorageServices; + private const int SiloDefaultProviderStartStage = SiloLifecycleStage.ApplicationServices; + + /// + /// Specifies the configuration to use for this silo. + /// + /// The host builder. + /// The configuration. + /// This method may only be called once per builder instance. + /// The silo builder. + public static ISiloHostBuilder UseConfiguration(this ISiloHostBuilder builder, ClusterConfiguration configuration) + { + if (configuration == null) throw new ArgumentNullException(nameof(configuration)); + return builder.ConfigureServices((context, services) => + { + services.AddLegacyClusterConfigurationSupport(configuration); + }); + } + + /// + /// Loads using . + /// + /// The host builder. + /// The silo builder. + public static ISiloHostBuilder LoadClusterConfiguration(this ISiloHostBuilder builder) + { + var configuration = new ClusterConfiguration(); + configuration.StandardLoad(); + return builder.UseConfiguration(configuration); + } + + /// + /// Configures a localhost silo. + /// + /// The host builder. + /// The silo-to-silo communication port. + /// The client-to-silo communication port. + /// The silo builder. + public static ISiloHostBuilder ConfigureLocalHostPrimarySilo(this ISiloHostBuilder builder, int siloPort = 22222, int gatewayPort = 40000) + { + builder.ConfigureSiloName(Silo.PrimarySiloName); + return builder.UseConfiguration(ClusterConfiguration.LocalhostPrimarySilo(siloPort, gatewayPort)); + } + + public static IServiceCollection AddLegacyClusterConfigurationSupport(this IServiceCollection services, ClusterConfiguration configuration) + { + if (configuration == null) throw new ArgumentNullException(nameof(configuration)); + + if (services.TryGetClusterConfiguration() != null) + { + throw new InvalidOperationException("Cannot configure legacy ClusterConfiguration support twice"); + } + + // these will eventually be removed once our code doesn't depend on the old ClientConfiguration + services.AddSingleton(configuration); + services.TryAddSingleton(); + services.TryAddSingleton(sp => sp.GetRequiredService().ClusterConfig.Globals); + services.TryAddTransient(sp => sp.GetRequiredService().NodeConfig); + services.TryAddSingleton>( + sp => + { + var initializationParams = sp.GetRequiredService(); + return () => initializationParams.NodeConfig; + }); + + services.Configure(options => + { + if (string.IsNullOrWhiteSpace(options.ClusterId) && !string.IsNullOrWhiteSpace(configuration.Globals.ClusterId)) + { + options.ClusterId = configuration.Globals.ClusterId; + } + + if (options.ServiceId == Guid.Empty) + { + options.ServiceId = configuration.Globals.ServiceId; + } + options.FastKillOnCancelKeyPress = configuration.Globals.FastKillOnCancelKeyPress; + }); + + services.Configure(options => + { + var globals = configuration.Globals; + if (globals.HasMultiClusterNetwork) + { + options.HasMultiClusterNetwork = true; + options.BackgroundGossipInterval = globals.BackgroundGossipInterval; + options.DefaultMultiCluster = globals.DefaultMultiCluster?.ToList(); + options.GlobalSingleInstanceNumberRetries = globals.GlobalSingleInstanceNumberRetries; + options.GlobalSingleInstanceRetryInterval = globals.GlobalSingleInstanceRetryInterval; + options.MaxMultiClusterGateways = globals.MaxMultiClusterGateways; + options.UseGlobalSingleInstanceByDefault = globals.UseGlobalSingleInstanceByDefault; + foreach(GlobalConfiguration.GossipChannelConfiguration channelConfig in globals.GossipChannels) + { + options.GossipChannels.Add(GlobalConfiguration.Remap(channelConfig.ChannelType), channelConfig.ConnectionString); + } + } + }); + + services.TryAddFromExisting(); + + services.AddOptions() + .Configure((options, nodeConfig) => LegacyConfigurationExtensions.CopyStatisticsOptions(nodeConfig, options)) + .Configure((options, nodeConfig) => + { + options.LoadSheddingEnabled = nodeConfig.LoadSheddingEnabled; + options.LoadSheddingLimit = nodeConfig.LoadSheddingLimit; + }) + .Configure((options, config) => + { + options.DeploymentLoadPublisherRefreshTime = config.DeploymentLoadPublisherRefreshTime; + }); + + // Translate legacy configuration to new Options + services.AddOptions() + .Configure((options, config) => + { + LegacyConfigurationExtensions.CopyCommonMessagingOptions(config, options); + options.SiloSenderQueues = config.SiloSenderQueues; + options.GatewaySenderQueues = config.GatewaySenderQueues; + options.MaxForwardCount = config.MaxForwardCount; + options.ClientDropTimeout = config.ClientDropTimeout; + options.ClientRegistrationRefresh = config.ClientRegistrationRefresh; + options.MaxRequestProcessingTime = config.MaxRequestProcessingTime; + options.AssumeHomogenousSilosForTesting = config.AssumeHomogenousSilosForTesting; + }) + .Configure((options, config) => + { + options.PropagateActivityId = config.PropagateActivityId; + LimitValue requestLimit = config.LimitManager.GetLimit(LimitNames.LIMIT_MAX_ENQUEUED_REQUESTS); + options.MaxEnqueuedRequestsSoftLimit = requestLimit.SoftLimitThreshold; + options.MaxEnqueuedRequestsHardLimit = requestLimit.HardLimitThreshold; + LimitValue statelessWorkerRequestLimit = config.LimitManager.GetLimit(LimitNames.LIMIT_MAX_ENQUEUED_REQUESTS_STATELESS_WORKER); + options.MaxEnqueuedRequestsSoftLimit_StatelessWorker = statelessWorkerRequestLimit.SoftLimitThreshold; + options.MaxEnqueuedRequestsHardLimit_StatelessWorker = statelessWorkerRequestLimit.HardLimitThreshold; + }); + + services.Configure(options => LegacyConfigurationExtensions.CopyNetworkingOptions(configuration.Globals, options)); + + services.AddOptions() + .Configure>((options, siloOptions) => + { + var nodeConfig = configuration.GetOrCreateNodeConfigurationForSilo(siloOptions.Value.SiloName); + if (options.IPAddress == null && string.IsNullOrWhiteSpace(options.HostNameOrIPAddress)) + { + options.IPAddress = nodeConfig.Endpoint.Address; + options.Port = nodeConfig.Endpoint.Port; + } + if (options.ProxyPort == 0 && nodeConfig.ProxyGatewayEndpoint != null) + { + options.ProxyPort = nodeConfig.ProxyGatewayEndpoint.Port; + } + }); + + services.Configure(options => + { + options.SerializationProviders = configuration.Globals.SerializationProviders; + options.FallbackSerializationProvider = configuration.Globals.FallbackSerializationProvider; + }); + + services.Configure(options => + { + LegacyConfigurationExtensions.CopyTelemetryOptions(configuration.Defaults.TelemetryConfiguration, services, options); + }); + + services.AddOptions().Configure>((options, siloOptions) => + { + var nodeConfig = configuration.GetOrCreateNodeConfigurationForSilo(siloOptions.Value.SiloName); + options.ExcludedGrainTypes.AddRange(nodeConfig.ExcludedGrainTypes); + }); + + LegacyMembershipConfigurator.ConfigureServices(configuration.Globals, services); + + services.AddOptions() + .Configure((options, config) => + { + options.AllowCallChainReentrancy = config.AllowCallChainReentrancy; + options.PerformDeadlockDetection = config.PerformDeadlockDetection; + }) + .Configure((options, nodeConfig) => + { + options.MaxActiveThreads = nodeConfig.MaxActiveThreads; + options.DelayWarningThreshold = nodeConfig.DelayWarningThreshold; + options.ActivationSchedulingQuantum = nodeConfig.ActivationSchedulingQuantum; + options.TurnWarningLengthThreshold = nodeConfig.TurnWarningLengthThreshold; + options.EnableWorkerThreadInjection = nodeConfig.EnableWorkerThreadInjection; + LimitValue itemLimit = nodeConfig.LimitManager.GetLimit(LimitNames.LIMIT_MAX_PENDING_ITEMS); + options.MaxPendingWorkItemsSoftLimit = itemLimit.SoftLimitThreshold; + options.MaxPendingWorkItemsHardLimit = itemLimit.HardLimitThreshold; + }); + + services.AddOptions().Configure((options, config) => + { + options.CollectionQuantum = config.CollectionQuantum; + options.CollectionAge = config.Application.DefaultCollectionAgeLimit; + foreach (GrainTypeConfiguration grainConfig in config.Application.ClassSpecific) + { + if(grainConfig.CollectionAgeLimit.HasValue) + { + options.ClassSpecificCollectionAge.Add(grainConfig.FullTypeName, grainConfig.CollectionAgeLimit.Value); + } + }; + }); + + services.TryAddSingleton(sp => + { + OrleansTaskScheduler scheduler = sp.GetRequiredService(); + SystemTarget fallbackSystemTarget = sp.GetRequiredService(); + return (taskFunc) => scheduler.QueueTask(taskFunc, fallbackSystemTarget.SchedulingContext); + }); + LegacyProviderConfigurator.ConfigureServices(configuration.Globals.ProviderConfigurations, services, SiloDefaultProviderInitStage, SiloDefaultProviderStartStage); + + services.AddOptions().Configure((options, config) => + { + options.DefaultPlacementStrategy = config.DefaultPlacementStrategy; + options.ActivationCountPlacementChooseOutOf = config.ActivationCountBasedPlacementChooseOutOf; + }); + + services.AddOptions().Configure((options, config) => + { + options.SiloNames = config.Overrides.Keys.ToList(); + }); + + // add grain service configs as keyed services + short id = 0; + foreach (IGrainServiceConfiguration grainServiceConfiguration in configuration.Globals.GrainServiceConfigurations.GrainServices.Values) + { + services.AddSingletonKeyedService(id++, (sp, k) => grainServiceConfiguration); + } + // populate grain service options + id = 0; + services.AddOptions().Configure((options, config) => + { + foreach(IGrainServiceConfiguration grainServiceConfiguration in config.GrainServiceConfigurations.GrainServices.Values) + { + options.GrainServices.Add(new KeyValuePair(grainServiceConfiguration.ServiceType, id++)); + } + }); + + services.AddOptions().Configure((options, config) => + { + options.UseVirtualBucketsConsistentRing = config.UseVirtualBucketsConsistentRing; + options.NumVirtualBucketsConsistentRing = config.NumVirtualBucketsConsistentRing; + }); + + services.AddOptions() + .Configure((options, config) => + { + options.NumMissedTableIAmAliveLimit = config.NumMissedTableIAmAliveLimit; + options.LivenessEnabled = config.LivenessEnabled; + options.ProbeTimeout = config.ProbeTimeout; + options.TableRefreshTimeout = config.TableRefreshTimeout; + options.DeathVoteExpirationTimeout = config.DeathVoteExpirationTimeout; + options.IAmAliveTablePublishTimeout = config.IAmAliveTablePublishTimeout; + options.MaxJoinAttemptTime = config.MaxJoinAttemptTime; + options.ExpectedClusterSize = config.ExpectedClusterSize; + options.ValidateInitialConnectivity = config.ValidateInitialConnectivity; + options.NumMissedProbesLimit = config.NumMissedProbesLimit; + options.UseLivenessGossip = config.UseLivenessGossip; + options.NumProbedSilos = config.NumProbedSilos; + options.NumVotesForDeathDeclaration = config.NumVotesForDeathDeclaration; + }) + .Configure((options, config) => + { + options.IsRunningAsUnitTest = config.IsRunningAsUnitTest; + }); + + services.AddOptions() + .Configure((options, config) => + { + options.ReminderService = GlobalConfiguration.Remap(config.ReminderServiceType); + options.ReminderTableAssembly = config.ReminderTableAssembly; + options.UseMockReminderTable = config.UseMockReminderTable; + options.MockReminderTableTimeout = config.MockReminderTableTimeout; + }); + + services.AddOptions() + .Configure((options, config) => + { + options.DefaultCompatibilityStrategy = config.DefaultCompatibilityStrategy?.GetType().Name ?? VersioningOptions.DEFAULT_COMPATABILITY_STRATEGY; + options.DefaultVersionSelectorStrategy = config.DefaultVersionSelectorStrategy?.GetType().Name ?? VersioningOptions.DEFAULT_VERSION_SELECTOR_STRATEGY; + }); + + services.AddOptions() + .Configure((options, config) => + { + options.MinDotNetThreadPoolSize = config.MinDotNetThreadPoolSize; + }); + + services.AddOptions() + .Configure((options, config) => + { + options.DefaultConnectionLimit = config.DefaultConnectionLimit; + options.Expect100Continue = config.Expect100Continue; + options.UseNagleAlgorithm = config.UseNagleAlgorithm; + }); + + services.AddOptions() + .Configure((options, config) => + { + options.DataConnectionString = config.DataConnectionString; + options.DataConnectionStringForReminders = config.DataConnectionStringForReminders; + }); + + services.AddOptions() + .Configure((options, config) => + { + options.Invariant = config.AdoInvariant; + options.InvariantForReminders = config.AdoInvariantForReminders; + }); + + services.AddOptions() + .Configure((options, config) => + { + options.TypeMapRefreshInterval = config.TypeMapRefreshInterval; + }); + + services.AddOptions() + .Configure((options, config) => + { + options.CachingStrategy = GlobalConfiguration.Remap(config.DirectoryCachingStrategy); + options.CacheSize = config.CacheSize; + options.InitialCacheTTL = config.InitialCacheTTL; + options.MaximumCacheTTL = config.MaximumCacheTTL; + options.CacheTTLExtensionFactor = config.CacheTTLExtensionFactor; + options.LazyDeregistrationDelay = config.DirectoryLazyDeregistrationDelay; + }); + + return services; + } + + public static ClusterConfiguration TryGetClusterConfiguration(this IServiceCollection services) + { + return services + .FirstOrDefault(s => s.ServiceType == typeof(ClusterConfiguration)) + ?.ImplementationInstance as ClusterConfiguration; + } + } +} diff --git a/src/Orleans.Runtime/MembershipService/LegacyMembershipConfigurator.cs b/src/Orleans.Runtime.Legacy/Configuration/LegacyMembershipConfigurator.cs similarity index 85% rename from src/Orleans.Runtime/MembershipService/LegacyMembershipConfigurator.cs rename to src/Orleans.Runtime.Legacy/Configuration/LegacyMembershipConfigurator.cs index fe402551ff..8e7b9b7497 100644 --- a/src/Orleans.Runtime/MembershipService/LegacyMembershipConfigurator.cs +++ b/src/Orleans.Runtime.Legacy/Configuration/LegacyMembershipConfigurator.cs @@ -1,5 +1,4 @@ using System; -using System.Collections.Generic; using System.Linq; using Microsoft.Extensions.DependencyInjection; using Orleans.Hosting; @@ -43,7 +42,14 @@ internal static void ConfigureServices(GlobalConfiguration configuration, IServi } private class LegacyGrainBasedMembershipConfigurator : ILegacyMembershipConfigurator { - public void ConfigureServices(GlobalConfiguration configuration, IServiceCollection services) + public void ConfigureServices(object configuration, IServiceCollection services) + { + GlobalConfiguration config = configuration as GlobalConfiguration; + if (config == null) throw new ArgumentException($"{nameof(GlobalConfiguration)} expected", nameof(configuration)); + ConfigureServices(config, services); + } + + private void ConfigureServices(GlobalConfiguration configuration, IServiceCollection services) { services.UseDevelopmentMembership(options => CopyGlobalGrainBasedMembershipOptions(configuration, options)); } diff --git a/src/Orleans.EventSourcing/LogConsistencyConfigurationExtensions.cs b/src/Orleans.Runtime.Legacy/Configuration/LogConsistencyConfigurationExtensions.cs similarity index 84% rename from src/Orleans.EventSourcing/LogConsistencyConfigurationExtensions.cs rename to src/Orleans.Runtime.Legacy/Configuration/LogConsistencyConfigurationExtensions.cs index 57499815e6..3d73a5ceeb 100644 --- a/src/Orleans.EventSourcing/LogConsistencyConfigurationExtensions.cs +++ b/src/Orleans.Runtime.Legacy/Configuration/LogConsistencyConfigurationExtensions.cs @@ -1,8 +1,5 @@ -using System; +using System; using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace Orleans.Runtime.Configuration { @@ -23,7 +20,7 @@ public static class LogConsistencyConfigurationExtensions { if (string.IsNullOrWhiteSpace(providerName)) throw new ArgumentNullException(nameof(providerName)); - config.Globals.RegisterLogConsistencyProvider(providerName); + config.Globals.RegisterLogConsistencyProvider("Orleans.EventSourcing.LogStorage.LogConsistencyProvider", providerName); } /// @@ -37,7 +34,7 @@ public static class LogConsistencyConfigurationExtensions { if (string.IsNullOrWhiteSpace(providerName)) throw new ArgumentNullException(nameof(providerName)); - config.Globals.RegisterLogConsistencyProvider(providerName); + config.Globals.RegisterLogConsistencyProvider("Orleans.EventSourcing.StateStorage.LogConsistencyProvider", providerName); } /// @@ -58,7 +55,7 @@ public static class LogConsistencyConfigurationExtensions if (primaryCluster != null) properties.Add("PrimaryCluster", primaryCluster); - config.Globals.RegisterLogConsistencyProvider(providerName, properties); + config.Globals.RegisterLogConsistencyProvider("Orleans.EventSourcing.CustomStorage.LogConsistencyProvider", providerName, properties); } } } diff --git a/src/Orleans.Runtime.Legacy/Configuration/PerfCountersConfigurationExtensions.cs b/src/Orleans.Runtime.Legacy/Configuration/PerfCountersConfigurationExtensions.cs new file mode 100644 index 0000000000..c3c4d37286 --- /dev/null +++ b/src/Orleans.Runtime.Legacy/Configuration/PerfCountersConfigurationExtensions.cs @@ -0,0 +1,22 @@ +using System.Linq; + +namespace Orleans.Runtime.Configuration +{ + public static class PerfCountersConfigurationExtensions + { + /// + /// Adds a metrics telemetric consumer provider of type . + /// + /// The cluster configuration object to add the telemetry consumer to. + public static void AddPerfCountersTelemetryConsumer(this ClusterConfiguration config) + { + string typeName = " OrleansTelemetryConsumers.Counters.OrleansPerfCounterTelemetryConsumer"; + string assemblyName = "Orleans.TelemetryConsumers.Counters"; + + foreach (var nodeConfig in config.Overrides.Values.Union(new[] { config.Defaults })) + { + nodeConfig.TelemetryConfiguration.Add(typeName, assemblyName, null); + } + } + } +} diff --git a/src/Orleans.Runtime/Silo/LegacyConfigurationWrapper.cs b/src/Orleans.Runtime.Legacy/Hosting/LegacyConfigurationWrapper.cs similarity index 100% rename from src/Orleans.Runtime/Silo/LegacyConfigurationWrapper.cs rename to src/Orleans.Runtime.Legacy/Hosting/LegacyConfigurationWrapper.cs diff --git a/src/Orleans.Runtime/Silo/SiloHost.cs b/src/Orleans.Runtime.Legacy/Hosting/SiloHost.cs similarity index 70% rename from src/Orleans.Runtime/Silo/SiloHost.cs rename to src/Orleans.Runtime.Legacy/Hosting/SiloHost.cs index 0d8260354d..99b161fe59 100644 --- a/src/Orleans.Runtime/Silo/SiloHost.cs +++ b/src/Orleans.Runtime.Legacy/Hosting/SiloHost.cs @@ -58,19 +58,19 @@ public class SiloHost : private EventWaitHandle startupEvent; private EventWaitHandle shutdownEvent; private bool disposed; - private const string dateFormat = "yyyy-MM-dd-HH.mm.ss.fffZ"; + private const string DateFormat = "yyyy-MM-dd-HH.mm.ss.fffZ"; /// /// Constructor /// /// Name of this silo. public SiloHost(string siloName) { - Name = siloName; + this.Name = siloName; this.loggerProvider = - new FileLoggerProvider($"SiloHost-{siloName}-{DateTime.UtcNow.ToString(dateFormat)}.log"); + new FileLoggerProvider($"SiloHost-{siloName}-{DateTime.UtcNow.ToString(DateFormat)}.log"); this.logger = this.loggerProvider.CreateLogger(this.GetType().FullName); - Type = Silo.SiloType.Secondary; // Default - IsStarted = false; + this.Type = Silo.SiloType.Secondary; // Default + this.IsStarted = false; } /// Constructor @@ -87,9 +87,9 @@ public SiloHost(string siloName, ClusterConfiguration config) : this(siloName) public SiloHost(string siloName, FileInfo configFile) : this(siloName) { - ConfigFileName = configFile.FullName; + this.ConfigFileName = configFile.FullName; var config = new ClusterConfiguration(); - config.LoadFromFile(ConfigFileName); + config.LoadFromFile(this.ConfigFileName); SetSiloConfig(config); } @@ -100,31 +100,31 @@ public void InitializeOrleansSilo() { try { - if (!ConfigLoaded) LoadOrleansConfig(); + if (!this.ConfigLoaded) LoadOrleansConfig(); var builder = new SiloHostBuilder() - .ConfigureSiloName(Name) - .UseConfiguration(Config) + .ConfigureSiloName(this.Name) + .UseConfiguration(this.Config) .ConfigureApplicationParts(parts => parts .AddFromAppDomain() .AddFromApplicationBaseDirectory()); - if (!string.IsNullOrWhiteSpace(Config.Defaults.StartupTypeName)) + if (!string.IsNullOrWhiteSpace(this.Config.Defaults.StartupTypeName)) { builder.UseServiceProviderFactory(services => - StartupBuilder.ConfigureStartup(Config.Defaults.StartupTypeName, services)); + StartupBuilder.ConfigureStartup(this.Config.Defaults.StartupTypeName, services)); } var host = builder.Build(); - orleans = host.Services.GetRequiredService(); + this.orleans = host.Services.GetRequiredService(); var localConfig = host.Services.GetRequiredService(); - logger.Info(ErrorCode.Runtime_Error_100288, "Successfully initialized Orleans silo '{0}'.", orleans.Name); + this.logger.Info(ErrorCode.Runtime_Error_100288, "Successfully initialized Orleans silo '{0}'.", this.orleans.Name); } catch (Exception exc) { ReportStartupError(exc); - orleans = null; + this.orleans = null; } } @@ -147,72 +147,72 @@ public bool StartOrleansSilo(bool catchExceptions = true) if (string.IsNullOrEmpty(Thread.CurrentThread.Name)) Thread.CurrentThread.Name = this.GetType().Name; - if (orleans != null) + if (this.orleans != null) { - var shutdownEventName = Config.Defaults.SiloShutdownEventName ?? Name + "-Shutdown"; + var shutdownEventName = this.Config.Defaults.SiloShutdownEventName ?? this.Name + "-Shutdown"; bool createdNew; try { - logger.Info(ErrorCode.SiloShutdownEventName, "Silo shutdown event name: {0}", shutdownEventName); - shutdownEvent = new EventWaitHandle(false, EventResetMode.ManualReset, shutdownEventName, out createdNew); + this.logger.Info(ErrorCode.SiloShutdownEventName, "Silo shutdown event name: {0}", shutdownEventName); + this.shutdownEvent = new EventWaitHandle(false, EventResetMode.ManualReset, shutdownEventName, out createdNew); if (!createdNew) { - logger.Info(ErrorCode.SiloShutdownEventOpened, "Opened existing shutdown event. Setting the event {0}", shutdownEventName); + this.logger.Info(ErrorCode.SiloShutdownEventOpened, "Opened existing shutdown event. Setting the event {0}", shutdownEventName); } else { - logger.Info(ErrorCode.SiloShutdownEventCreated, "Created and set shutdown event {0}", shutdownEventName); + this.logger.Info(ErrorCode.SiloShutdownEventCreated, "Created and set shutdown event {0}", shutdownEventName); } } catch (PlatformNotSupportedException exc) { - logger.Info(ErrorCode.SiloShutdownEventFailure, "Unable to create SiloShutdownEvent: {0}", exc.ToString()); + this.logger.Info(ErrorCode.SiloShutdownEventFailure, "Unable to create SiloShutdownEvent: {0}", exc.ToString()); } // Start silo - orleans.Start(); + this.orleans.Start(); // Wait for the shutdown event, and trigger a graceful shutdown if we receive it. - if (shutdownEvent != null) + if (this.shutdownEvent != null) { var shutdownThread = new Thread(o => { - shutdownEvent.WaitOne(); - logger.Info(ErrorCode.SiloShutdownEventReceived, "Received a shutdown event. Starting graceful shutdown."); - orleans.Shutdown(); + this.shutdownEvent.WaitOne(); + this.logger.Info(ErrorCode.SiloShutdownEventReceived, "Received a shutdown event. Starting graceful shutdown."); + this.orleans.Shutdown(); }) { IsBackground = true, Name = "SiloShutdownMonitor" }; - shutdownThread.Start(); + shutdownThread.Start(); } try { - var startupEventName = Name; - logger.Info(ErrorCode.SiloStartupEventName, "Silo startup event name: {0}", startupEventName); + var startupEventName = this.Name; + this.logger.Info(ErrorCode.SiloStartupEventName, "Silo startup event name: {0}", startupEventName); - startupEvent = new EventWaitHandle(true, EventResetMode.ManualReset, startupEventName, out createdNew); + this.startupEvent = new EventWaitHandle(true, EventResetMode.ManualReset, startupEventName, out createdNew); if (!createdNew) { - logger.Info(ErrorCode.SiloStartupEventOpened, "Opened existing startup event. Setting the event {0}", startupEventName); - startupEvent.Set(); + this.logger.Info(ErrorCode.SiloStartupEventOpened, "Opened existing startup event. Setting the event {0}", startupEventName); + this.startupEvent.Set(); } else { - logger.Info(ErrorCode.SiloStartupEventCreated, "Created and set startup event {0}", startupEventName); + this.logger.Info(ErrorCode.SiloStartupEventCreated, "Created and set startup event {0}", startupEventName); } } catch (PlatformNotSupportedException exc) { - logger.Info(ErrorCode.SiloStartupEventFailure, "Unable to create SiloStartupEvent: {0}", exc.ToString()); + this.logger.Info(ErrorCode.SiloStartupEventFailure, "Unable to create SiloStartupEvent: {0}", exc.ToString()); } - logger.Info(ErrorCode.SiloStarted, "Silo {0} started successfully", Name); - IsStarted = true; + this.logger.Info(ErrorCode.SiloStarted, "Silo {0} started successfully", this.Name); + this.IsStarted = true; } else { @@ -224,8 +224,8 @@ public bool StartOrleansSilo(bool catchExceptions = true) if (catchExceptions) { ReportStartupError(exc); - orleans = null; - IsStarted = false; + this.orleans = null; + this.IsStarted = false; return false; } else @@ -240,8 +240,8 @@ public bool StartOrleansSilo(bool catchExceptions = true) /// public void StopOrleansSilo() { - IsStarted = false; - if (orleans != null) orleans.Stop(); + this.IsStarted = false; + if (this.orleans != null) this.orleans.Stop(); } /// @@ -249,8 +249,8 @@ public void StopOrleansSilo() /// public void ShutdownOrleansSilo() { - IsStarted = false; - if (orleans != null) orleans.Shutdown(); + this.IsStarted = false; + if (this.orleans != null) this.orleans.Shutdown(); } /// @@ -261,14 +261,14 @@ public void ShutdownOrleansSilo() /// public Task ShutdownOrleansSiloAsync(int millisecondsTimeout, CancellationToken cancellationToken) { - if (orleans == null || !IsStarted) + if (this.orleans == null || !this.IsStarted) return Task.CompletedTask; - IsStarted = false; + this.IsStarted = false; var shutdownThread = new Thread(o => { - orleans.Shutdown(); + this.orleans.Shutdown(); }) { IsBackground = true, @@ -331,7 +331,7 @@ public async Task WaitForOrleansSiloShutdownAsync(int millisecondsTimeout, { var tcs = new TaskCompletionSource(); registeredHandle = ThreadPool.RegisterWaitForSingleObject( - orleans.SiloTerminatedEvent, + this.orleans.SiloTerminatedEvent, (state, timedOut) => ((TaskCompletionSource)state).TrySetResult(!timedOut), tcs, millisecondsTimeout, @@ -358,11 +358,11 @@ public async Task WaitForOrleansSiloShutdownAsync(int millisecondsTimeout, /// Azure connection string to use the silo system data. public void SetDeploymentId(string clusterId, string connectionString) { - logger.Info(ErrorCode.SiloSetDeploymentId, "Setting Deployment Id to {0} and data connection string to {1}", + this.logger.Info(ErrorCode.SiloSetDeploymentId, "Setting Deployment Id to {0} and data connection string to {1}", clusterId, ConfigUtilities.RedactConnectionStringInfo(connectionString)); - Config.Globals.ClusterId = clusterId; - Config.Globals.DataConnectionString = connectionString; + this.Config.Globals.ClusterId = clusterId; + this.Config.Globals.DataConnectionString = connectionString; } /// @@ -374,10 +374,10 @@ public void SetDeploymentId(string clusterId, string connectionString) /// Generation number for this silo. public void SetSiloEndpoint(IPEndPoint endpoint, int generation) { - logger.Info(ErrorCode.SiloSetSiloEndpoint, "Setting silo endpoint address to {0}:{1}", endpoint, generation); - NodeConfig.HostNameOrIPAddress = endpoint.Address.ToString(); - NodeConfig.Port = endpoint.Port; - NodeConfig.Generation = generation; + this.logger.Info(ErrorCode.SiloSetSiloEndpoint, "Setting silo endpoint address to {0}:{1}", endpoint, generation); + this.NodeConfig.HostNameOrIPAddress = endpoint.Address.ToString(); + this.NodeConfig.Port = endpoint.Port; + this.NodeConfig.Generation = generation; } /// @@ -386,8 +386,8 @@ public void SetSiloEndpoint(IPEndPoint endpoint, int generation) /// IP address of the gateway socket connection. public void SetProxyEndpoint(IPEndPoint endpoint) { - logger.Info(ErrorCode.SiloSetProxyEndpoint, "Setting silo proxy endpoint address to {0}", endpoint); - NodeConfig.ProxyGatewayEndpoint = endpoint; + this.logger.Info(ErrorCode.SiloSetProxyEndpoint, "Setting silo proxy endpoint address to {0}", endpoint); + this.NodeConfig.ProxyGatewayEndpoint = endpoint; } /// @@ -396,9 +396,9 @@ public void SetProxyEndpoint(IPEndPoint endpoint) /// IP address of the inter-silo connection socket on the seed node silo. public void SetSeedNodeEndpoint(IPEndPoint endpoint) { - logger.Info(ErrorCode.SiloSetSeedNode, "Adding seed node address={0} port={1}", endpoint.Address, endpoint.Port); - Config.Globals.SeedNodes.Clear(); - Config.Globals.SeedNodes.Add(endpoint); + this.logger.Info(ErrorCode.SiloSetSeedNode, "Adding seed node address={0} port={1}", endpoint.Address, endpoint.Port); + this.Config.Globals.SeedNodes.Clear(); + this.Config.Globals.SeedNodes.Add(endpoint); } /// @@ -408,11 +408,11 @@ public void SetSeedNodeEndpoint(IPEndPoint endpoint) public void SetSeedNodeEndpoints(IPEndPoint[] endpoints) { // Add all silos as seed nodes - Config.Globals.SeedNodes.Clear(); + this.Config.Globals.SeedNodes.Clear(); foreach (IPEndPoint endpoint in endpoints) { - logger.Info(ErrorCode.SiloAddSeedNode, "Adding seed node address={0} port={1}", endpoint.Address, endpoint.Port); - Config.Globals.SeedNodes.Add(endpoint); + this.logger.Info(ErrorCode.SiloAddSeedNode, "Adding seed node address={0} port={1}", endpoint.Address, endpoint.Port); + this.Config.Globals.SeedNodes.Add(endpoint); } } @@ -424,8 +424,8 @@ public void SetSeedNodeEndpoints(IPEndPoint[] endpoints) /// The IP address for the inter-silo connection socket on the Primary silo. public void SetPrimaryNodeEndpoint(IPEndPoint endpoint) { - logger.Info(ErrorCode.SiloSetPrimaryNode, "Setting primary node address={0} port={1}", endpoint.Address, endpoint.Port); - Config.PrimaryNode = endpoint; + this.logger.Info(ErrorCode.SiloSetPrimaryNode, "Setting primary node address={0} port={1}", endpoint.Address, endpoint.Port); + this.Config.PrimaryNode = endpoint; } /// @@ -434,8 +434,8 @@ public void SetPrimaryNodeEndpoint(IPEndPoint endpoint) /// Type of this silo. public void SetSiloType(Silo.SiloType siloType) { - logger.Info(ErrorCode.SiloSetSiloType, "Setting silo type {0}", siloType); - Type = siloType; + this.logger.Info(ErrorCode.SiloSetSiloType, "Setting silo type {0}", siloType); + this.Type = siloType; } /// @@ -444,8 +444,8 @@ public void SetSiloType(Silo.SiloType siloType) /// Liveness type for this silo public void SetSiloLivenessType(GlobalConfiguration.LivenessProviderType livenessType) { - logger.Info(ErrorCode.SetSiloLivenessType, "Setting silo Liveness Provider Type={0}", livenessType); - Config.Globals.LivenessType = livenessType; + this.logger.Info(ErrorCode.SetSiloLivenessType, "Setting silo Liveness Provider Type={0}", livenessType); + this.Config.Globals.LivenessType = livenessType; } /// @@ -454,8 +454,8 @@ public void SetSiloLivenessType(GlobalConfiguration.LivenessProviderType livenes /// Reminder service type for this silo public void SetReminderServiceType(GlobalConfiguration.ReminderServiceProviderType reminderType) { - logger.Info(ErrorCode.SetSiloLivenessType, "Setting silo Reminder Service Provider Type={0}", reminderType); - Config.Globals.SetReminderServiceType(reminderType); + this.logger.Info(ErrorCode.SetSiloLivenessType, "Setting silo Reminder Service Provider Type={0}", reminderType); + this.Config.Globals.SetReminderServiceType(reminderType); } /// @@ -464,8 +464,8 @@ public void SetReminderServiceType(GlobalConfiguration.ReminderServiceProviderTy /// The expected deployment size. public void SetExpectedClusterSize(int size) { - logger.Info(ErrorCode.SetSiloLivenessType, "Setting Expected Cluster Size to={0}", size); - Config.Globals.ExpectedClusterSize = size; + this.logger.Info(ErrorCode.SetSiloLivenessType, "Setting Expected Cluster Size to={0}", size); + this.Config.Globals.ExpectedClusterSize = size; } /// @@ -479,17 +479,17 @@ public void SetExpectedClusterSize(int size) /// Exception which caused the silo startup issue. public void ReportStartupError(Exception exc) { - if (string.IsNullOrWhiteSpace(Name)) - Name = "Silo"; + if (string.IsNullOrWhiteSpace(this.Name)) + this.Name = "Silo"; - var errMsg = "ERROR starting Orleans silo name=" + Name + " Exception=" + LogFormatter.PrintException(exc); - if (logger != null) logger.Error(ErrorCode.Runtime_Error_100105, errMsg, exc); + var errMsg = "ERROR starting Orleans silo name=" + this.Name + " Exception=" + LogFormatter.PrintException(exc); + if (this.logger != null) this.logger.Error(ErrorCode.Runtime_Error_100105, errMsg, exc); // Dump Startup error to a log file var now = DateTime.UtcNow; - - var dateString = now.ToString(dateFormat, CultureInfo.InvariantCulture); - var startupLog = Name + "-StartupError-" + dateString + ".txt"; + + var dateString = now.ToString(DateFormat, CultureInfo.InvariantCulture); + var startupLog = this.Name + "-StartupError-" + dateString + ".txt"; try { @@ -497,7 +497,7 @@ public void ReportStartupError(Exception exc) } catch (Exception exc2) { - if (logger != null) logger.Error(ErrorCode.Runtime_Error_100106, "Error writing log file " + startupLog, exc2); + if (this.logger != null) this.logger.Error(ErrorCode.Runtime_Error_100106, "Error writing log file " + startupLog, exc2); } } @@ -506,16 +506,16 @@ public void ReportStartupError(Exception exc) /// public void LoadOrleansConfig() { - if (ConfigLoaded) return; + if (this.ConfigLoaded) return; - var config = Config ?? new ClusterConfiguration(); + var config = this.Config ?? new ClusterConfiguration(); try { - if (ConfigFileName == null) + if (this.ConfigFileName == null) config.StandardLoad(); else - config.LoadFromFile(ConfigFileName); + config.LoadFromFile(this.ConfigFileName); } catch (Exception ex) { @@ -531,18 +531,18 @@ public void LoadOrleansConfig() /// Configuration data for this silo and cluster. private void SetSiloConfig(ClusterConfiguration config) { - Config = config; + this.Config = config; - if (!String.IsNullOrEmpty(DeploymentId)) - Config.Globals.ClusterId = DeploymentId; + if (!string.IsNullOrEmpty(this.DeploymentId)) + this.Config.Globals.ClusterId = this.DeploymentId; - if (string.IsNullOrWhiteSpace(Name)) + if (string.IsNullOrWhiteSpace(this.Name)) throw new ArgumentException("SiloName not defined - cannot initialize config"); - NodeConfig = Config.GetOrCreateNodeConfigurationForSilo(Name); - Type = NodeConfig.IsPrimaryNode ? Silo.SiloType.Primary : Silo.SiloType.Secondary; + this.NodeConfig = this.Config.GetOrCreateNodeConfigurationForSilo(this.Name); + this.Type = this.NodeConfig.IsPrimaryNode ? Silo.SiloType.Primary : Silo.SiloType.Secondary; - ConfigLoaded = true; + this.ConfigLoaded = true; } /// @@ -556,19 +556,19 @@ private void SetSiloConfig(ClusterConfiguration config) /// private void WaitForOrleansSiloShutdownImpl(CancellationToken? cancellationToken = null) { - if (!IsStarted) + if (!this.IsStarted) throw new InvalidOperationException("Cannot wait for silo " + this.Name + " since it was not started successfully previously."); - if (startupEvent != null) - startupEvent.Reset(); - - if (orleans != null) + if (this.startupEvent != null) + this.startupEvent.Reset(); + + if (this.orleans != null) { // Intercept cancellation to initiate silo stop if (cancellationToken.HasValue) - cancellationToken.Value.Register(HandleExternalCancellation); + cancellationToken.Value.Register(this.HandleExternalCancellation); - orleans.SiloTerminatedEvent.WaitOne(); + this.orleans.SiloTerminatedEvent.WaitOne(); } else throw new InvalidOperationException("Cannot wait for silo " + this.Name + " due to prior initialization error"); @@ -580,7 +580,7 @@ private void WaitForOrleansSiloShutdownImpl(CancellationToken? cancellationToken private void HandleExternalCancellation() { // Try to perform gracefull shutdown of Silo when we a cancellation request has been made - logger.Info(ErrorCode.SiloStopping, "External cancellation triggered, starting to shutdown silo."); + this.logger.Info(ErrorCode.SiloStopping, "External cancellation triggered, starting to shutdown silo."); ShutdownOrleansSilo(); } @@ -597,21 +597,21 @@ public void Dispose() /// protected virtual void Dispose(bool disposing) { - if (!disposed) + if (!this.disposed) { if (disposing) { this.loggerProvider?.Dispose(); this.loggerProvider = null; - if (startupEvent != null) + if (this.startupEvent != null) { - startupEvent.Dispose(); - startupEvent = null; + this.startupEvent.Dispose(); + this.startupEvent = null; } this.IsStarted = false; } } - disposed = true; + this.disposed = true; } } } diff --git a/src/Orleans.Runtime.Legacy/Orleans.Runtime.Legacy.csproj b/src/Orleans.Runtime.Legacy/Orleans.Runtime.Legacy.csproj index ca81428125..a0f869aaa3 100644 --- a/src/Orleans.Runtime.Legacy/Orleans.Runtime.Legacy.csproj +++ b/src/Orleans.Runtime.Legacy/Orleans.Runtime.Legacy.csproj @@ -11,12 +11,6 @@ Orleans.Runtime.Legacy - - - - - - diff --git a/src/Orleans.Runtime/Catalog/ActivationCollector.cs b/src/Orleans.Runtime/Catalog/ActivationCollector.cs index b25ad964f3..3a4145d1e8 100644 --- a/src/Orleans.Runtime/Catalog/ActivationCollector.cs +++ b/src/Orleans.Runtime/Catalog/ActivationCollector.cs @@ -4,6 +4,8 @@ using System.Collections.Generic; using System.Linq; using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Options; +using Orleans.Hosting; using Orleans.Runtime.Configuration; namespace Orleans.Runtime @@ -22,15 +24,16 @@ internal class ActivationCollector : IActivationCollector private static readonly List nothing = new List { Capacity = 0 }; private readonly ILogger logger; - public ActivationCollector(ClusterConfiguration config, ILoggerFactory loggerFactory) + public ActivationCollector(IOptions options, ILoggerFactory loggerFactory) { - if (TimeSpan.Zero == config.Globals.CollectionQuantum) + if (TimeSpan.Zero == options.Value.CollectionQuantum) { throw new ArgumentException("Globals.CollectionQuantum cannot be zero.", "config"); } - quantum = config.Globals.CollectionQuantum; - shortestAgeLimit = config.Globals.Application.ShortestCollectionAgeLimit; + quantum = options.Value.CollectionQuantum; + shortestAgeLimit = TimeSpan.FromTicks(options.Value.ClassSpecificCollectionAge.Values + .Aggregate(options.Value.CollectionAge.Ticks, (a,v) => Math.Min(a,v.Ticks))); buckets = new ConcurrentDictionary(); nextTicket = MakeTicketFromDateTime(DateTime.UtcNow); nextTicketLock = new object(); diff --git a/src/Orleans.Runtime/Catalog/ActivationData.cs b/src/Orleans.Runtime/Catalog/ActivationData.cs index cc8b624514..4e0caaa88b 100644 --- a/src/Orleans.Runtime/Catalog/ActivationData.cs +++ b/src/Orleans.Runtime/Catalog/ActivationData.cs @@ -5,14 +5,16 @@ using System.Text; using System.Threading; using System.Threading.Tasks; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Options; using Orleans.CodeGeneration; using Orleans.Core; using Orleans.GrainDirectory; using Orleans.Runtime.Configuration; using Orleans.Runtime.Scheduler; using Orleans.Storage; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Logging; +using Orleans.Hosting; namespace Orleans.Runtime { @@ -164,14 +166,11 @@ internal class GrainActivationContextFactory // This is the maximum amount of time we expect a request to continue processing private readonly TimeSpan maxRequestProcessingTime; private readonly TimeSpan maxWarningRequestProcessingTime; - private readonly NodeConfiguration nodeConfiguration; + private readonly SiloMessagingOptions messagingOptions; public readonly TimeSpan CollectionAgeLimit; private readonly ILogger logger; private IGrainMethodInvoker lastInvoker; private IServiceScope serviceScope; - - // This is the maximum number of enqueued request messages for a single activation before we write a warning log or reject new requests. - private LimitValue maxEnqueuedRequestsLimit; private HashSet timers; public ActivationData( @@ -181,7 +180,7 @@ internal class GrainActivationContextFactory IMultiClusterRegistrationStrategy registrationStrategy, IActivationCollector collector, TimeSpan ageLimit, - NodeConfiguration nodeConfiguration, + IOptions messagingOptions, TimeSpan maxWarningRequestProcessingTime, TimeSpan maxRequestProcessingTime, IRuntimeClient runtimeClient, @@ -195,7 +194,7 @@ internal class GrainActivationContextFactory this.lifecycle = new GrainLifecycle(loggerFactory); this.maxRequestProcessingTime = maxRequestProcessingTime; this.maxWarningRequestProcessingTime = maxWarningRequestProcessingTime; - this.nodeConfiguration = nodeConfiguration; + this.messagingOptions = messagingOptions.Value; ResetKeepAliveRequest(); Address = addr; State = ActivationState.Create; @@ -617,10 +616,15 @@ public EnqueueMessageResult EnqueueMessage(Message message) /// Returns LimitExceededException if overloaded, otherwise nullc> public LimitExceededException CheckOverloaded(ILogger log) { - LimitValue limitValue = GetMaxEnqueuedRequestLimit(); - - int maxRequestsHardLimit = limitValue.HardLimitThreshold; - int maxRequestsSoftLimit = limitValue.SoftLimitThreshold; + string limitName = LimitNames.LIMIT_MAX_ENQUEUED_REQUESTS; + int maxRequestsHardLimit = this.messagingOptions.MaxEnqueuedRequestsHardLimit; + int maxRequestsSoftLimit = this.messagingOptions.MaxEnqueuedRequestsSoftLimit; + if (GrainInstanceType != null && CodeGeneration.GrainInterfaceUtils.IsStatelessWorker(GrainInstanceType.GetTypeInfo())) + { + limitName = LimitNames.LIMIT_MAX_ENQUEUED_REQUESTS_STATELESS_WORKER; + maxRequestsHardLimit = this.messagingOptions.MaxEnqueuedRequestsHardLimit_StatelessWorker; + maxRequestsSoftLimit = this.messagingOptions.MaxEnqueuedRequestsSoftLimit_StatelessWorker; + } if (maxRequestsHardLimit <= 0 && maxRequestsSoftLimit <= 0) return null; // No limits are set @@ -632,7 +636,7 @@ public LimitExceededException CheckOverloaded(ILogger log) String.Format("Overload - {0} enqueued requests for activation {1}, exceeding hard limit rejection threshold of {2}", count, this, maxRequestsHardLimit)); - return new LimitExceededException(limitValue.Name, count, maxRequestsHardLimit, this.ToString()); + return new LimitExceededException(limitName, count, maxRequestsHardLimit, this.ToString()); } if (maxRequestsSoftLimit > 0 && count > maxRequestsSoftLimit) // Soft limit { @@ -656,21 +660,6 @@ internal int GetRequestCount() } } - private LimitValue GetMaxEnqueuedRequestLimit() - { - if (maxEnqueuedRequestsLimit != null) return maxEnqueuedRequestsLimit; - if (GrainInstanceType != null) - { - string limitName = CodeGeneration.GrainInterfaceUtils.IsStatelessWorker(GrainInstanceType.GetTypeInfo()) - ? LimitNames.LIMIT_MAX_ENQUEUED_REQUESTS_STATELESS_WORKER - : LimitNames.LIMIT_MAX_ENQUEUED_REQUESTS; - maxEnqueuedRequestsLimit = nodeConfiguration.LimitManager.GetLimit(limitName); // Cache for next time - return maxEnqueuedRequestsLimit; - } - - return nodeConfiguration.LimitManager.GetLimit(LimitNames.LIMIT_MAX_ENQUEUED_REQUESTS); - } - public Message PeekNextWaitingMessage() { if (waiting != null && waiting.Count > 0) return waiting[0]; diff --git a/src/Orleans.Runtime/Catalog/Catalog.cs b/src/Orleans.Runtime/Catalog/Catalog.cs index 8147fc8ef8..c5e0380975 100644 --- a/src/Orleans.Runtime/Catalog/Catalog.cs +++ b/src/Orleans.Runtime/Catalog/Catalog.cs @@ -20,6 +20,7 @@ using System.Runtime.ExceptionServices; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; +using Orleans.Hosting; namespace Orleans.Runtime { @@ -82,7 +83,6 @@ public override void GetObjectData(SerializationInfo info, StreamingContext cont private int collectionNumber; private int destroyActivationsNumber; private IDisposable gcTimer; - private readonly GlobalConfiguration config; private readonly string localSiloName; private readonly CounterStatistic activationsCreated; private readonly CounterStatistic activationsDestroyed; @@ -90,21 +90,20 @@ public override void GetObjectData(SerializationInfo info, StreamingContext cont private readonly IntValueStatistic inProcessRequests; private readonly CounterStatistic collectionCounter; private readonly GrainCreator grainCreator; - private readonly NodeConfiguration nodeConfig; private readonly TimeSpan maxRequestProcessingTime; private readonly TimeSpan maxWarningRequestProcessingTime; private readonly SerializationManager serializationManager; private readonly CachedVersionSelectorManager versionSelectorManager; private readonly ILoggerFactory loggerFactory; + private readonly IOptions collectionOptions; + private readonly IOptions messagingOptions; public Catalog( ILocalSiloDetails localSiloDetails, ILocalGrainDirectory grainDirectory, GrainTypeManager typeManager, OrleansTaskScheduler scheduler, ActivationDirectory activationDirectory, - ClusterConfiguration config, GrainCreator grainCreator, - NodeConfiguration nodeConfig, ISiloMessageCenter messageCenter, PlacementDirectorsManager placementDirectorsManager, MessageFactory messageFactory, @@ -113,7 +112,9 @@ public override void GetObjectData(SerializationInfo info, StreamingContext cont IServiceProvider serviceProvider, CachedVersionSelectorManager versionSelectorManager, ILoggerFactory loggerFactory, - IOptions schedulingOptions) + IOptions schedulingOptions, + IOptions collectionOptions, + IOptions messagingOptions) : base(Constants.CatalogId, messageCenter.MyAddress, loggerFactory) { LocalSilo = localSiloDetails.SiloAddress; @@ -126,18 +127,18 @@ public override void GetObjectData(SerializationInfo info, StreamingContext cont collectionNumber = 0; destroyActivationsNumber = 0; this.grainCreator = grainCreator; - this.nodeConfig = nodeConfig; this.serializationManager = serializationManager; this.versionSelectorManager = versionSelectorManager; this.providerRuntime = providerRuntime; this.serviceProvider = serviceProvider; + this.collectionOptions = collectionOptions; + this.messagingOptions = messagingOptions; logger = loggerFactory.CreateLogger(); - this.config = config.Globals; - ActivationCollector = new ActivationCollector(config, loggerFactory); + ActivationCollector = new ActivationCollector(this.collectionOptions, loggerFactory); this.Dispatcher = new Dispatcher(scheduler, messageCenter, this, - config, + this.messagingOptions, placementDirectorsManager, grainDirectory, messageFactory, @@ -147,7 +148,8 @@ public override void GetObjectData(SerializationInfo info, StreamingContext cont schedulingOptions); GC.GetTotalMemory(true); // need to call once w/true to ensure false returns OK value - config.OnConfigChange("Globals/Activation", () => scheduler.RunOrQueueAction(Start, SchedulingContext), false); +// TODO: figure out how to read config change notification from options. - jbragg +// config.OnConfigChange("Globals/Activation", () => scheduler.RunOrQueueAction(Start, SchedulingContext), false); IntValueStatistic.FindOrCreate(StatisticNames.CATALOG_ACTIVATION_COUNT, () => activations.Count); activationsCreated = CounterStatistic.FindOrCreate(StatisticNames.CATALOG_ACTIVATION_CREATED); activationsDestroyed = CounterStatistic.FindOrCreate(StatisticNames.CATALOG_ACTIVATION_DESTROYED); @@ -166,8 +168,8 @@ public override void GetObjectData(SerializationInfo info, StreamingContext cont } return counter; }); - maxWarningRequestProcessingTime = this.config.ResponseTimeout.Multiply(5); - maxRequestProcessingTime = this.config.MaxRequestProcessingTime; + maxWarningRequestProcessingTime = this.messagingOptions.Value.ResponseTimeout.Multiply(5); + maxRequestProcessingTime = this.messagingOptions.Value.MaxRequestProcessingTime; grainDirectory.SetSiloRemovedCatalogCallback(this.OnSiloStatusChange); } @@ -180,7 +182,7 @@ public IList GetCompatibleSilos(PlacementTarget target) { // For test only: if we have silos that are not yet in the Cluster TypeMap, we assume that they are compatible // with the current silo - if (this.config.AssumeHomogenousSilosForTesting) + if (this.messagingOptions.Value.AssumeHomogenousSilosForTesting) return AllActiveSilos; var typeCode = target.GrainIdentity.TypeCode; @@ -476,6 +478,10 @@ public void GetGrainTypeInfo(int typeCode, out string grainClass, out PlacementS if (newPlacement && !SiloStatusOracle.CurrentStatus.IsTerminating()) { + TimeSpan ageLimit = this.collectionOptions.Value.ClassSpecificCollectionAge.TryGetValue(grainType, out TimeSpan limit) + ? limit + : collectionOptions.Value.CollectionAge; + // create a dummy activation that will queue up messages until the real data arrives // We want to do this (RegisterMessageTarget) under the same lock that we tested TryGetActivationData. They both access ActivationDirectory. result = new ActivationData( @@ -483,9 +489,9 @@ public void GetGrainTypeInfo(int typeCode, out string grainClass, out PlacementS genericArguments, placement, activationStrategy, - ActivationCollector, - config.Application.GetCollectionAgeLimit(grainType), - this.nodeConfig, + ActivationCollector, + ageLimit, + this.messagingOptions, this.maxWarningRequestProcessingTime, this.maxRequestProcessingTime, this.RuntimeClient, diff --git a/src/Orleans.Runtime/Core/Dispatcher.cs b/src/Orleans.Runtime/Core/Dispatcher.cs index 3f908ec669..e148fb09f0 100644 --- a/src/Orleans.Runtime/Core/Dispatcher.cs +++ b/src/Orleans.Runtime/Core/Dispatcher.cs @@ -7,6 +7,7 @@ using Microsoft.Extensions.Options; using Orleans.CodeGeneration; using Orleans.GrainDirectory; +using Orleans.Hosting; using Orleans.Runtime.Configuration; using Orleans.Runtime.GrainDirectory; using Orleans.Runtime.Messaging; @@ -24,7 +25,7 @@ internal class Dispatcher private readonly OrleansTaskScheduler scheduler; private readonly Catalog catalog; private readonly ILogger logger; - private readonly ClusterConfiguration config; + private readonly SiloMessagingOptions messagingOptions; private readonly PlacementDirectorsManager placementDirectorsManager; private readonly ILocalGrainDirectory localGrainDirectory; private readonly MessageFactory messagefactory; @@ -36,8 +37,8 @@ internal class Dispatcher internal Dispatcher( OrleansTaskScheduler scheduler, ISiloMessageCenter transport, - Catalog catalog, - ClusterConfiguration config, + Catalog catalog, + IOptions messagingOptions, PlacementDirectorsManager placementDirectorsManager, ILocalGrainDirectory localGrainDirectory, MessageFactory messagefactory, @@ -49,7 +50,7 @@ internal class Dispatcher this.scheduler = scheduler; this.catalog = catalog; Transport = transport; - this.config = config; + this.messagingOptions = messagingOptions.Value; this.invokeWorkItemLogger = loggerFactory.CreateLogger(); this.placementDirectorsManager = placementDirectorsManager; this.localGrainDirectory = localGrainDirectory; @@ -586,7 +587,7 @@ internal void RerouteMessage(Message message) internal bool TryResendMessage(Message message) { - if (!message.MayResend(this.config.Globals.MaxResendCount)) return false; + if (!message.MayResend(this.messagingOptions.MaxResendCount)) return false; message.ResendCount = message.ResendCount + 1; MessagingProcessingStatisticsGroup.OnIgcMessageResend(message); @@ -596,7 +597,7 @@ internal bool TryResendMessage(Message message) internal bool TryForwardMessage(Message message, ActivationAddress forwardingAddress) { - if (!message.MayForward(this.config.Globals)) return false; + if (!message.MayForward(this.messagingOptions)) return false; message.ForwardCount = message.ForwardCount + 1; MessagingProcessingStatisticsGroup.OnIgcMessageForwared(message); diff --git a/src/Orleans.Runtime/Core/InsideRuntimeClient.cs b/src/Orleans.Runtime/Core/InsideRuntimeClient.cs index c52b65c6d7..faf14115ab 100644 --- a/src/Orleans.Runtime/Core/InsideRuntimeClient.cs +++ b/src/Orleans.Runtime/Core/InsideRuntimeClient.cs @@ -55,7 +55,6 @@ internal class InsideRuntimeClient : ISiloRuntimeClient, ILifecycleParticipant(); callbacks = new ConcurrentDictionary(); - Config = config; - config.OnConfigChange("Globals/Message", () => ResponseTimeout = Config.Globals.ResponseTimeout); + this.ResponseTimeout = messagingOptions.Value.ResponseTimeout; +// config.OnConfigChange("Globals/Message", () => ResponseTimeout = Config.Globals.ResponseTimeout); this.typeManager = typeManager; this.messageFactory = messageFactory; this.transactionAgent = new Lazy(() => transactionAgent()); @@ -105,8 +104,6 @@ internal class InsideRuntimeClient : ISiloRuntimeClient, ILifecycleParticipant GrainCallFilters if (context == null && !oneWay) logger.Warn(ErrorCode.IGC_SendRequest_NullContext, "Null context {0}: {1}", message, Utils.GetStackTrace()); - if (message.IsExpirableMessage(Config.Globals.DropExpiredMessages)) + if (message.IsExpirableMessage(this.messagingOptions.DropExpiredMessages)) message.TimeToLive = ResponseTimeout; if (!oneWay) diff --git a/src/Orleans.Runtime/Core/ManagementGrain.cs b/src/Orleans.Runtime/Core/ManagementGrain.cs index 7479efdfdd..d3685b5f12 100644 --- a/src/Orleans.Runtime/Core/ManagementGrain.cs +++ b/src/Orleans.Runtime/Core/ManagementGrain.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using System.IO; using System.Linq; using System.Threading.Tasks; using System.Xml; @@ -9,7 +8,6 @@ using Microsoft.Extensions.Options; using Orleans.Hosting; using Orleans.MultiCluster; -using Orleans.Runtime.Configuration; using Orleans.Runtime.MembershipService; using Orleans.Runtime.MultiClusterNetwork; using Orleans.Versions; @@ -177,43 +175,6 @@ public async Task GetGrainActivationCount(GrainReference grainReference) return tasks.Select(s => s.Result).Select(r => r.LocalActivations.Count).Sum(); } - public async Task UpdateConfiguration(SiloAddress[] hostIds, Dictionary configuration, Dictionary tracing) - { - var global = new[] { "Globals/", "/Globals/", "OrleansConfiguration/Globals/", "/OrleansConfiguration/Globals/" }; - if (hostIds != null && configuration.Keys.Any(k => global.Any(k.StartsWith))) - throw new ArgumentException("Must update global configuration settings on all silos"); - - var silos = GetSiloAddresses(hostIds); - if (silos.Length == 0) return; - - var document = XPathValuesToXml(configuration); - if (tracing != null) - { - AddXPathValue(document, new[] { "OrleansConfiguration", "Defaults", "Tracing" }, null); - var parent = document["OrleansConfiguration"]["Defaults"]["Tracing"]; - foreach (var trace in tracing) - { - var child = document.CreateElement("TraceLevelOverride"); - child.SetAttribute("LogPrefix", trace.Key); - child.SetAttribute("TraceLevel", trace.Value); - parent.AppendChild(child); - } - } - - using(var sw = new StringWriter()) - { - using(var xw = XmlWriter.Create(sw)) - { - document.WriteTo(xw); - xw.Flush(); - var xml = sw.ToString(); - // do first one, then all the rest to avoid spamming all the silos in case of a parameter error - await GetSiloControlReference(silos[0]).UpdateConfiguration(xml); - await Task.WhenAll(silos.Skip(1).Select(s => GetSiloControlReference(s).UpdateConfiguration(xml))); - } - } - } - public async Task GetActiveGrainTypes(SiloAddress[] hostsIds=null) { if (hostsIds == null) diff --git a/src/Orleans.Runtime/Counters/SiloPerformanceMetrics.cs b/src/Orleans.Runtime/Counters/SiloPerformanceMetrics.cs index 0384e828ae..1e647b932b 100644 --- a/src/Orleans.Runtime/Counters/SiloPerformanceMetrics.cs +++ b/src/Orleans.Runtime/Counters/SiloPerformanceMetrics.cs @@ -1,7 +1,8 @@ using System; using System.Threading.Tasks; using Microsoft.Extensions.Logging; -using Orleans.Runtime.Configuration; +using Microsoft.Extensions.Options; +using Orleans.Hosting; using Orleans.Runtime.Scheduler; using Orleans.Statistics; @@ -14,7 +15,7 @@ internal class SiloPerformanceMetrics : ISiloPerformanceMetrics, IDisposable internal ActivationCollector ActivationCollector { get; set; } internal IMessageCenter MessageCenter { get; set; } internal ISiloMetricsDataPublisher MetricsDataPublisher { get; set; } - internal NodeConfiguration NodeConfig { get; set; } + internal SiloStatisticsOptions statisticsOptions { get; set; } private readonly ILoggerFactory loggerFactory; private TimeSpan reportFrequency; @@ -29,8 +30,8 @@ internal class SiloPerformanceMetrics : ISiloPerformanceMetrics, IDisposable internal SiloPerformanceMetrics( IHostEnvironmentStatistics hostEnvironmentStatistics, IAppEnvironmentStatistics appEnvironmentStatistics, - ILoggerFactory loggerFactory, - NodeConfiguration cfg = null) + ILoggerFactory loggerFactory, + IOptions statisticsOptions) { this.loggerFactory = loggerFactory; this.hostEnvironmentStatistics = hostEnvironmentStatistics; @@ -39,7 +40,7 @@ internal class SiloPerformanceMetrics : ISiloPerformanceMetrics, IDisposable overloadLatched = false; overloadValue = false; this.logger = loggerFactory.CreateLogger(); - NodeConfig = cfg ?? new NodeConfiguration(); + this.statisticsOptions = statisticsOptions.Value; StringValueStatistic.FindOrCreate(StatisticNames.RUNTIME_IS_OVERLOADED, () => IsOverloaded.ToString()); } @@ -90,7 +91,7 @@ public void UnlatchCpuUsage() public bool IsOverloaded { - get { return overloadLatched ? overloadValue : (NodeConfig.LoadSheddingEnabled && (CpuUsage > NodeConfig.LoadSheddingLimit)); } + get { return this.overloadLatched ? overloadValue : (this.statisticsOptions.LoadSheddingEnabled && (CpuUsage > this.statisticsOptions.LoadSheddingLimit)); } } public long RequestQueueLength diff --git a/src/Orleans.Runtime/Counters/SiloStatisticsManager.cs b/src/Orleans.Runtime/Counters/SiloStatisticsManager.cs index 0eab64ab15..d2b3cbeb7a 100644 --- a/src/Orleans.Runtime/Counters/SiloStatisticsManager.cs +++ b/src/Orleans.Runtime/Counters/SiloStatisticsManager.cs @@ -1,10 +1,8 @@ -using System; using System.Threading.Tasks; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using Microsoft.Extensions.DependencyInjection; using Orleans.Hosting; -using Orleans.Runtime.Configuration; using Orleans.Serialization; using Orleans.Statistics; @@ -18,18 +16,21 @@ internal class SiloStatisticsManager internal SiloPerformanceMetrics MetricsTable; private readonly ILogger logger; private readonly ILocalSiloDetails siloDetails; + private readonly StorageOptions storageOptions; public SiloStatisticsManager( - NodeConfiguration nodeConfiguration, + IOptions statisticsOptions, + IOptions azureStorageOptions, ILocalSiloDetails siloDetails, SerializationManager serializationManager, ITelemetryProducer telemetryProducer, IHostEnvironmentStatistics hostEnvironmentStatistics, IAppEnvironmentStatistics appEnvironmentStatistics, ILoggerFactory loggerFactory, - IOptions messagingOptions) + IOptions messagingOptions) { this.siloDetails = siloDetails; + this.storageOptions = azureStorageOptions.Value; MessagingStatisticsGroup.Init(true); MessagingProcessingStatisticsGroup.Init(); NetworkingStatisticsGroup.Init(true); @@ -39,9 +40,9 @@ internal class SiloStatisticsManager TransactionsStatisticsGroup.Init(); this.logger = loggerFactory.CreateLogger(); this.hostEnvironmentStatistics = hostEnvironmentStatistics; - this.logStatistics = new LogStatistics(nodeConfiguration.StatisticsLogWriteInterval, true, serializationManager, loggerFactory); - this.MetricsTable = new SiloPerformanceMetrics(this.hostEnvironmentStatistics, appEnvironmentStatistics, loggerFactory, nodeConfiguration); - this.countersPublisher = new CountersStatistics(nodeConfiguration.StatisticsPerfCountersWriteInterval, telemetryProducer, loggerFactory); + this.logStatistics = new LogStatistics(statisticsOptions.Value.LogWriteInterval, true, serializationManager, loggerFactory); + this.MetricsTable = new SiloPerformanceMetrics(this.hostEnvironmentStatistics, appEnvironmentStatistics, loggerFactory, statisticsOptions); + this.countersPublisher = new CountersStatistics(statisticsOptions.Value.PerfCountersWriteInterval, telemetryProducer, loggerFactory); } internal async Task SetSiloMetricsTableDataManager(Silo silo, StatisticsOptions options) @@ -63,7 +64,7 @@ internal async Task SetSiloMetricsTableDataManager(Silo silo, StatisticsOptions // Hook up to publish silo metrics to Azure storage table var gateway = this.siloDetails.GatewayAddress?.Endpoint; metricsDataPublisher = AssemblyLoader.LoadAndCreateInstance(Constants.ORLEANS_STATISTICS_AZURESTORAGE, logger, silo.Services); - await metricsDataPublisher.Init(this.siloDetails.ClusterId, silo.GlobalConfig.DataConnectionString, this.siloDetails.SiloAddress, this.siloDetails.Name, gateway, this.siloDetails.DnsHostName); + await metricsDataPublisher.Init(this.siloDetails.ClusterId, this.storageOptions.DataConnectionString, this.siloDetails.SiloAddress, this.siloDetails.Name, gateway, this.siloDetails.DnsHostName); MetricsTable.MetricsDataPublisher = metricsDataPublisher; } } @@ -87,7 +88,7 @@ internal async Task SetSiloStatsTableDataManager(Silo silo, StatisticsOptions op else if (CanUseAzureTable(silo, options)) { statsDataPublisher = AssemblyLoader.LoadAndCreateInstance(Constants.ORLEANS_STATISTICS_AZURESTORAGE, logger, silo.Services); - await statsDataPublisher.Init(true, silo.GlobalConfig.DataConnectionString, this.siloDetails.ClusterId, this.siloDetails.SiloAddress.ToLongString(), this.siloDetails.Name, this.siloDetails.DnsHostName); + await statsDataPublisher.Init(true, this.storageOptions.DataConnectionString, this.siloDetails.ClusterId, this.siloDetails.SiloAddress.ToLongString(), this.siloDetails.Name, this.siloDetails.DnsHostName); logStatistics.StatsTablePublisher = statsDataPublisher; } // else no stats @@ -97,10 +98,11 @@ internal async Task SetSiloStatsTableDataManager(Silo silo, StatisticsOptions op Silo silo, StatisticsOptions options) { - // TODO: use DI to configure this and don't rely on GlobalConfiguration nor NodeConfiguration - return silo.GlobalConfig.LivenessType == GlobalConfiguration.LivenessProviderType.AzureTable - && !string.IsNullOrEmpty(this.siloDetails.ClusterId) - && !string.IsNullOrEmpty(silo.GlobalConfig.DataConnectionString); + return + // TODO: find a better way? - jbragg + silo.Services.GetService()?.GetType().Name == "AzureBasedMembershipTable" && + !string.IsNullOrEmpty(this.siloDetails.ClusterId) && + !string.IsNullOrEmpty(this.storageOptions.DataConnectionString); } internal void Start(StatisticsOptions options) diff --git a/src/Orleans.Runtime/GrainDirectory/ClientObserverRegistrar.cs b/src/Orleans.Runtime/GrainDirectory/ClientObserverRegistrar.cs index 2c7828ff5e..c6dcb8f0a5 100644 --- a/src/Orleans.Runtime/GrainDirectory/ClientObserverRegistrar.cs +++ b/src/Orleans.Runtime/GrainDirectory/ClientObserverRegistrar.cs @@ -3,6 +3,8 @@ using System.Linq; using System.Threading.Tasks; using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Options; +using Orleans.Hosting; using Orleans.Runtime.Configuration; using Orleans.Runtime.GrainDirectory; using Orleans.Runtime.Messaging; @@ -19,7 +21,7 @@ internal class ClientObserverRegistrar : SystemTarget, IClientObserverRegistrar, private readonly ILocalGrainDirectory grainDirectory; private readonly SiloAddress myAddress; private readonly OrleansTaskScheduler scheduler; - private readonly ClusterConfiguration orleansConfig; + private readonly SiloMessagingOptions messagingOptions; private readonly ILogger logger; private Gateway gateway; private IDisposable refreshTimer; @@ -29,14 +31,14 @@ internal class ClientObserverRegistrar : SystemTarget, IClientObserverRegistrar, ILocalSiloDetails siloDetails, ILocalGrainDirectory dir, OrleansTaskScheduler scheduler, - ClusterConfiguration config, + IOptions messagingOptions, ILoggerFactory loggerFactory) : base(Constants.ClientObserverRegistrarId, siloDetails.SiloAddress, loggerFactory) { grainDirectory = dir; myAddress = siloDetails.SiloAddress; this.scheduler = scheduler; - orleansConfig = config; + this.messagingOptions = messagingOptions.Value; logger = loggerFactory.CreateLogger(); } @@ -51,12 +53,12 @@ internal void SetGateway(Gateway gateway) private void Start() { var random = new SafeRandom(); - var randomOffset = random.NextTimeSpan(orleansConfig.Globals.ClientRegistrationRefresh); + var randomOffset = random.NextTimeSpan(this.messagingOptions.ClientRegistrationRefresh); this.refreshTimer = this.RegisterTimer( this.OnClientRefreshTimer, null, randomOffset, - orleansConfig.Globals.ClientRegistrationRefresh, + this.messagingOptions.ClientRegistrationRefresh, "ClientObserverRegistrar.ClientRefreshTimer"); if (logger.IsEnabled(LogLevel.Debug)) { logger.Debug("Client registrar service started successfully."); } } @@ -97,7 +99,7 @@ private async Task ExecuteWithRetries(Func functionToExecute, ErrorCode er }, AsyncExecutorWithRetries.INFINITE_RETRIES, // Do not limit the number of on-error retries, control it via "maxExecutionTime" (exc, i) => true, // Retry on all errors. - orleansConfig.Globals.ClientRegistrationRefresh, // "maxExecutionTime" + this.messagingOptions.ClientRegistrationRefresh, // "maxExecutionTime" new ExponentialBackoff(EXP_BACKOFF_ERROR_MIN, EXP_BACKOFF_ERROR_MAX, EXP_BACKOFF_STEP)); // how long to wait between error retries } catch (Exception exc) diff --git a/src/Orleans.Runtime/GrainDirectory/GrainDirectoryCacheFactory.cs b/src/Orleans.Runtime/GrainDirectory/GrainDirectoryCacheFactory.cs index 9d9b7f1515..60e95ce435 100644 --- a/src/Orleans.Runtime/GrainDirectory/GrainDirectoryCacheFactory.cs +++ b/src/Orleans.Runtime/GrainDirectory/GrainDirectoryCacheFactory.cs @@ -1,25 +1,26 @@ using System; using System.Collections.Generic; using Microsoft.Extensions.Logging; +using Orleans.Hosting; using Orleans.Runtime.Configuration; namespace Orleans.Runtime.GrainDirectory { internal static class GrainDirectoryCacheFactory { - internal static IGrainDirectoryCache CreateGrainDirectoryCache(GlobalConfiguration cfg) + internal static IGrainDirectoryCache CreateGrainDirectoryCache(GrainDirectoryOptions options) { - if (cfg.CacheSize <= 0) + if (options.CacheSize <= 0) return new NullGrainDirectoryCache(); - switch (cfg.DirectoryCachingStrategy) + switch (options.CachingStrategy) { - case GlobalConfiguration.DirectoryCachingStrategyType.None: + case GrainDirectoryOptions.CachingStrategyType.None: return new NullGrainDirectoryCache(); - case GlobalConfiguration.DirectoryCachingStrategyType.LRU: - return new LRUBasedGrainDirectoryCache(cfg.CacheSize, cfg.MaximumCacheTTL); + case GrainDirectoryOptions.CachingStrategyType.LRU: + return new LRUBasedGrainDirectoryCache(options.CacheSize, options.MaximumCacheTTL); default: - return new AdaptiveGrainDirectoryCache(cfg.InitialCacheTTL, cfg.MaximumCacheTTL, cfg.CacheTTLExtensionFactor, cfg.CacheSize); + return new AdaptiveGrainDirectoryCache(options.InitialCacheTTL, options.MaximumCacheTTL, options.CacheTTLExtensionFactor, options.CacheSize); } } diff --git a/src/Orleans.Runtime/GrainDirectory/GrainDirectoryPartition.cs b/src/Orleans.Runtime/GrainDirectory/GrainDirectoryPartition.cs index a90c95c28e..20f07ee289 100644 --- a/src/Orleans.Runtime/GrainDirectory/GrainDirectoryPartition.cs +++ b/src/Orleans.Runtime/GrainDirectory/GrainDirectoryPartition.cs @@ -3,7 +3,9 @@ using System.Linq; using System.Text; using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Options; using Orleans.GrainDirectory; +using Orleans.Hosting; using Orleans.Runtime.Configuration; namespace Orleans.Runtime.GrainDirectory @@ -30,7 +32,7 @@ public ActivationInfo(IActivationInfo iActivationInfo) } - public bool OkToRemove(UnregistrationCause cause, GlobalConfiguration config) + public bool OkToRemove(UnregistrationCause cause, TimeSpan lazyDeregistrationDelay) { switch (cause) { @@ -45,7 +47,7 @@ public bool OkToRemove(UnregistrationCause cause, GlobalConfiguration config) if (RegistrationStatus == GrainDirectoryEntryStatus.Cached) return true; // cache entries are always removed - var delayparameter = config.DirectoryLazyDeregistrationDelay; + var delayparameter = lazyDeregistrationDelay; if (delayparameter <= TimeSpan.Zero) return false; // no lazy deregistration else @@ -122,11 +124,11 @@ public ActivationAddress AddSingleActivation(GrainId grain, ActivationId act, Si } } - public bool RemoveActivation(ActivationId act, UnregistrationCause cause, GlobalConfiguration config, out IActivationInfo info, out bool wasRemoved) + public bool RemoveActivation(ActivationId act, UnregistrationCause cause, TimeSpan lazyDeregistrationDelay, out IActivationInfo info, out bool wasRemoved) { info = null; wasRemoved = false; - if (Instances.TryGetValue(act, out info) && info.OkToRemove(cause, config)) + if (Instances.TryGetValue(act, out info) && info.OkToRemove(cause, lazyDeregistrationDelay)) { Instances.Remove(act); wasRemoved = true; @@ -216,8 +218,8 @@ internal class GrainDirectoryPartition private readonly ILogger log; private readonly ILoggerFactory loggerFactory; private readonly ISiloStatusOracle siloStatusOracle; - private readonly GlobalConfiguration globalConfig; private readonly IInternalGrainFactory grainFactory; + private readonly IOptions grainDirectoryOptions; [ThreadStatic] private static ActivationId[] activationIdsHolder; @@ -227,13 +229,13 @@ internal class GrainDirectoryPartition internal int Count { get { return partitionData.Count; } } - public GrainDirectoryPartition(ISiloStatusOracle siloStatusOracle, GlobalConfiguration globalConfig, IInternalGrainFactory grainFactory, ILoggerFactory loggerFactory) + public GrainDirectoryPartition(ISiloStatusOracle siloStatusOracle, IOptions grainDirectoryOptions, IInternalGrainFactory grainFactory, ILoggerFactory loggerFactory) { partitionData = new Dictionary(); lockable = new object(); log = loggerFactory.CreateLogger(); this.siloStatusOracle = siloStatusOracle; - this.globalConfig = globalConfig; + this.grainDirectoryOptions = grainDirectoryOptions; this.grainFactory = grainFactory; this.loggerFactory = loggerFactory; } @@ -353,7 +355,7 @@ internal void RemoveActivation(GrainId grain, ActivationId activation, Unregistr entry = null; lock (lockable) { - if (partitionData.ContainsKey(grain) && partitionData[grain].RemoveActivation(activation, cause, globalConfig, out entry, out wasRemoved)) + if (partitionData.ContainsKey(grain) && partitionData[grain].RemoveActivation(activation, cause, this.grainDirectoryOptions.Value.LazyDeregistrationDelay, out entry, out wasRemoved)) // if the last activation for the grain was removed, we remove the entire grain info partitionData.Remove(grain); @@ -530,7 +532,7 @@ internal void Merge(GrainDirectoryPartition other) /// new grain directory partition containing entries satisfying the given predicate internal GrainDirectoryPartition Split(Predicate predicate, bool modifyOrigin) { - var newDirectory = new GrainDirectoryPartition(this.siloStatusOracle, this.globalConfig, this.grainFactory, this.loggerFactory); + var newDirectory = new GrainDirectoryPartition(this.siloStatusOracle, this.grainDirectoryOptions, this.grainFactory, this.loggerFactory); if (modifyOrigin) { diff --git a/src/Orleans.Runtime/GrainDirectory/LocalGrainDirectory.cs b/src/Orleans.Runtime/GrainDirectory/LocalGrainDirectory.cs index 5534dc542e..e20c2d0bb4 100644 --- a/src/Orleans.Runtime/GrainDirectory/LocalGrainDirectory.cs +++ b/src/Orleans.Runtime/GrainDirectory/LocalGrainDirectory.cs @@ -92,7 +92,6 @@ internal class LocalGrainDirectory : internal readonly CounterStatistic UnregistrationsManyRemoteReceived; public LocalGrainDirectory( - ClusterConfiguration clusterConfig, ILocalSiloDetails siloDetails, OrleansTaskScheduler scheduler, ISiloStatusOracle siloStatusOracle, @@ -103,10 +102,10 @@ internal class LocalGrainDirectory : ExecutorService executorService, IOptions developmentMembershipOptions, IOptions multiClusterOptions, + IOptions grainDirectoryOptions, ILoggerFactory loggerFactory) { this.log = loggerFactory.CreateLogger(); - var globalConfig = clusterConfig.Globals; var clusterId = multiClusterOptions.Value.HasMultiClusterNetwork ? siloDetails.ClusterId : null; MyAddress = siloDetails.SiloAddress; @@ -119,13 +118,19 @@ internal class LocalGrainDirectory : membershipCache = new HashSet(); ClusterId = clusterId; - clusterConfig.OnConfigChange("Globals/Caching", () => + lock (membershipCache) { - lock (membershipCache) - { - DirectoryCache = GrainDirectoryCacheFactory>>.CreateGrainDirectoryCache(globalConfig); - } - }); + DirectoryCache = GrainDirectoryCacheFactory>>.CreateGrainDirectoryCache(grainDirectoryOptions.Value); + } + /* TODO - investigate dynamic config changes using IOptions - jbragg + clusterConfig.OnConfigChange("Globals/Caching", () => + { + lock (membershipCache) + { + DirectoryCache = GrainDirectoryCacheFactory>>.CreateGrainDirectoryCache(globalConfig); + } + }); + */ maintainer = GrainDirectoryCacheFactory>>.CreateGrainDirectoryCacheMaintainer( this, @@ -134,7 +139,7 @@ internal class LocalGrainDirectory : grainFactory, executorService, loggerFactory); - GsiActivationMaintainer = new GlobalSingleInstanceActivationMaintainer(this, this.Logger, globalConfig, grainFactory, multiClusterOracle, executorService, siloDetails, multiClusterOptions, loggerFactory); + GsiActivationMaintainer = new GlobalSingleInstanceActivationMaintainer(this, this.Logger, grainFactory, multiClusterOracle, executorService, siloDetails, multiClusterOptions, loggerFactory); var primarySiloEndPoint = developmentMembershipOptions.Value.PrimarySiloEndpoint; if (primarySiloEndPoint != null) diff --git a/src/Orleans.Runtime/GrainDirectory/MultiClusterRegistration/GlobalSingleInstanceActivationMaintainer.cs b/src/Orleans.Runtime/GrainDirectory/MultiClusterRegistration/GlobalSingleInstanceActivationMaintainer.cs index e3ce25bf99..ed01936dcf 100644 --- a/src/Orleans.Runtime/GrainDirectory/MultiClusterRegistration/GlobalSingleInstanceActivationMaintainer.cs +++ b/src/Orleans.Runtime/GrainDirectory/MultiClusterRegistration/GlobalSingleInstanceActivationMaintainer.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; @@ -33,7 +33,6 @@ internal class GlobalSingleInstanceActivationMaintainer : AsynchAgent public GlobalSingleInstanceActivationMaintainer( LocalGrainDirectory router, ILogger logger, - GlobalConfiguration config, IInternalGrainFactory grainFactory, IMultiClusterOracle multiClusterOracle, ExecutorService executorService, @@ -48,7 +47,7 @@ internal class GlobalSingleInstanceActivationMaintainer : AsynchAgent this.multiClusterOracle = multiClusterOracle; this.siloDetails = siloDetails; this.multiClusterOptions = multiClusterOptions.Value; - this.period = config.GlobalSingleInstanceRetryInterval; + this.period = multiClusterOptions.Value.GlobalSingleInstanceRetryInterval; logger.Debug("GSIP:M GlobalSingleInstanceActivationMaintainer Started, Period = {0}", period); } diff --git a/src/Orleans.Runtime/GrainDirectory/MultiClusterRegistration/GlobalSingleInstanceRegistrar.cs b/src/Orleans.Runtime/GrainDirectory/MultiClusterRegistration/GlobalSingleInstanceRegistrar.cs index d568e1b9aa..89b22ad0f1 100644 --- a/src/Orleans.Runtime/GrainDirectory/MultiClusterRegistration/GlobalSingleInstanceRegistrar.cs +++ b/src/Orleans.Runtime/GrainDirectory/MultiClusterRegistration/GlobalSingleInstanceRegistrar.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; @@ -38,7 +38,6 @@ internal class GlobalSingleInstanceRegistrar : IGrainRegistrar logger, GlobalSingleInstanceActivationMaintainer gsiActivationMaintainer, - GlobalConfiguration config, IInternalGrainFactory grainFactory, IMultiClusterOracle multiClusterOracle, ILocalSiloDetails siloDetails, @@ -47,7 +46,7 @@ internal class GlobalSingleInstanceRegistrar : IGrainRegistrar( - grainClass, - attr => new StatelessWorkerPlacement(attr.MaxLocalWorkers), - out placement)) - { - return placement; - } - if (GetPlacementStrategy( grainClass, a => a.PlacementStrategy, diff --git a/src/Orleans.Runtime/GrainTypeManager/GrainTypeManager.cs b/src/Orleans.Runtime/GrainTypeManager/GrainTypeManager.cs index 135ca0d9f3..55c5172b57 100644 --- a/src/Orleans.Runtime/GrainTypeManager/GrainTypeManager.cs +++ b/src/Orleans.Runtime/GrainTypeManager/GrainTypeManager.cs @@ -40,7 +40,7 @@ internal class GrainTypeManager public GrainTypeManager( ILocalSiloDetails siloDetails, IApplicationPartManager applicationPartManager, - DefaultPlacementStrategy defaultPlacementStrategy, + PlacementStrategy defaultPlacementStrategy, SerializationManager serializationManager, MultiClusterRegistrationStrategyManager multiClusterRegistrationStrategyManager, ILogger logger, @@ -48,7 +48,7 @@ internal class GrainTypeManager { var localTestMode = siloDetails.SiloAddress.Endpoint.Address.Equals(IPAddress.Loopback); this.logger = logger; - this.defaultPlacementStrategy = defaultPlacementStrategy.PlacementStrategy; + this.defaultPlacementStrategy = defaultPlacementStrategy; this.serializationManager = serializationManager; this.multiClusterRegistrationStrategyManager = multiClusterRegistrationStrategyManager; grainInterfaceMap = new GrainInterfaceMap(localTestMode, this.defaultPlacementStrategy); diff --git a/src/Orleans.Runtime/Hosting/CoreHostingExtensions.cs b/src/Orleans.Runtime/Hosting/CoreHostingExtensions.cs index b80c8b873e..0d433b7271 100644 --- a/src/Orleans.Runtime/Hosting/CoreHostingExtensions.cs +++ b/src/Orleans.Runtime/Hosting/CoreHostingExtensions.cs @@ -67,47 +67,6 @@ public static ISiloHostBuilder ConfigureSiloName(this ISiloHostBuilder builder, return builder; } - /// - /// Specifies the configuration to use for this silo. - /// - /// The host builder. - /// The configuration. - /// This method may only be called once per builder instance. - /// The silo builder. - public static ISiloHostBuilder UseConfiguration(this ISiloHostBuilder builder, ClusterConfiguration configuration) - { - if (configuration == null) throw new ArgumentNullException(nameof(configuration)); - return builder.ConfigureServices((context, services) => - { - services.AddLegacyClusterConfigurationSupport(configuration); - }); - } - - /// - /// Loads using . - /// - /// The host builder. - /// The silo builder. - public static ISiloHostBuilder LoadClusterConfiguration(this ISiloHostBuilder builder) - { - var configuration = new ClusterConfiguration(); - configuration.StandardLoad(); - return builder.UseConfiguration(configuration); - } - - /// - /// Configures a localhost silo. - /// - /// The host builder. - /// The silo-to-silo communication port. - /// The client-to-silo communication port. - /// The silo builder. - public static ISiloHostBuilder ConfigureLocalHostPrimarySilo(this ISiloHostBuilder builder, int siloPort = 22222, int gatewayPort = 40000) - { - builder.ConfigureSiloName(Silo.PrimarySiloName); - return builder.UseConfiguration(ClusterConfiguration.LocalhostPrimarySilo(siloPort, gatewayPort)); - } - /// /// Configure silo to use Development membership /// diff --git a/src/Orleans.Runtime/Hosting/DefaultSiloServices.cs b/src/Orleans.Runtime/Hosting/DefaultSiloServices.cs index 8d9bb28996..7872975358 100644 --- a/src/Orleans.Runtime/Hosting/DefaultSiloServices.cs +++ b/src/Orleans.Runtime/Hosting/DefaultSiloServices.cs @@ -2,7 +2,6 @@ using Microsoft.Extensions.DependencyInjection.Extensions; using Orleans.Configuration; using Orleans.GrainDirectory; -using Orleans.Runtime.Configuration; using Orleans.Runtime.ConsistentRing; using Orleans.Runtime.Counters; using Orleans.Runtime.GrainDirectory; @@ -35,6 +34,7 @@ using System.Collections.Generic; using Orleans.Metadata; using Orleans.Statistics; +using Microsoft.Extensions.Options; namespace Orleans.Hosting { @@ -138,27 +138,48 @@ internal static void AddDefaultServices(HostBuilderContext context, IServiceColl // Placement services.TryAddSingleton(); - services.TryAddSingleton, RandomPlacementDirector>(); - services.TryAddSingleton, RandomPlacementDirector>(); - services.TryAddSingleton, PreferLocalPlacementDirector>(); - services.TryAddSingleton, StatelessWorkerDirector>(); - services.TryAddSingleton, StatelessWorkerDirector>(); - services.TryAddSingleton, ActivationCountPlacementDirector>(); - services.TryAddSingleton, HashBasedPlacementDirector>(); - services.TryAddSingleton(); services.TryAddSingleton(); - - // Versions + // Placement strategies + services.AddSingletonNamedService(nameof(RandomPlacement)); + services.AddSingletonNamedService(nameof(PreferLocalPlacement)); + services.AddSingletonNamedService(nameof(StatelessWorkerPlacement)); + services.AddSingletonNamedService(nameof(ActivationCountBasedPlacement)); + services.AddSingletonNamedService(nameof(HashBasedPlacement)); + // Default placement stragety + services.TryAddSingleton(PlacementStrategyFactory.Create); + // Placement directors + services.AddSingletonKeyedService(typeof(RandomPlacement)); + services.AddSingletonKeyedService(typeof(PreferLocalPlacement)); + services.AddSingletonKeyedService(typeof(StatelessWorkerPlacement)); + services.AddSingletonKeyedService(typeof(ActivationCountBasedPlacement)); + services.AddSingletonKeyedService(typeof(HashBasedPlacement)); + // Activation selectors + services.AddSingletonKeyedService(typeof(RandomPlacement)); + services.AddSingletonKeyedService(typeof(StatelessWorkerPlacement)); + + // Versioning services.TryAddSingleton(); - services.TryAddSingleton, MinimumVersionSelector>(); - services.TryAddSingleton, LatestVersionSelector>(); - services.TryAddSingleton, AllCompatibleVersionsSelector>(); - services.TryAddSingleton(); - services.TryAddSingleton, BackwardCompatilityDirector>(); - services.TryAddSingleton, AllVersionsCompatibilityDirector>(); - services.TryAddSingleton, StrictVersionCompatibilityDirector>(); services.TryAddSingleton(); + // Version selector strategy services.TryAddSingleton(); + services.AddSingletonNamedService(nameof(AllCompatibleVersions)); + services.AddSingletonNamedService(nameof(LatestVersion)); + services.AddSingletonNamedService(nameof(MinimumVersion)); + // Versions selectors + services.AddSingletonKeyedService(typeof(MinimumVersion)); + services.AddSingletonKeyedService(typeof(LatestVersion)); + services.AddSingletonKeyedService(typeof(AllCompatibleVersions)); + + // Compatibility + services.TryAddSingleton(); + // Compatability strategy + services.AddSingletonNamedService(nameof(AllVersionsCompatible)); + services.AddSingletonNamedService(nameof(BackwardCompatible)); + services.AddSingletonNamedService(nameof(StrictVersionCompatible)); + // Compatability directors + services.AddSingletonKeyedService(typeof(BackwardCompatible)); + services.AddSingletonKeyedService(typeof(AllVersionsCompatible)); + services.AddSingletonKeyedService(typeof(StrictVersionCompatible)); services.TryAddSingleton>(sp => () => sp.GetRequiredService()); @@ -173,12 +194,13 @@ internal static void AddDefaultServices(HostBuilderContext context, IServiceColl services.TryAddSingleton( sp => { - var globalConfig = sp.GetRequiredService(); + // TODO: make this not sux - jbragg + var consistentRingOptions = sp.GetRequiredService>().Value; var siloDetails = sp.GetRequiredService(); var loggerFactory = sp.GetRequiredService(); - if (globalConfig.UseVirtualBucketsConsistentRing) + if (consistentRingOptions.UseVirtualBucketsConsistentRing) { - return new VirtualBucketsRingProvider(siloDetails.SiloAddress, loggerFactory, globalConfig.NumVirtualBucketsConsistentRing); + return new VirtualBucketsRingProvider(siloDetails.SiloAddress, loggerFactory, consistentRingOptions.NumVirtualBucketsConsistentRing); } return new ConsistentRingProvider(siloDetails.SiloAddress, loggerFactory); @@ -214,7 +236,7 @@ internal static void AddDefaultServices(HostBuilderContext context, IServiceColl //Add default option formatter if none is configured, for options which are requied to be configured services.TryConfigureFormatter(); - services.TryConfigureFormatter(); + services.TryConfigureFormatter(); services.TryConfigureFormatter(); services.TryConfigureFormatter(); } diff --git a/src/Orleans.Runtime/Hosting/LegacyClusterConfigurationExtensions.cs b/src/Orleans.Runtime/Hosting/LegacyClusterConfigurationExtensions.cs deleted file mode 100644 index 1982af39df..0000000000 --- a/src/Orleans.Runtime/Hosting/LegacyClusterConfigurationExtensions.cs +++ /dev/null @@ -1,147 +0,0 @@ -using System; -using System.Linq; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.DependencyInjection.Extensions; -using Microsoft.Extensions.Options; -using Orleans.Configuration; -using Orleans.Runtime; -using Orleans.Runtime.Configuration; -using Orleans.Runtime.MembershipService; -using Orleans.Runtime.Scheduler; -using Orleans.Runtime.Providers; -using Orleans.Providers; -using Orleans.Configuration.Options; - -namespace Orleans.Hosting -{ - public static class LegacyClusterConfigurationExtensions - { - private const int SiloDefaultProviderInitStage = SiloLifecycleStage.RuntimeStorageServices; - private const int SiloDefaultProviderStartStage = SiloLifecycleStage.ApplicationServices; - - public static IServiceCollection AddLegacyClusterConfigurationSupport(this IServiceCollection services, ClusterConfiguration configuration) - { - if (configuration == null) throw new ArgumentNullException(nameof(configuration)); - - if (services.TryGetClusterConfiguration() != null) - { - throw new InvalidOperationException("Cannot configure legacy ClusterConfiguration support twice"); - } - - // these will eventually be removed once our code doesn't depend on the old ClientConfiguration - services.AddSingleton(configuration); - services.TryAddSingleton(); - services.TryAddSingleton(sp => sp.GetRequiredService().ClusterConfig.Globals); - services.TryAddTransient(sp => sp.GetRequiredService().NodeConfig); - services.TryAddSingleton>( - sp => - { - var initializationParams = sp.GetRequiredService(); - return () => initializationParams.NodeConfig; - }); - - services.Configure(options => - { - if (string.IsNullOrWhiteSpace(options.ClusterId) && !string.IsNullOrWhiteSpace(configuration.Globals.ClusterId)) - { - options.ClusterId = configuration.Globals.ClusterId; - } - - if (options.ServiceId == Guid.Empty) - { - options.ServiceId = configuration.Globals.ServiceId; - } - }); - - services.Configure(options => - { - var globals = configuration.Globals; - if (globals.HasMultiClusterNetwork) - { - options.HasMultiClusterNetwork = true; - options.BackgroundGossipInterval = globals.BackgroundGossipInterval; - options.DefaultMultiCluster = globals.DefaultMultiCluster?.ToList(); - options.GlobalSingleInstanceNumberRetries = globals.GlobalSingleInstanceNumberRetries; - options.GlobalSingleInstanceRetryInterval = globals.GlobalSingleInstanceRetryInterval; - options.MaxMultiClusterGateways = globals.MaxMultiClusterGateways; - options.UseGlobalSingleInstanceByDefault = globals.UseGlobalSingleInstanceByDefault; - } - }); - - services.TryAddFromExisting(); - - services.AddOptions() - .Configure((options, nodeConfig) => LegacyConfigurationExtensions.CopyStatisticsOptions(nodeConfig, options)); - - // Translate legacy configuration to new Options - services.Configure(options => - { - LegacyConfigurationExtensions.CopyCommonMessagingOptions(configuration.Globals, options); - - options.SiloSenderQueues = configuration.Globals.SiloSenderQueues; - options.GatewaySenderQueues = configuration.Globals.GatewaySenderQueues; - options.MaxForwardCount = configuration.Globals.MaxForwardCount; - options.ClientDropTimeout = configuration.Globals.ClientDropTimeout; - }); - - services.Configure(options => LegacyConfigurationExtensions.CopyNetworkingOptions(configuration.Globals, options)); - - services.AddOptions() - .Configure>((options, siloOptions) => - { - var nodeConfig = configuration.GetOrCreateNodeConfigurationForSilo(siloOptions.Value.SiloName); - if (options.IPAddress == null && string.IsNullOrWhiteSpace(options.HostNameOrIPAddress)) - { - options.IPAddress = nodeConfig.Endpoint.Address; - options.Port = nodeConfig.Endpoint.Port; - } - if (options.ProxyPort == 0 && nodeConfig.ProxyGatewayEndpoint != null) - { - options.ProxyPort = nodeConfig.ProxyGatewayEndpoint.Port; - } - }); - - services.Configure(options => - { - options.SerializationProviders = configuration.Globals.SerializationProviders; - options.FallbackSerializationProvider = configuration.Globals.FallbackSerializationProvider; - }); - - services.Configure(options => - { - LegacyConfigurationExtensions.CopyTelemetryOptions(configuration.Defaults.TelemetryConfiguration, services, options); - }); - - services.AddOptions().Configure>((options, siloOptions) => - { - var nodeConfig = configuration.GetOrCreateNodeConfigurationForSilo(siloOptions.Value.SiloName); - options.ExcludedGrainTypes.AddRange(nodeConfig.ExcludedGrainTypes); - }); - - LegacyMembershipConfigurator.ConfigureServices(configuration.Globals, services); - - services.AddOptions().Configure((options, config) => - { - options.AllowCallChainReentrancy = config.AllowCallChainReentrancy; - options.PerformDeadlockDetection = config.PerformDeadlockDetection; - }); - - services.TryAddSingleton(sp => - { - OrleansTaskScheduler scheduler = sp.GetRequiredService(); - SystemTarget fallbackSystemTarget = sp.GetRequiredService(); - return (taskFunc) => scheduler.QueueTask(taskFunc, fallbackSystemTarget.SchedulingContext); - }); - LegacyProviderConfigurator.ConfigureServices(configuration.Globals.ProviderConfigurations, services, SiloDefaultProviderInitStage, SiloDefaultProviderStartStage); - - return services; - } - - public static ClusterConfiguration TryGetClusterConfiguration(this IServiceCollection services) - { - return services - .FirstOrDefault(s => s.ServiceType == typeof(ClusterConfiguration)) - ?.ImplementationInstance as ClusterConfiguration; - } - } -} diff --git a/src/Orleans.Runtime/MembershipService/MembershipOracle.cs b/src/Orleans.Runtime/MembershipService/MembershipOracle.cs index a1976bceab..ae5739e7b6 100644 --- a/src/Orleans.Runtime/MembershipService/MembershipOracle.cs +++ b/src/Orleans.Runtime/MembershipService/MembershipOracle.cs @@ -19,7 +19,7 @@ internal class MembershipOracle : SystemTarget, IMembershipOracle, IMembershipSe private readonly MembershipOracleData membershipOracleData; private Dictionary probedSilos; // map from currently probed silos to the number of failed probes private readonly ILogger logger; - private readonly ClusterConfiguration orleansConfig; + private readonly MembershipOptions membershipOptions; private SiloAddress MyAddress { get { return membershipOracleData.MyAddress; } } private GrainTimer timerGetTableUpdates; private GrainTimer timerProbeOtherSilos; @@ -38,10 +38,10 @@ internal class MembershipOracle : SystemTarget, IMembershipOracle, IMembershipSe public string SiloName { get { return membershipOracleData.SiloName; } } public SiloAddress SiloAddress { get { return membershipOracleData.MyAddress; } } - private TimeSpan AllowedIAmAliveMissPeriod { get { return orleansConfig.Globals.IAmAliveTablePublishTimeout.Multiply(orleansConfig.Globals.NumMissedTableIAmAliveLimit); } } + private TimeSpan AllowedIAmAliveMissPeriod { get { return this.membershipOptions.IAmAliveTablePublishTimeout.Multiply(this.membershipOptions.NumMissedTableIAmAliveLimit); } } private readonly ILoggerFactory loggerFactory; - public MembershipOracle(ILocalSiloDetails siloDetails, ClusterConfiguration clusterConfiguration, MembershipTableFactory membershipTableFactory, IInternalGrainFactory grainFactory, IOptions multiClusterOptions, ILoggerFactory loggerFactory) + public MembershipOracle(ILocalSiloDetails siloDetails, IOptions membershipOptions, MembershipTableFactory membershipTableFactory, IInternalGrainFactory grainFactory, IOptions multiClusterOptions, ILoggerFactory loggerFactory) : base(Constants.MembershipOracleId, siloDetails.SiloAddress, loggerFactory) { this.loggerFactory = loggerFactory; @@ -50,9 +50,9 @@ public MembershipOracle(ILocalSiloDetails siloDetails, ClusterConfiguration clus logger = loggerFactory.CreateLogger(); membershipOracleData = new MembershipOracleData(siloDetails, logger, multiClusterOptions.Value); probedSilos = new Dictionary(); - orleansConfig = clusterConfiguration; + this.membershipOptions = membershipOptions.Value; pingCounter = 0; - TimeSpan backOffMax = StandardExtensions.Max(EXP_BACKOFF_STEP.Multiply(orleansConfig.Globals.ExpectedClusterSize), SiloMessageSender.CONNECTION_RETRY_DELAY.Multiply(2)); + TimeSpan backOffMax = StandardExtensions.Max(EXP_BACKOFF_STEP.Multiply(this.membershipOptions.ExpectedClusterSize), SiloMessageSender.CONNECTION_RETRY_DELAY.Multiply(2)); EXP_BACKOFF_CONTENTION_MAX = backOffMax; EXP_BACKOFF_ERROR_MAX = backOffMax; timerLogger = this.loggerFactory.CreateLogger(); @@ -72,8 +72,8 @@ public async Task Start() // randomly delay the startup, so not all silos write to the table at once. // Use random time not larger than MaxJoinAttemptTime, one minute and 0.5sec*ExpectedClusterSize; var random = new SafeRandom(); - var maxDelay = TimeSpan.FromMilliseconds(500).Multiply(orleansConfig.Globals.ExpectedClusterSize); - maxDelay = StandardExtensions.Min(maxDelay, StandardExtensions.Min(orleansConfig.Globals.MaxJoinAttemptTime, TimeSpan.FromMinutes(1))); + var maxDelay = TimeSpan.FromMilliseconds(500).Multiply(this.membershipOptions.ExpectedClusterSize); + maxDelay = StandardExtensions.Min(maxDelay, StandardExtensions.Min(this.membershipOptions.MaxJoinAttemptTime, TimeSpan.FromMinutes(1))); var randomDelay = random.NextTimeSpan(maxDelay); await Task.Delay(randomDelay); @@ -148,8 +148,8 @@ public async Task BecomeActive() Action configure = () => { var random = new SafeRandom(); - var randomTableOffset = random.NextTimeSpan(orleansConfig.Globals.TableRefreshTimeout); - var randomProbeOffset = random.NextTimeSpan(orleansConfig.Globals.ProbeTimeout); + var randomTableOffset = random.NextTimeSpan(this.membershipOptions.TableRefreshTimeout); + var randomProbeOffset = random.NextTimeSpan(this.membershipOptions.ProbeTimeout); if (timerGetTableUpdates != null) timerGetTableUpdates.Dispose(); timerGetTableUpdates = GrainTimer.FromTimerCallback( @@ -158,7 +158,7 @@ public async Task BecomeActive() OnGetTableUpdateTimer, null, randomTableOffset, - orleansConfig.Globals.TableRefreshTimeout, + this.membershipOptions.TableRefreshTimeout, "Membership.ReadTableTimer"); timerGetTableUpdates.Start(); @@ -172,13 +172,15 @@ public async Task BecomeActive() OnProbeOtherSilosTimer, null, randomProbeOffset, - orleansConfig.Globals.ProbeTimeout, + this.membershipOptions.ProbeTimeout, "Membership.ProbeTimer"); timerProbeOtherSilos.Start(); }; +/* TODO - figure out how to wire up config changes using options - jbragg orleansConfig.OnConfigChange( "Globals/Liveness", () => this.RuntimeClient.Scheduler.RunOrQueueAction(configure, SchedulingContext), false); +*/ configure(); logger.Info(ErrorCode.MembershipFinishBecomeActive, "-Finished BecomeActive."); @@ -203,7 +205,7 @@ private void StartIAmAliveUpdateTimer() OnIAmAliveUpdateInTableTimer, null, TimeSpan.Zero, - orleansConfig.Globals.IAmAliveTablePublishTimeout, + this.membershipOptions.IAmAliveTablePublishTimeout, "Membership.IAmAliveTimer"); timerIAmAliveUpdateInTable.Start(); @@ -379,7 +381,7 @@ private Task CleanupTable() return await CleanupTableEntries(table); }; - return MembershipExecuteWithRetries(cleanupTableEntriesTask, orleansConfig.Globals.MaxJoinAttemptTime); + return MembershipExecuteWithRetries(cleanupTableEntriesTask, this.membershipOptions.MaxJoinAttemptTime); } private async Task UpdateMyStatusGlobal(SiloStatus status) @@ -396,7 +398,7 @@ private async Task UpdateMyStatusGlobal(SiloStatus status) return await TryUpdateMyStatusGlobalOnce(status); // function to retry }; - bool ok = await MembershipExecuteWithRetries(updateMyStatusTask, orleansConfig.Globals.MaxJoinAttemptTime); + bool ok = await MembershipExecuteWithRetries(updateMyStatusTask, this.membershipOptions.MaxJoinAttemptTime); if (ok) { @@ -473,7 +475,7 @@ private async Task TryUpdateMyStatusGlobalOnce(SiloStatus newStatus) myEntry.Status = newStatus; myEntry.IAmAliveTime = now; - if (newStatus == SiloStatus.Active && orleansConfig.Globals.ValidateInitialConnectivity) + if (newStatus == SiloStatus.Active && this.membershipOptions.ValidateInitialConnectivity) await GetJoiningPreconditionPromise(table); TableVersion next = table.Version.Next(); @@ -683,7 +685,7 @@ private void KillMyselfLocally(string reason) DisposeTimers(); membershipOracleData.UpdateMyStatusLocal(SiloStatus.Dead); - if (!alreadyStopping || !orleansConfig.IsRunningAsUnitTest) + if (!alreadyStopping || !this.membershipOptions.IsRunningAsUnitTest) { logger.Fail(ErrorCode.MembershipKillMyselfLocally, msg); } @@ -697,7 +699,7 @@ private void GossipMyStatus() private void GossipToOthers(SiloAddress updatedSilo, SiloStatus updatedStatus) { - if (!orleansConfig.Globals.UseLivenessGossip) return; + if (!this.membershipOptions.UseLivenessGossip) return; // spread the rumor that some silo has just been marked dead foreach (var silo in membershipOracleData.GetSiloStatuses(IsFunctionalMBR, false).Keys) @@ -744,10 +746,10 @@ private void UpdateListOfProbedSilos() var silosToWatch = new List(); var additionalSilos = new List(); - for (int i = 0; i < tmpList.Count - 1 && silosToWatch.Count < orleansConfig.Globals.NumProbedSilos; i++) + for (int i = 0; i < tmpList.Count - 1 && silosToWatch.Count < this.membershipOptions.NumProbedSilos; i++) { SiloAddress candidate = tmpList[(myIndex + i + 1) % tmpList.Count]; - bool isSuspected = membershipOracleData.GetSiloEntry(candidate).GetFreshVotes(orleansConfig.Globals.DeathVoteExpirationTimeout).Count > 0; + bool isSuspected = membershipOracleData.GetSiloEntry(candidate).GetFreshVotes(this.membershipOptions.DeathVoteExpirationTimeout).Count > 0; if (isSuspected) { additionalSilos.Add(candidate); @@ -924,11 +926,11 @@ private void IncFailedProbes(SiloAddress silo, int pingNumber, Exception failure probedSilos[silo] = probedSilos[silo] + 1; if (logger.IsEnabled(LogLevel.Trace)) logger.Trace("-Current number of failed probes for {0}: {1}", silo.ToLongString(), probedSilos[silo]); - if (probedSilos[silo] < orleansConfig.Globals.NumMissedProbesLimit) + if (probedSilos[silo] < this.membershipOptions.NumMissedProbesLimit) return; MembershipExecuteWithRetries( - _ => TryToSuspectOrKill(silo), orleansConfig.Globals.MaxJoinAttemptTime) + _ => TryToSuspectOrKill(silo), this.membershipOptions.MaxJoinAttemptTime) .ContinueWith(task => { if (task.IsFaulted) @@ -990,15 +992,15 @@ private async Task TryToSuspectOrKill(SiloAddress silo) var allVotes = entry.SuspectTimes ?? new List>(); // get all valid (non-expired) votes - var freshVotes = entry.GetFreshVotes(orleansConfig.Globals.DeathVoteExpirationTimeout); + var freshVotes = entry.GetFreshVotes(this.membershipOptions.DeathVoteExpirationTimeout); if (logger.IsEnabled(LogLevel.Trace)) logger.Trace("-Current number of fresh Voters for {0} is {1}", silo.ToLongString(), freshVotes.Count.ToString()); - if (freshVotes.Count >= orleansConfig.Globals.NumVotesForDeathDeclaration) + if (freshVotes.Count >= this.membershipOptions.NumVotesForDeathDeclaration) { // this should not happen ... var str = String.Format("-Silo {0} is suspected by {1} which is more or equal than {2}, but is not marked as dead. This is a bug!!!", - entry.SiloAddress.ToLongString(), freshVotes.Count.ToString(), orleansConfig.Globals.NumVotesForDeathDeclaration.ToString()); + entry.SiloAddress.ToLongString(), freshVotes.Count.ToString(), this.membershipOptions.NumVotesForDeathDeclaration.ToString()); logger.Error(ErrorCode.Runtime_Error_100053, str); KillMyselfLocally("Found a bug 1! Will commit suicide."); return false; @@ -1015,7 +1017,7 @@ private async Task TryToSuspectOrKill(SiloAddress silo) bool declareDead = false; int myAdditionalVote = myVoteIndex == -1 ? 1 : 0; - if (freshVotes.Count + myAdditionalVote >= orleansConfig.Globals.NumVotesForDeathDeclaration) + if (freshVotes.Count + myAdditionalVote >= this.membershipOptions.NumVotesForDeathDeclaration) declareDead = true; if (freshVotes.Count + myAdditionalVote >= (activeSilos + 1) / 2) @@ -1028,8 +1030,8 @@ private async Task TryToSuspectOrKill(SiloAddress silo) "-Going to mark silo {0} as DEAD in the table #1. I am the last voter: #freshVotes={1}, myVoteIndex = {2}, NumVotesForDeathDeclaration={3} , #activeSilos={4}, suspect list={5}", entry.SiloAddress.ToLongString(), freshVotes.Count, - myVoteIndex, - orleansConfig.Globals.NumVotesForDeathDeclaration, + myVoteIndex, + this.membershipOptions.NumVotesForDeathDeclaration, activeSilos, PrintSuspectList(allVotes)); return await DeclareDead(entry, eTag, table.Version); @@ -1044,7 +1046,7 @@ private async Task TryToSuspectOrKill(SiloAddress silo) if (indexToWrite == -1) { // My vote is not recorded. Find the most outdated vote if the list is full, and overwrite it - if (allVotes.Count >= orleansConfig.Globals.NumVotesForDeathDeclaration) // if the list is full + if (allVotes.Count >= this.membershipOptions.NumVotesForDeathDeclaration) // if the list is full { // The list is full. DateTime minVoteTime = allVotes.Min(voter => voter.Item2); // pick the most outdated vote @@ -1078,7 +1080,7 @@ private async Task TryToSuspectOrKill(SiloAddress silo) private async Task DeclareDead(MembershipEntry entry, string etag, TableVersion tableVersion) { - if (orleansConfig.Globals.LivenessEnabled) + if (this.membershipOptions.LivenessEnabled) { // add the killer (myself) to the suspect list, for easier diagnosis later on. entry.AddSuspector(MyAddress, DateTime.UtcNow); diff --git a/src/Orleans.Runtime/MultiClusterNetwork/MultiClusterGossipChannelFactory.cs b/src/Orleans.Runtime/MultiClusterNetwork/MultiClusterGossipChannelFactory.cs index 33fb3ba83f..825860e367 100644 --- a/src/Orleans.Runtime/MultiClusterNetwork/MultiClusterGossipChannelFactory.cs +++ b/src/Orleans.Runtime/MultiClusterNetwork/MultiClusterGossipChannelFactory.cs @@ -1,23 +1,23 @@ -using System; +using System; using System.Collections.Generic; using System.Threading.Tasks; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; -using Orleans.Runtime.Configuration; +using Orleans.Hosting; namespace Orleans.Runtime.MultiClusterNetwork { internal class MultiClusterGossipChannelFactory { private readonly SiloOptions siloOptions; - private readonly GlobalConfiguration globalConfig; + private readonly MultiClusterOptions multiClusterOptions; private readonly IServiceProvider serviceProvider; private readonly ILogger logger; - public MultiClusterGossipChannelFactory(IOptions siloOptions, GlobalConfiguration globalConfig, IServiceProvider serviceProvider, ILogger logger) + public MultiClusterGossipChannelFactory(IOptions siloOptions, IOptions multiClusterOptions, IServiceProvider serviceProvider, ILogger logger) { this.siloOptions = siloOptions.Value; - this.globalConfig = globalConfig; + this.multiClusterOptions = multiClusterOptions.Value; this.serviceProvider = serviceProvider; this.logger = logger; } @@ -26,17 +26,16 @@ internal async Task> CreateGossipChannels() { List gossipChannels = new List(); - var channelConfigurations = this.globalConfig.GossipChannels; - if (channelConfigurations != null) + foreach(KeyValuePair channelConfig in this.multiClusterOptions.GossipChannels) { - logger.Info("Creating Gossip Channels."); - foreach (var channelConfiguration in channelConfigurations) + if (!string.IsNullOrWhiteSpace(channelConfig.Key)) { - switch (channelConfiguration.ChannelType) + logger.Info("Creating Gossip Channel."); + switch (channelConfig.Key) { - case GlobalConfiguration.GossipChannelType.AzureTable: + case MultiClusterOptions.BuiltIn.AzureTable: var tableChannel = AssemblyLoader.LoadAndCreateInstance(Constants.ORLEANS_CLUSTERING_AZURESTORAGE, logger, this.serviceProvider); - await tableChannel.Initialize(this.siloOptions.ServiceId, channelConfiguration.ConnectionString); + await tableChannel.Initialize(this.siloOptions.ServiceId, channelConfig.Value); gossipChannels.Add(tableChannel); break; @@ -44,7 +43,7 @@ internal async Task> CreateGossipChannels() break; } - logger.Info("Configured Gossip Channel: Type={0} ConnectionString={1}", channelConfiguration.ChannelType, channelConfiguration.ConnectionString); + logger.Info("Configured Gossip Channel: Type={0}", channelConfig.Key); } } diff --git a/src/Orleans.Runtime/Placement/ActivationCountPlacementDirector.cs b/src/Orleans.Runtime/Placement/ActivationCountPlacementDirector.cs index 333c910c6a..c81d864ee1 100644 --- a/src/Orleans.Runtime/Placement/ActivationCountPlacementDirector.cs +++ b/src/Orleans.Runtime/Placement/ActivationCountPlacementDirector.cs @@ -5,11 +5,12 @@ using System.Threading; using System.Threading.Tasks; using Microsoft.Extensions.Logging; -using Orleans.Runtime.Configuration; +using Microsoft.Extensions.Options; +using Orleans.Hosting; namespace Orleans.Runtime.Placement { - internal class ActivationCountPlacementDirector : RandomPlacementDirector, ISiloStatisticsChangeListener, IPlacementDirector + internal class ActivationCountPlacementDirector : RandomPlacementDirector, ISiloStatisticsChangeListener, IPlacementDirector { private class CachedLocalStat { @@ -43,16 +44,16 @@ public void IncrementActivationCount(int delta) private readonly SafeRandom random = new SafeRandom(); private int chooseHowMany = 2; - public ActivationCountPlacementDirector(DeploymentLoadPublisher deploymentLoadPublisher, GlobalConfiguration globalConfig, ILogger logger) + public ActivationCountPlacementDirector(DeploymentLoadPublisher deploymentLoadPublisher, IOptions options, ILogger logger) { this.logger = logger; SelectSilo = SelectSiloPowerOfK; - if (globalConfig.ActivationCountBasedPlacementChooseOutOf <= 0) + if (options.Value.ActivationCountPlacementChooseOutOf <= 0) throw new ArgumentException( - "GlobalConfig.ActivationCountBasedPlacementChooseOutOf is " + globalConfig.ActivationCountBasedPlacementChooseOutOf); + "GlobalConfig.ActivationCountBasedPlacementChooseOutOf is " + options.Value.ActivationCountPlacementChooseOutOf); - chooseHowMany = globalConfig.ActivationCountBasedPlacementChooseOutOf; + chooseHowMany = options.Value.ActivationCountPlacementChooseOutOf; deploymentLoadPublisher?.SubscribeToStatisticsChangeEvents(this); } diff --git a/src/Orleans.Runtime/Placement/DeploymentLoadPublisher.cs b/src/Orleans.Runtime/Placement/DeploymentLoadPublisher.cs index d9d18d6eec..c4d814a6b5 100644 --- a/src/Orleans.Runtime/Placement/DeploymentLoadPublisher.cs +++ b/src/Orleans.Runtime/Placement/DeploymentLoadPublisher.cs @@ -4,6 +4,8 @@ using System.Linq; using System.Threading.Tasks; using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Options; +using Orleans.Hosting; using Orleans.Runtime.Configuration; using Orleans.Runtime.Scheduler; @@ -32,7 +34,7 @@ internal class DeploymentLoadPublisher : SystemTarget, IDeploymentLoadPublisher, ILocalSiloDetails siloDetails, ISiloPerformanceMetrics siloMetrics, ISiloStatusOracle siloStatusOracle, - GlobalConfiguration config, + IOptions statisticsOptions, IInternalGrainFactory grainFactory, OrleansTaskScheduler scheduler, ILoggerFactory loggerFactory) @@ -44,7 +46,7 @@ internal class DeploymentLoadPublisher : SystemTarget, IDeploymentLoadPublisher, this.siloStatusOracle = siloStatusOracle; this.grainFactory = grainFactory; this.scheduler = scheduler; - statisticsRefreshTime = config.DeploymentLoadPublisherRefreshTime; + statisticsRefreshTime = statisticsOptions.Value.DeploymentLoadPublisherRefreshTime; periodicStats = new ConcurrentDictionary(); siloStatisticsChangeListeners = new List(); } diff --git a/src/Orleans.Runtime/Placement/HashBasedPlacementDirector.cs b/src/Orleans.Runtime/Placement/HashBasedPlacementDirector.cs index 2519269566..1b25858b39 100644 --- a/src/Orleans.Runtime/Placement/HashBasedPlacementDirector.cs +++ b/src/Orleans.Runtime/Placement/HashBasedPlacementDirector.cs @@ -1,9 +1,9 @@ -using System.Linq; +using System.Linq; using System.Threading.Tasks; namespace Orleans.Runtime.Placement { - internal class HashBasedPlacementDirector : IPlacementDirector + internal class HashBasedPlacementDirector : IPlacementDirector { public virtual Task OnAddActivation( PlacementStrategy strategy, PlacementTarget target, IPlacementContext context) diff --git a/src/Orleans.Runtime/Placement/IActivationSelector.cs b/src/Orleans.Runtime/Placement/IActivationSelector.cs index 6a2c109848..0ed8d8cb39 100644 --- a/src/Orleans.Runtime/Placement/IActivationSelector.cs +++ b/src/Orleans.Runtime/Placement/IActivationSelector.cs @@ -1,4 +1,4 @@ -using System.Collections.Generic; + using System.Threading.Tasks; namespace Orleans.Runtime.Placement @@ -14,13 +14,4 @@ internal interface IActivationSelector bool TrySelectActivationSynchronously( PlacementStrategy strategy, GrainId target, IPlacementRuntime context, out PlacementResult placementResult); } - - /// - /// Interface for activation selectors implementing the specified strategy. - /// - /// The placement strategy which this selector implements. - internal interface IActivationSelector : IActivationSelector - where TStrategy : PlacementStrategy - { - } } diff --git a/src/Orleans.Runtime/Placement/PlacementDirectorsManager.cs b/src/Orleans.Runtime/Placement/PlacementDirectorsManager.cs index 97aa9c74cc..bd995eb2ec 100644 --- a/src/Orleans.Runtime/Placement/PlacementDirectorsManager.cs +++ b/src/Orleans.Runtime/Placement/PlacementDirectorsManager.cs @@ -18,11 +18,11 @@ internal class PlacementDirectorsManager public PlacementDirectorsManager( IServiceProvider services, - DefaultPlacementStrategy defaultPlacementStrategy, + PlacementStrategy defaultPlacementStrategy, ClientObserversPlacementDirector clientObserversPlacementDirector) { this.serviceProvider = services; - this.defaultPlacementStrategy = defaultPlacementStrategy.PlacementStrategy; + this.defaultPlacementStrategy = defaultPlacementStrategy; this.clientObserversPlacementDirector = clientObserversPlacementDirector; this.ResolveBuiltInStrategies(); // TODO: Make default selector configurable @@ -35,8 +35,7 @@ private IPlacementDirector ResolveDirector(PlacementStrategy strategy) var strategyType = strategy.GetType(); if (!this.directors.TryGetValue(strategyType, out result)) { - var directorType = typeof(IPlacementDirector<>).MakeGenericType(strategyType); - result = (IPlacementDirector)this.serviceProvider.GetRequiredService(directorType); + result = this.serviceProvider.GetRequiredServiceByKey(strategyType); this.directors[strategyType] = result; } @@ -49,8 +48,7 @@ private IActivationSelector ResolveSelector(PlacementStrategy strategy, bool add var strategyType = strategy.GetType(); if (!this.selectors.TryGetValue(strategyType, out result) && addIfDoesNotExist) { - var directorType = typeof(IActivationSelector<>).MakeGenericType(strategyType); - result = (IActivationSelector)this.serviceProvider.GetRequiredService(directorType); + result = this.serviceProvider.GetRequiredServiceByKey(strategyType); this.selectors[strategyType] = result; } diff --git a/src/Orleans.Runtime/Placement/PlacementStrategyFactory.cs b/src/Orleans.Runtime/Placement/PlacementStrategyFactory.cs new file mode 100644 index 0000000000..b60a26eea4 --- /dev/null +++ b/src/Orleans.Runtime/Placement/PlacementStrategyFactory.cs @@ -0,0 +1,16 @@ +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; +using Orleans.Hosting; +using System; + +namespace Orleans.Runtime.Placement +{ + internal static class PlacementStrategyFactory + { + public static PlacementStrategy Create(IServiceProvider services) + { + IOptions grainPlacementOptions = services.GetRequiredService>(); + return services.GetRequiredServiceByName(grainPlacementOptions.Value.DefaultPlacementStrategy); + } + } +} diff --git a/src/Orleans.Runtime/Placement/PreferLocalPlacementDirector.cs b/src/Orleans.Runtime/Placement/PreferLocalPlacementDirector.cs index 3407ff3ab0..ff2b4cd246 100644 --- a/src/Orleans.Runtime/Placement/PreferLocalPlacementDirector.cs +++ b/src/Orleans.Runtime/Placement/PreferLocalPlacementDirector.cs @@ -10,7 +10,7 @@ namespace Orleans.Runtime.Placement /// If none exits, it prefers to place a new one in the local silo. If there are no races (only one silo at a time tries to activate this grain), /// the the local silo wins. In the case of concurrent activations of the first activation of this grain, only one silo wins. /// - internal class PreferLocalPlacementDirector : RandomPlacementDirector, IPlacementDirector + internal class PreferLocalPlacementDirector : RandomPlacementDirector, IPlacementDirector { private Task cachedLocalSilo; diff --git a/src/Orleans.Runtime/Placement/RandomPlacementDirector.cs b/src/Orleans.Runtime/Placement/RandomPlacementDirector.cs index 38dedb2664..94db474b63 100644 --- a/src/Orleans.Runtime/Placement/RandomPlacementDirector.cs +++ b/src/Orleans.Runtime/Placement/RandomPlacementDirector.cs @@ -5,7 +5,7 @@ namespace Orleans.Runtime.Placement { - internal class RandomPlacementDirector : IPlacementDirector, IActivationSelector + internal class RandomPlacementDirector : IPlacementDirector, IActivationSelector { private readonly SafeRandom random = new SafeRandom(); diff --git a/src/Orleans.Runtime/Placement/StatelessWorkerDirector.cs b/src/Orleans.Runtime/Placement/StatelessWorkerDirector.cs index 13de937796..ad46606fa9 100644 --- a/src/Orleans.Runtime/Placement/StatelessWorkerDirector.cs +++ b/src/Orleans.Runtime/Placement/StatelessWorkerDirector.cs @@ -5,7 +5,7 @@ namespace Orleans.Runtime.Placement { - internal class StatelessWorkerDirector : IPlacementDirector, IActivationSelector + internal class StatelessWorkerDirector : IPlacementDirector, IActivationSelector { private static readonly SafeRandom random = new SafeRandom(); diff --git a/src/Orleans.Runtime/ReminderService/GrainBasedReminderTable.cs b/src/Orleans.Runtime/ReminderService/GrainBasedReminderTable.cs index b9ab3641f1..3f6dd98b6c 100644 --- a/src/Orleans.Runtime/ReminderService/GrainBasedReminderTable.cs +++ b/src/Orleans.Runtime/ReminderService/GrainBasedReminderTable.cs @@ -25,7 +25,7 @@ public override Task OnActivateAsync() return Task.CompletedTask; } - public Task Init(GlobalConfiguration config) + public Task Init() { return Task.CompletedTask; } diff --git a/src/Orleans.Runtime/ReminderService/LocalReminderService.cs b/src/Orleans.Runtime/ReminderService/LocalReminderService.cs index 9b9c9a877f..c5bc53cda0 100644 --- a/src/Orleans.Runtime/ReminderService/LocalReminderService.cs +++ b/src/Orleans.Runtime/ReminderService/LocalReminderService.cs @@ -3,10 +3,8 @@ using System.Diagnostics; using System.Linq; using System.Threading.Tasks; -using Orleans.Runtime.Configuration; using Orleans.Runtime.Scheduler; using Microsoft.Extensions.Logging; -using Microsoft.Extensions.DependencyInjection; namespace Orleans.Runtime.ReminderService { @@ -26,22 +24,19 @@ internal class LocalReminderService : GrainService, IReminderService private readonly ILoggerFactory loggerFactory; private readonly AverageTimeSpanStatistic tardinessStat; private readonly CounterStatistic ticksDeliveredStat; - private readonly GlobalConfiguration config; private readonly TimeSpan initTimeout; internal LocalReminderService( Silo silo, GrainId id, IReminderTable reminderTable, - GlobalConfiguration config, TimeSpan initTimeout, ILoggerFactory loggerFactory) - : base(id, silo, null, loggerFactory) + : base(id, silo, loggerFactory) { this.timerLogger = loggerFactory.CreateLogger(); localReminders = new Dictionary(); this.reminderTable = reminderTable; - this.config = config; this.initTimeout = initTimeout; localTableSequence = 0; this.loggerFactory = loggerFactory; @@ -61,11 +56,12 @@ internal class LocalReminderService : GrainService, IReminderService public override async Task Start() { // confirm that it can access the underlying store, as after this the ReminderService will load in the background, without the opportunity to prevent the Silo from starting - await reminderTable.Init(config).WithTimeout(initTimeout); + await reminderTable.Init().WithTimeout(initTimeout); await base.Start(); } + public async override Task Stop() { await base.Stop(); diff --git a/src/Orleans.Runtime/ReminderService/LocalReminderServiceFactory.cs b/src/Orleans.Runtime/ReminderService/LocalReminderServiceFactory.cs index b68d522538..eb6fa73560 100644 --- a/src/Orleans.Runtime/ReminderService/LocalReminderServiceFactory.cs +++ b/src/Orleans.Runtime/ReminderService/LocalReminderServiceFactory.cs @@ -32,7 +32,7 @@ public LocalReminderServiceFactory(IReminderTable reminderTable, ILoggerFactory var typeCode = GrainInterfaceUtils.GetGrainClassTypeCode(typeof(IReminderService)); var grainId = GrainId.GetGrainServiceGrainId(0, typeCode); - return new LocalReminderService(silo, grainId, this.reminderTable, silo.GlobalConfig, iniTimeSpan, this.loggerFactory); + return new LocalReminderService(silo, grainId, this.reminderTable, iniTimeSpan, this.loggerFactory); } } } \ No newline at end of file diff --git a/src/Orleans.Runtime/ReminderService/MockReminderTable.cs b/src/Orleans.Runtime/ReminderService/MockReminderTable.cs index 822e821572..643cbda37f 100644 --- a/src/Orleans.Runtime/ReminderService/MockReminderTable.cs +++ b/src/Orleans.Runtime/ReminderService/MockReminderTable.cs @@ -1,7 +1,5 @@ using System; using System.Threading.Tasks; -using Orleans.Runtime.Configuration; -using Microsoft.Extensions.Logging; namespace Orleans.Runtime.ReminderService { @@ -14,8 +12,7 @@ public MockReminderTable(TimeSpan delay) { this.delay = delay; } - - public Task Init(GlobalConfiguration config) + public Task Init() { return Task.CompletedTask; } diff --git a/src/Orleans.Runtime/ReminderService/ReminderTableFactory.cs b/src/Orleans.Runtime/ReminderService/ReminderTableFactory.cs index 5e7cef6c15..758756b726 100644 --- a/src/Orleans.Runtime/ReminderService/ReminderTableFactory.cs +++ b/src/Orleans.Runtime/ReminderService/ReminderTableFactory.cs @@ -1,23 +1,24 @@ using System; using Microsoft.Extensions.Logging; -using Orleans.Runtime.Configuration; +using Microsoft.Extensions.Options; +using Orleans.Hosting; namespace Orleans.Runtime.ReminderService { internal class ReminderTableFactory { - private readonly GlobalConfiguration globalConfiguration; + private readonly ReminderOptions options; private readonly IGrainFactory grainFactory; private readonly IServiceProvider serviceProvider; private readonly ILogger logger; public ReminderTableFactory( - GlobalConfiguration globalConfiguration, + IOptions options, IGrainFactory grainFactory, IServiceProvider serviceProvider, ILogger logger) { - this.globalConfiguration = globalConfiguration; + this.options = options.Value; this.grainFactory = grainFactory; this.logger = logger; this.serviceProvider = serviceProvider; @@ -25,33 +26,33 @@ internal class ReminderTableFactory public IReminderTable Create() { - var config = this.globalConfiguration; - var serviceType = config.ReminderServiceType; + var serviceType = this.options.ReminderService; switch (serviceType) { - default: - throw new NotSupportedException( - $"The reminder table does not currently support service provider {serviceType}."); - case GlobalConfiguration.ReminderServiceProviderType.SqlServer: + case ReminderOptions.BuiltIn.SqlServer: return AssemblyLoader.LoadAndCreateInstance( Constants.ORLEANS_REMINDERS_ADONET, logger, this.serviceProvider); - case GlobalConfiguration.ReminderServiceProviderType.AzureTable: + case ReminderOptions.BuiltIn.AzureTable: return AssemblyLoader.LoadAndCreateInstance( Constants.ORLEANS_REMINDERS_AZURESTORAGE, logger, this.serviceProvider); - case GlobalConfiguration.ReminderServiceProviderType.ReminderTableGrain: + case ReminderOptions.BuiltIn.ReminderTableGrain: return this.grainFactory.GetGrain(Constants.ReminderTableGrainId); - case GlobalConfiguration.ReminderServiceProviderType.MockTable: - return new MockReminderTable(config.MockReminderTableTimeout); - case GlobalConfiguration.ReminderServiceProviderType.Custom: + case ReminderOptions.BuiltIn.MockTable: + return new MockReminderTable(this.options.MockReminderTableTimeout); + case ReminderOptions.BuiltIn.Custom: return AssemblyLoader.LoadAndCreateInstance( - config.ReminderTableAssembly, + this.options.ReminderTableAssembly, logger, this.serviceProvider); + default: + throw new NotSupportedException( + $"The reminder table does not currently support service provider {serviceType}."); + } } } diff --git a/src/Orleans.Runtime/Scheduler/OrleansTaskScheduler.cs b/src/Orleans.Runtime/Scheduler/OrleansTaskScheduler.cs index 97ad4e1f4e..b2cbcb63ed 100644 --- a/src/Orleans.Runtime/Scheduler/OrleansTaskScheduler.cs +++ b/src/Orleans.Runtime/Scheduler/OrleansTaskScheduler.cs @@ -6,8 +6,8 @@ using System.Text; using System.Threading.Tasks; using Microsoft.Extensions.Logging; -using Orleans.Runtime.Configuration; -using Orleans.Runtime.Counters; +using Microsoft.Extensions.Options; +using Orleans.Hosting; namespace Orleans.Runtime.Scheduler { @@ -24,7 +24,8 @@ internal class OrleansTaskScheduler : TaskScheduler, ITaskScheduler, IHealthChec internal WorkerPool Pool { get; private set; } internal static TimeSpan TurnWarningLengthThreshold { get; set; } // This is the maximum number of pending work items for a single activation before we write a warning log. - internal LimitValue MaxPendingItemsLimit { get; private set; } + internal int MaxPendingItemsSoftLimit { get; private set; } + internal int MaxPendingItemsHardLimit { get; private set; } internal TimeSpan DelayWarningThreshold { get; private set; } public int RunQueueLength { get { return RunQueue.Length; } } @@ -36,22 +37,23 @@ public static OrleansTaskScheduler CreateTestInstance(int maxActiveThreads, ICor TimeSpan.FromMilliseconds(100), TimeSpan.FromMilliseconds(100), TimeSpan.FromMilliseconds(100), - NodeConfiguration.ENABLE_WORKER_THREAD_INJECTION, - LimitManager.GetDefaultLimit(LimitNames.LIMIT_MAX_PENDING_ITEMS), + SchedulingOptions.DEFAULT_ENABLE_WORKER_THREAD_INJECTION, + SchedulingOptions.DEFAULT_MAX_PENDING_ITEMS_SOFT_LIMIT, + SchedulingOptions.DEFAULT_MAX_PENDING_ITEMS_HARD_LIMIT, performanceMetrics, new ExecutorService(), loggerFactory); } - public OrleansTaskScheduler(NodeConfiguration config, ICorePerformanceMetrics performanceMetrics, ExecutorService executorService, ILoggerFactory loggerFactory) - : this(config.MaxActiveThreads, config.DelayWarningThreshold, config.ActivationSchedulingQuantum, - config.TurnWarningLengthThreshold, config.EnableWorkerThreadInjection, config.LimitManager.GetLimit(LimitNames.LIMIT_MAX_PENDING_ITEMS), - performanceMetrics, executorService, loggerFactory) + public OrleansTaskScheduler(IOptions options, ICorePerformanceMetrics performanceMetrics, ExecutorService executorService, ILoggerFactory loggerFactory) + : this(options.Value.MaxActiveThreads, options.Value.DelayWarningThreshold, options.Value.ActivationSchedulingQuantum, + options.Value.TurnWarningLengthThreshold, options.Value.EnableWorkerThreadInjection, options.Value.MaxPendingWorkItemsSoftLimit, + options.Value.MaxPendingWorkItemsHardLimit, performanceMetrics, executorService, loggerFactory) { } private OrleansTaskScheduler(int maxActiveThreads, TimeSpan delayWarningThreshold, TimeSpan activationSchedulingQuantum, - TimeSpan turnWarningLengthThreshold, bool injectMoreWorkerThreads, LimitValue maxPendingItemsLimit, + TimeSpan turnWarningLengthThreshold, bool injectMoreWorkerThreads, int maxPendingItemsSoftLimit, int maxPendingItemsHardLimit, ICorePerformanceMetrics performanceMetrics, ExecutorService executorService, ILoggerFactory loggerFactory) { this.logger = loggerFactory.CreateLogger(); @@ -60,7 +62,8 @@ public OrleansTaskScheduler(NodeConfiguration config, ICorePerformanceMetrics pe WorkItemGroup.ActivationSchedulingQuantum = activationSchedulingQuantum; TurnWarningLengthThreshold = turnWarningLengthThreshold; applicationTurnsStopped = false; - MaxPendingItemsLimit = maxPendingItemsLimit; + this.MaxPendingItemsSoftLimit = maxPendingItemsSoftLimit; + this.MaxPendingItemsHardLimit = maxPendingItemsHardLimit; workgroupDirectory = new ConcurrentDictionary(); RunQueue = new WorkQueue(); this.taskWorkItemLogger = loggerFactory.CreateLogger(); diff --git a/src/Orleans.Runtime/Scheduler/SchedulingOptions.cs b/src/Orleans.Runtime/Scheduler/SchedulingOptions.cs deleted file mode 100644 index 6545cc1053..0000000000 --- a/src/Orleans.Runtime/Scheduler/SchedulingOptions.cs +++ /dev/null @@ -1,18 +0,0 @@ -namespace Orleans.Runtime.Scheduler -{ - /// - /// Options for configuring scheduler behavior. - /// - public class SchedulingOptions - { - /// - /// Whether or not to perform deadlock detection. - /// - public bool PerformDeadlockDetection { get; set; } - - /// - /// Whether or not to allow reentrancy for calls within the same call chain. - /// - public bool AllowCallChainReentrancy { get; set; } - } -} \ No newline at end of file diff --git a/src/Orleans.Runtime/Scheduler/WorkItemGroup.cs b/src/Orleans.Runtime/Scheduler/WorkItemGroup.cs index 65d6a01aab..24e6d21f93 100644 --- a/src/Orleans.Runtime/Scheduler/WorkItemGroup.cs +++ b/src/Orleans.Runtime/Scheduler/WorkItemGroup.cs @@ -199,7 +199,7 @@ public void EnqueueTask(Task task) SchedulerStatisticsGroup.OnWorkItemEnqueue(); #endif workItems.Enqueue(task); - int maxPendingItemsLimit = masterScheduler.MaxPendingItemsLimit.SoftLimitThreshold; + int maxPendingItemsLimit = masterScheduler.MaxPendingItemsSoftLimit; if (maxPendingItemsLimit > 0 && count > maxPendingItemsLimit) { log.Warn(ErrorCode.SchedulerTooManyPendingItems, String.Format("{0} pending work items for group {1}, exceeding the warning threshold of {2}", diff --git a/src/Orleans.Runtime/Services/GrainService.cs b/src/Orleans.Runtime/Services/GrainService.cs index 61ff8045b6..9d760f896f 100644 --- a/src/Orleans.Runtime/Services/GrainService.cs +++ b/src/Orleans.Runtime/Services/GrainService.cs @@ -36,9 +36,6 @@ protected GrainServiceStatus Status } } - /// Configuration of service - protected IGrainServiceConfiguration Config { get; private set; } - /// Only to make Reflection happy protected GrainService() : base(null, null, null) { @@ -46,7 +43,7 @@ protected GrainService() : base(null, null, null) } /// Constructor to use for grain services - protected GrainService(IGrainIdentity grainId, Silo silo, IGrainServiceConfiguration config, ILoggerFactory loggerFactory) : base((GrainId)grainId, silo.SiloAddress, lowPriority: true, loggerFactory:loggerFactory) + protected GrainService(IGrainIdentity grainId, Silo silo, ILoggerFactory loggerFactory) : base((GrainId)grainId, silo.SiloAddress, lowPriority: true, loggerFactory:loggerFactory) { typeName = this.GetType().FullName; Logger = loggerFactory.CreateLogger(typeName); @@ -54,7 +51,6 @@ protected GrainService(IGrainIdentity grainId, Silo silo, IGrainServiceConfigura scheduler = silo.LocalScheduler; ring = silo.RingProvider; StoppedCancellationTokenSource = new CancellationTokenSource(); - Config = config; } /// Invoked upon initialization of the service diff --git a/src/Orleans.Runtime/Silo/LocalSiloDetails.cs b/src/Orleans.Runtime/Silo/LocalSiloDetails.cs index eae3ccf02f..5cd69f07c4 100644 --- a/src/Orleans.Runtime/Silo/LocalSiloDetails.cs +++ b/src/Orleans.Runtime/Silo/LocalSiloDetails.cs @@ -36,7 +36,7 @@ private static IPEndPoint ResolveEndpoint(EndpointOptions options) else { // TODO: refactor this out of ClusterConfiguration - ipAddress = ClusterConfiguration.ResolveIPAddress(options.HostNameOrIPAddress, null, AddressFamily.InterNetwork).GetAwaiter().GetResult(); + ipAddress = ConfigUtilities.ResolveIPAddress(options.HostNameOrIPAddress, null, AddressFamily.InterNetwork).GetAwaiter().GetResult(); } return new IPEndPoint(ipAddress, options.Port); diff --git a/src/Orleans.Runtime/Silo/Silo.cs b/src/Orleans.Runtime/Silo/Silo.cs index a7a7b3f7dc..2a4f5dc4ba 100644 --- a/src/Orleans.Runtime/Silo/Silo.cs +++ b/src/Orleans.Runtime/Silo/Silo.cs @@ -53,7 +53,6 @@ public enum SiloType } private readonly ILocalSiloDetails siloDetails; - private readonly LegacyConfigurationWrapper legacyConfiguration; private readonly SiloOptions siloOptions; private readonly ISiloMessageCenter messageCenter; private readonly OrleansTaskScheduler scheduler; @@ -88,8 +87,6 @@ public enum SiloType /// Gets the type of this /// internal string Name => this.siloDetails.Name; - internal GlobalConfiguration GlobalConfig => this.legacyConfiguration.ClusterConfig.Globals; - internal NodeConfiguration LocalConfig => this.legacyConfiguration.NodeConfig; internal OrleansTaskScheduler LocalScheduler { get { return scheduler; } } internal ILocalGrainDirectory LocalGrainDirectory { get { return localGrainDirectory; } } internal IMultiClusterOracle LocalMultiClusterOracle { get { return multiClusterOracle; } } @@ -127,19 +124,20 @@ public Silo(ILocalSiloDetails siloDetails, IServiceProvider services) { string name = siloDetails.Name; // Temporarily still require this. Hopefuly gone when 2.0 is released. - this.legacyConfiguration = services.GetRequiredService(); this.siloDetails = siloDetails; this.SystemStatus = SystemStatus.Creating; AsynchAgent.IsStarting = true; var startTime = DateTime.UtcNow; - StatisticsCollector.Initialize(LocalConfig.StatisticsCollectionLevel); - - initTimeout = GlobalConfig.MaxJoinAttemptTime; + IOptions statisticsOptions = services.GetRequiredService>(); + StatisticsCollector.Initialize(statisticsOptions.Value.CollectionLevel); + + IOptions membershipOptions = services.GetRequiredService>(); + initTimeout = membershipOptions.Value.MaxJoinAttemptTime; if (Debugger.IsAttached) { - initTimeout = StandardExtensions.Max(TimeSpan.FromMinutes(10), GlobalConfig.MaxJoinAttemptTime); + initTimeout = StandardExtensions.Max(TimeSpan.FromMinutes(10), membershipOptions.Value.MaxJoinAttemptTime); stopTimeout = initTimeout; } @@ -149,8 +147,9 @@ public Silo(ILocalSiloDetails siloDetails, IServiceProvider services) this.Services = services; this.Services.InitializeSiloUnobservedExceptionsHandler(); - //set PropagateActivityId flag from node cofnig - RequestContext.PropagateActivityId = this.legacyConfiguration.NodeConfig.PropagateActivityId; + //set PropagateActivityId flag from node config + IOptions messagingOptions = services.GetRequiredService>(); + RequestContext.PropagateActivityId = messagingOptions.Value.PropagateActivityId; this.loggerFactory = this.Services.GetRequiredService(); logger = this.loggerFactory.CreateLogger(); @@ -161,13 +160,12 @@ public Silo(ILocalSiloDetails siloDetails, IServiceProvider services) logger.Warn(ErrorCode.SiloGcWarning, "Note: ServerGC only kicks in on multi-core systems (settings enabling ServerGC have no effect on single-core machines)."); } - logger.Info(ErrorCode.SiloInitializing, "-------------- Initializing {0} silo on host {1} MachineName {2} at {3}, gen {4} --------------", - this.legacyConfiguration.Type, this.siloDetails.DnsHostName, Environment.MachineName, localEndpoint, this.siloDetails.SiloAddress.Generation); - logger.Info(ErrorCode.SiloInitConfig, "Starting silo {0} with the following configuration= " + Environment.NewLine + "{1}", - name, this.legacyConfiguration.ClusterConfig.ToString(name)); + logger.Info(ErrorCode.SiloInitializing, "-------------- Initializing silo on host {0} MachineName {1} at {2}, gen {3} --------------", + this.siloDetails.DnsHostName, Environment.MachineName, localEndpoint, this.siloDetails.SiloAddress.Generation); + logger.Info(ErrorCode.SiloInitConfig, "Starting silo {0}", name); var siloMessagingOptions = this.Services.GetRequiredService>(); - BufferPool.InitGlobalBufferPool(siloMessagingOptions); + BufferPool.InitGlobalBufferPool(siloMessagingOptions.Value); try { @@ -308,7 +306,8 @@ private void CreateSystemTargets() var implicitStreamSubscriberTable = Services.GetRequiredService(); var versionDirectorManager = this.Services.GetRequiredService(); var grainTypeManager = this.Services.GetRequiredService(); - typeManager = new TypeManager(SiloAddress, grainTypeManager, membershipOracle, LocalScheduler, GlobalConfig.TypeMapRefreshInterval, implicitStreamSubscriberTable, this.grainFactory, versionDirectorManager, + IOptions typeManagementOptions = this.Services.GetRequiredService>(); + typeManager = new TypeManager(SiloAddress, grainTypeManager, membershipOracle, LocalScheduler, typeManagementOptions.Value.TypeMapRefreshInterval, implicitStreamSubscriberTable, this.grainFactory, versionDirectorManager, this.loggerFactory); this.RegisterSystemTarget(typeManager); @@ -351,7 +350,8 @@ private async Task InjectDependencies() this.membershipOracle.SubscribeToSiloStatusEvents(Services.GetRequiredService()); - if (!GlobalConfig.ReminderServiceType.Equals(GlobalConfiguration.ReminderServiceProviderType.Disabled)) + IOptions reminderOptions = this.Services.GetRequiredService>(); + if (!reminderOptions.Value.ReminderService.Equals(ReminderOptions.BuiltIn.Disabled)) { // start the reminder service system target reminderService = Services.GetRequiredService() @@ -384,7 +384,7 @@ private Task OnRuntimeInitializeStart(CancellationToken ct) // Hook up to receive notification of process exit / Ctrl-C events AppDomain.CurrentDomain.ProcessExit += HandleProcessExit; - if (GlobalConfig.FastKillOnCancelKeyPress) + if (this.siloOptions.FastKillOnCancelKeyPress) Console.CancelKeyPress += HandleProcessExit; //TODO: setup thead pool directly to lifecycle StartTaskWithPerfAnalysis("ConfigureThreadPoolAndServicePointSettings", @@ -439,7 +439,7 @@ void InitImplicitStreamSubscribeTable() var siloProviderRuntime = Services.GetRequiredService(); - StatisticsOptions statisticsOptions = Services.GetRequiredService>().Value; + SiloStatisticsOptions statisticsOptions = Services.GetRequiredService>().Value; runtimeClient.CurrentStreamProviderRuntime = siloProviderRuntime; await StartAsyncTaskWithPerfAnalysis("Load StatisticProviders", LoadStatsProvider, stopWatch); async Task LoadStatsProvider() @@ -457,7 +457,8 @@ async Task LoadStatsProvider() }, stopWatch); // Validate the configuration. - GlobalConfig.Application.ValidateConfiguration(logger); + // TODO - refactor validation - jbragg + //GlobalConfig.Application.ValidateConfiguration(logger); } private async Task OnRuntimeGrainServicesStart(CancellationToken ct) @@ -474,8 +475,9 @@ await scheduler.QueueTask(transactionAgent.Start, transactionAgentContext) } // Load and init grain services before silo becomes active. + GrainServiceOptions grainServiceOptions = Services.GetRequiredService>().Value; await StartAsyncTaskWithPerfAnalysis("Init grain services", - () => CreateGrainServices(GlobalConfig.GrainServiceConfigurations), stopWatch); + () => CreateGrainServices(grainServiceOptions), stopWatch); this.membershipOracleContext = (this.membershipOracle as SystemTarget)?.SchedulingContext ?? this.fallbackScheduler.SchedulingContext; @@ -516,7 +518,7 @@ await scheduler.QueueTask(() => multiClusterOracle.Start(), multiClusterOracleCo try { - StatisticsOptions statisticsOptions = Services.GetRequiredService>().Value; + SiloStatisticsOptions statisticsOptions = Services.GetRequiredService>().Value; StartTaskWithPerfAnalysis("Start silo statistics", () => this.siloStatistics.Start(statisticsOptions), stopWatch); logger.Debug("Silo statistics manager started successfully."); @@ -532,7 +534,7 @@ await this.scheduler.QueueTask(deploymentLoadPublisher.Start, deploymentLoadPubl // Start background timer tick to watch for platform execution stalls, such as when GC kicks in - this.platformWatchdog = new Watchdog(this.LocalConfig.StatisticsLogWriteInterval, this.healthCheckParticipants, this.executorService, this.loggerFactory); + this.platformWatchdog = new Watchdog(statisticsOptions.LogWriteInterval, this.healthCheckParticipants, this.executorService, this.loggerFactory); this.platformWatchdog.Start(); if (this.logger.IsEnabled(LogLevel.Debug)) { logger.Debug("Silo platform watchdog started successfully."); } @@ -568,50 +570,51 @@ void StartGateway() if (logger.IsEnabled(LogLevel.Debug)) { logger.Debug("Silo.Start complete: System status = {0}", this.SystemStatus); } } - private async Task CreateGrainServices(GrainServiceConfigurations grainServiceConfigurations) + private async Task CreateGrainServices(GrainServiceOptions grainServiceOptions) { - foreach (var serviceConfig in grainServiceConfigurations.GrainServices) + foreach (KeyValuePair serviceConfig in grainServiceOptions.GrainServices) { // Construct the Grain Service - var serviceType = System.Type.GetType(serviceConfig.Value.ServiceType); + var serviceType = System.Type.GetType(serviceConfig.Key); if (serviceType == null) { - throw new Exception(String.Format("Cannot find Grain Service type {0} of Grain Service {1}", serviceConfig.Value.ServiceType, serviceConfig.Value.Name)); + throw new Exception(String.Format("Cannot find Grain Service type {0} of with Service Id {1}", serviceConfig.Key, serviceConfig.Value)); } var grainServiceInterfaceType = serviceType.GetInterfaces().FirstOrDefault(x => x.GetInterfaces().Contains(typeof(IGrainService))); if (grainServiceInterfaceType == null) { - throw new Exception(String.Format("Cannot find an interface on {0} which implements IGrainService", serviceConfig.Value.ServiceType)); + throw new Exception(String.Format("Cannot find an interface on {0} which implements IGrainService", serviceConfig.Value)); } var typeCode = GrainInterfaceUtils.GetGrainClassTypeCode(grainServiceInterfaceType); - var grainId = (IGrainIdentity)GrainId.GetGrainServiceGrainId(0, typeCode); - var grainService = (GrainService)ActivatorUtilities.CreateInstance(this.Services, serviceType, grainId, serviceConfig.Value); + var grainId = (IGrainIdentity)GrainId.GetGrainServiceGrainId(serviceConfig.Value, typeCode); + var grainService = (GrainService)ActivatorUtilities.CreateInstance(this.Services, serviceType, grainId); RegisterSystemTarget(grainService); await this.scheduler.QueueTask(() => grainService.Init(Services), grainService.SchedulingContext).WithTimeout(this.initTimeout); await this.scheduler.QueueTask(grainService.Start, grainService.SchedulingContext).WithTimeout(this.initTimeout); if (this.logger.IsEnabled(LogLevel.Debug)) { - logger.Debug(String.Format("{0} Grain Service started successfully.", serviceConfig.Value.Name)); + logger.Debug(String.Format("{0} Grain Service with Id {1} started successfully.", serviceConfig.Key, serviceConfig.Value)); } } } private void ConfigureThreadPoolAndServicePointSettings() { - if (LocalConfig.MinDotNetThreadPoolSize > 0) + ThreadPoolOptions threadPoolOptions = Services.GetRequiredService>().Value; + if (threadPoolOptions.MinDotNetThreadPoolSize > 0) { int workerThreads; int completionPortThreads; ThreadPool.GetMinThreads(out workerThreads, out completionPortThreads); - if (LocalConfig.MinDotNetThreadPoolSize > workerThreads || - LocalConfig.MinDotNetThreadPoolSize > completionPortThreads) + if (threadPoolOptions.MinDotNetThreadPoolSize > workerThreads || + threadPoolOptions.MinDotNetThreadPoolSize > completionPortThreads) { // if at least one of the new values is larger, set the new min values to be the larger of the prev. and new config value. - int newWorkerThreads = Math.Max(LocalConfig.MinDotNetThreadPoolSize, workerThreads); - int newCompletionPortThreads = Math.Max(LocalConfig.MinDotNetThreadPoolSize, completionPortThreads); + int newWorkerThreads = Math.Max(threadPoolOptions.MinDotNetThreadPoolSize, workerThreads); + int newCompletionPortThreads = Math.Max(threadPoolOptions.MinDotNetThreadPoolSize, completionPortThreads); bool ok = ThreadPool.SetMinThreads(newWorkerThreads, newCompletionPortThreads); if (ok) { @@ -630,12 +633,13 @@ private void ConfigureThreadPoolAndServicePointSettings() // Set .NET ServicePointManager settings to optimize throughput performance when using Azure storage // http://blogs.msdn.com/b/windowsazurestorage/archive/2010/06/25/nagle-s-algorithm-is-not-friendly-towards-small-requests.aspx + ServicePointOptions servicePointOptions = Services.GetRequiredService>().Value; logger.Info(ErrorCode.SiloConfiguredServicePointManager, "Configured .NET ServicePointManager to Expect100Continue={0}, DefaultConnectionLimit={1}, UseNagleAlgorithm={2} to improve Azure storage performance.", - LocalConfig.Expect100Continue, LocalConfig.DefaultConnectionLimit, LocalConfig.UseNagleAlgorithm); - ServicePointManager.Expect100Continue = LocalConfig.Expect100Continue; - ServicePointManager.DefaultConnectionLimit = LocalConfig.DefaultConnectionLimit; - ServicePointManager.UseNagleAlgorithm = LocalConfig.UseNagleAlgorithm; + servicePointOptions.Expect100Continue, servicePointOptions.DefaultConnectionLimit, servicePointOptions.UseNagleAlgorithm); + ServicePointManager.Expect100Continue = servicePointOptions.Expect100Continue; + ServicePointManager.DefaultConnectionLimit = servicePointOptions.DefaultConnectionLimit; + ServicePointManager.UseNagleAlgorithm = servicePointOptions.UseNagleAlgorithm; } /// diff --git a/src/Orleans.Runtime/Silo/SiloControl.cs b/src/Orleans.Runtime/Silo/SiloControl.cs index 7337a1988f..966e37740a 100644 --- a/src/Orleans.Runtime/Silo/SiloControl.cs +++ b/src/Orleans.Runtime/Silo/SiloControl.cs @@ -19,8 +19,6 @@ internal class SiloControl : SystemTarget, ISiloControl { private readonly ILogger logger; private readonly ILocalSiloDetails localSiloDetails; - private readonly Factory localConfiguration; - private readonly ClusterConfiguration clusterConfiguration; private readonly DeploymentLoadPublisher deploymentLoadPublisher; private readonly Catalog catalog; @@ -33,8 +31,6 @@ internal class SiloControl : SystemTarget, ISiloControl public SiloControl( ILocalSiloDetails localSiloDetails, - Factory localConfiguration, - ClusterConfiguration clusterConfiguration, DeploymentLoadPublisher deploymentLoadPublisher, Catalog catalog, GrainTypeManager grainTypeManager, @@ -47,8 +43,6 @@ internal class SiloControl : SystemTarget, ISiloControl : base(Constants.SiloControlId, localSiloDetails.SiloAddress, loggerFactory) { this.localSiloDetails = localSiloDetails; - this.localConfiguration = localConfiguration; - this.clusterConfiguration = clusterConfiguration; this.logger = loggerFactory.CreateLogger(); this.deploymentLoadPublisher = deploymentLoadPublisher; @@ -130,14 +124,6 @@ public Task GetDetailedGrainReport(GrainId grainId) return Task.FromResult( this.catalog.GetDetailedGrainReport(grainId)); } - public Task UpdateConfiguration(string configuration) - { - logger.Info("UpdateConfiguration with {0}", configuration); - this.clusterConfiguration.Update(configuration); - logger.Info(ErrorCode.Runtime_Error_100318, "UpdateConfiguration - new config is now {0}", this.clusterConfiguration.ToString(this.localSiloDetails.Name)); - return Task.CompletedTask; - } - public Task GetActivationCount() { return Task.FromResult(this.catalog.ActivationCount); diff --git a/src/Orleans.Runtime/Streams/QueueBalancer/DeploymentBasedQueueBalancer.cs b/src/Orleans.Runtime/Streams/QueueBalancer/DeploymentBasedQueueBalancer.cs index fd81b3136d..e752734069 100644 --- a/src/Orleans.Runtime/Streams/QueueBalancer/DeploymentBasedQueueBalancer.cs +++ b/src/Orleans.Runtime/Streams/QueueBalancer/DeploymentBasedQueueBalancer.cs @@ -7,6 +7,8 @@ using Orleans.Runtime; using Orleans.Runtime.Configuration; using Orleans.Providers; +using Orleans.Hosting; +using Microsoft.Extensions.Options; namespace Orleans.Streams { @@ -14,8 +16,8 @@ public class StaticClusterConfigDeploymentBalancer : DeploymentBasedQueueBalance { public StaticClusterConfigDeploymentBalancer( ISiloStatusOracle siloStatusOracle, - ClusterConfiguration clusterConfiguration) - : base(siloStatusOracle, new StaticClusterDeploymentConfiguration(clusterConfiguration), true) + IOptions options) + : base(siloStatusOracle, options.Value, true) { } } @@ -23,8 +25,8 @@ public class DynamicClusterConfigDeploymentBalancer : DeploymentBasedQueueBalanc { public DynamicClusterConfigDeploymentBalancer( ISiloStatusOracle siloStatusOracle, - ClusterConfiguration clusterConfiguration) - : base(siloStatusOracle, new StaticClusterDeploymentConfiguration(clusterConfiguration), false) + IOptions options) + : base(siloStatusOracle, options.Value, false) { } } diff --git a/src/Orleans.Runtime/Streams/QueueBalancer/LeaseBasedQueueBalancer.cs b/src/Orleans.Runtime/Streams/QueueBalancer/LeaseBasedQueueBalancer.cs index 390718a2c5..d6f40d49ec 100644 --- a/src/Orleans.Runtime/Streams/QueueBalancer/LeaseBasedQueueBalancer.cs +++ b/src/Orleans.Runtime/Streams/QueueBalancer/LeaseBasedQueueBalancer.cs @@ -1,4 +1,4 @@ -using Orleans.LeaseProviders; +using Orleans.LeaseProviders; using Orleans.Runtime; using Orleans.Runtime.Configuration; using Orleans.Streams; @@ -13,6 +13,8 @@ using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using Orleans.Providers; +using Orleans.Hosting; +using Microsoft.Extensions.Options; namespace Orleans.Streams { @@ -71,8 +73,8 @@ public List NextSelection(int newSelectionCount, List existingSelection) public class ClusterConfigDeploymentLeaseBasedBalancer : LeaseBasedQueueBalancer { public ClusterConfigDeploymentLeaseBasedBalancer(IServiceProvider serviceProvider, ISiloStatusOracle siloStatusOracle, - ClusterConfiguration clusterConfiguration, ILoggerFactory loggerFactory) - : base(serviceProvider, siloStatusOracle, new StaticClusterDeploymentConfiguration(clusterConfiguration), loggerFactory) + IOptions options, ILoggerFactory loggerFactory) + : base(serviceProvider, siloStatusOracle, options.Value, loggerFactory) { } } diff --git a/src/Orleans.Runtime/Streams/QueueBalancer/StaticClusterDeploymentConfiguration.cs b/src/Orleans.Runtime/Streams/QueueBalancer/StaticClusterDeploymentConfiguration.cs index bba0758e79..2420d8f7f0 100644 --- a/src/Orleans.Runtime/Streams/QueueBalancer/StaticClusterDeploymentConfiguration.cs +++ b/src/Orleans.Runtime/Streams/QueueBalancer/StaticClusterDeploymentConfiguration.cs @@ -1,29 +1,18 @@ -using System; using System.Collections.Generic; -using System.Linq; -using Orleans.Runtime.Configuration; +using Orleans.Streams; -namespace Orleans.Streams +namespace Orleans.Hosting { /// /// Deployment configuration that reads from orleans cluster configuration /// - internal class StaticClusterDeploymentConfiguration : IDeploymentConfiguration + public class StaticClusterDeploymentOptions : IDeploymentConfiguration { - private readonly ClusterConfiguration _clusterConfiguration; + public IList SiloNames { get; set; } = new List(); - public StaticClusterDeploymentConfiguration(ClusterConfiguration clusterConfiguration) + IList IDeploymentConfiguration.GetAllSiloNames() { - if (clusterConfiguration == null) - { - throw new ArgumentNullException("clusterConfiguration"); - } - _clusterConfiguration = clusterConfiguration; - } - - public IList GetAllSiloNames() - { - return _clusterConfiguration.Overrides.Keys.ToList(); + return this.SiloNames; } } } diff --git a/src/Orleans.Runtime/Transactions/TransactionAgent.cs b/src/Orleans.Runtime/Transactions/TransactionAgent.cs index f651a5b7c5..f01dd6e047 100644 --- a/src/Orleans.Runtime/Transactions/TransactionAgent.cs +++ b/src/Orleans.Runtime/Transactions/TransactionAgent.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Diagnostics; @@ -8,6 +8,8 @@ using Orleans.Concurrency; using Orleans.Runtime.Configuration; using DateTime = System.DateTime; +using Orleans.Hosting; +using Microsoft.Extensions.Options; namespace Orleans.Transactions { @@ -117,7 +119,7 @@ internal class TransactionAgent : SystemTarget, ITransactionAgent, ITransactionA //metrics related private TransactionAgentMetrics metrics; - public TransactionAgent(ILocalSiloDetails siloDetails, ITransactionManagerService tmService, ILoggerFactory loggerFactory, ITelemetryProducer telemetryProducer, Factory getNodeConfig) + public TransactionAgent(ILocalSiloDetails siloDetails, ITransactionManagerService tmService, ILoggerFactory loggerFactory, ITelemetryProducer telemetryProducer, IOptions statisticsOptions) : base(Constants.TransactionAgentSystemTargetId, siloDetails.SiloAddress, loggerFactory) { logger = loggerFactory.CreateLogger(); @@ -132,7 +134,7 @@ public TransactionAgent(ILocalSiloDetails siloDetails, ITransactionManagerServic transactionCommitQueue = new ConcurrentQueue(); commitCompletions = new ConcurrentDictionary>(); outstandingCommits = new HashSet(); - this.metrics = new TransactionAgentMetrics(telemetryProducer, getNodeConfig().StatisticsMetricsTableWriteInterval); + this.metrics = new TransactionAgentMetrics(telemetryProducer, statisticsOptions.Value.MetricsTableWriteInterval); } #region ITransactionAgent diff --git a/src/Orleans.Runtime/Versions/Compatibility/AllVersionsCompatibilityDirector.cs b/src/Orleans.Runtime/Versions/Compatibility/AllVersionsCompatibilityDirector.cs index cc03c3d651..5a26136154 100644 --- a/src/Orleans.Runtime/Versions/Compatibility/AllVersionsCompatibilityDirector.cs +++ b/src/Orleans.Runtime/Versions/Compatibility/AllVersionsCompatibilityDirector.cs @@ -1,8 +1,8 @@ -using Orleans.Versions.Compatibility; +using Orleans.Versions.Compatibility; namespace Orleans.Runtime.Versions.Compatibility { - internal class AllVersionsCompatibilityDirector : ICompatibilityDirector + internal class AllVersionsCompatibilityDirector : ICompatibilityDirector { public bool IsCompatible(ushort requestedVersion, ushort currentVersion) { diff --git a/src/Orleans.Runtime/Versions/Compatibility/BackwardCompatilityDirector.cs b/src/Orleans.Runtime/Versions/Compatibility/BackwardCompatilityDirector.cs index c54900e43f..6a50b66605 100644 --- a/src/Orleans.Runtime/Versions/Compatibility/BackwardCompatilityDirector.cs +++ b/src/Orleans.Runtime/Versions/Compatibility/BackwardCompatilityDirector.cs @@ -1,8 +1,8 @@ -using Orleans.Versions.Compatibility; +using Orleans.Versions.Compatibility; namespace Orleans.Runtime.Versions.Compatibility { - internal class BackwardCompatilityDirector : ICompatibilityDirector + internal class BackwardCompatilityDirector : ICompatibilityDirector { public bool IsCompatible(ushort requestedVersion, ushort currentVersion) { diff --git a/src/Orleans.Runtime/Versions/Compatibility/CompatibilityDirectorManager.cs b/src/Orleans.Runtime/Versions/Compatibility/CompatibilityDirectorManager.cs index 76d7e132db..1e9f766aa7 100644 --- a/src/Orleans.Runtime/Versions/Compatibility/CompatibilityDirectorManager.cs +++ b/src/Orleans.Runtime/Versions/Compatibility/CompatibilityDirectorManager.cs @@ -1,7 +1,7 @@ -using System; +using System; using System.Collections.Generic; -using Microsoft.Extensions.DependencyInjection; -using Orleans.Runtime.Configuration; +using Microsoft.Extensions.Options; +using Orleans.Hosting; using Orleans.Versions.Compatibility; namespace Orleans.Runtime.Versions.Compatibility @@ -15,17 +15,12 @@ internal class CompatibilityDirectorManager public ICompatibilityDirector Default { get; private set; } - public CompatibilityDirectorManager(IServiceProvider serviceProvider, GlobalConfiguration configuration) - : this(serviceProvider, configuration.DefaultCompatibilityStrategy) - { - } - - public CompatibilityDirectorManager(IServiceProvider serviceProvider, CompatibilityStrategy defaultCompatibilityStrategy) + public CompatibilityDirectorManager(IServiceProvider serviceProvider, IOptions options) { this.serviceProvider = serviceProvider; - this.strategyFromConfig = defaultCompatibilityStrategy; + this.strategyFromConfig = serviceProvider.GetRequiredServiceByName(options.Value.DefaultCompatibilityStrategy); this.compatibilityDirectors = new Dictionary(); - Default = ResolveVersionDirector(serviceProvider, defaultCompatibilityStrategy); + Default = ResolveVersionDirector(serviceProvider, this.strategyFromConfig); } public ICompatibilityDirector GetDirector(int interfaceId) @@ -58,8 +53,7 @@ public void SetStrategy(int interfaceId, CompatibilityStrategy strategy) CompatibilityStrategy compatibilityStrategy) { var strategyType = compatibilityStrategy.GetType(); - var directorType = typeof(ICompatibilityDirector<>).MakeGenericType(strategyType); - return (ICompatibilityDirector) serviceProvider.GetRequiredService(directorType); + return serviceProvider.GetRequiredServiceByKey(strategyType); } } } diff --git a/src/Orleans.Runtime/Versions/Compatibility/StrictVersionCompatibilityDirector.cs b/src/Orleans.Runtime/Versions/Compatibility/StrictVersionCompatibilityDirector.cs index 2c02faacc4..3c00497c72 100644 --- a/src/Orleans.Runtime/Versions/Compatibility/StrictVersionCompatibilityDirector.cs +++ b/src/Orleans.Runtime/Versions/Compatibility/StrictVersionCompatibilityDirector.cs @@ -1,8 +1,8 @@ -using Orleans.Versions.Compatibility; +using Orleans.Versions.Compatibility; namespace Orleans.Runtime.Versions.Compatibility { - internal class StrictVersionCompatibilityDirector : ICompatibilityDirector + internal class StrictVersionCompatibilityDirector : ICompatibilityDirector { public bool IsCompatible(ushort requestedVersion, ushort currentVersion) { diff --git a/src/Orleans.Runtime/Versions/Selector/AllCompatibleVersionsSelector.cs b/src/Orleans.Runtime/Versions/Selector/AllCompatibleVersionsSelector.cs index 6d2e44e4a4..18d42a2200 100644 --- a/src/Orleans.Runtime/Versions/Selector/AllCompatibleVersionsSelector.cs +++ b/src/Orleans.Runtime/Versions/Selector/AllCompatibleVersionsSelector.cs @@ -1,11 +1,11 @@ -using System.Collections.Generic; +using System.Collections.Generic; using System.Linq; using Orleans.Versions.Compatibility; using Orleans.Versions.Selector; namespace Orleans.Runtime.Versions.Selector { - internal class AllCompatibleVersionsSelector : IVersionSelector + internal class AllCompatibleVersionsSelector : IVersionSelector { public IReadOnlyList GetSuitableVersion(ushort requestedVersion, IReadOnlyList availableVersions, ICompatibilityDirector compatibilityDirector) { diff --git a/src/Orleans.Runtime/Versions/Selector/LatestVersionDirector.cs b/src/Orleans.Runtime/Versions/Selector/LatestVersionDirector.cs index ebb2f1c2f2..801a56c602 100644 --- a/src/Orleans.Runtime/Versions/Selector/LatestVersionDirector.cs +++ b/src/Orleans.Runtime/Versions/Selector/LatestVersionDirector.cs @@ -1,11 +1,11 @@ -using System.Collections.Generic; +using System.Collections.Generic; using System.Linq; using Orleans.Versions.Compatibility; using Orleans.Versions.Selector; namespace Orleans.Runtime.Versions.Selector { - internal sealed class LatestVersionSelector : IVersionSelector + internal sealed class LatestVersionSelector : IVersionSelector { public IReadOnlyList GetSuitableVersion(ushort requestedVersion, IReadOnlyList availableVersions, ICompatibilityDirector compatibilityDirector) { diff --git a/src/Orleans.Runtime/Versions/Selector/MinimumVersionSelector.cs b/src/Orleans.Runtime/Versions/Selector/MinimumVersionSelector.cs index 00faa792a8..c08f22766a 100644 --- a/src/Orleans.Runtime/Versions/Selector/MinimumVersionSelector.cs +++ b/src/Orleans.Runtime/Versions/Selector/MinimumVersionSelector.cs @@ -1,11 +1,11 @@ -using System.Collections.Generic; +using System.Collections.Generic; using System.Linq; using Orleans.Versions.Compatibility; using Orleans.Versions.Selector; namespace Orleans.Runtime.Versions.Selector { - internal sealed class MinimumVersionSelector : IVersionSelector + internal sealed class MinimumVersionSelector : IVersionSelector { public IReadOnlyList GetSuitableVersion(ushort requestedVersion, IReadOnlyList availableVersions, ICompatibilityDirector compatibilityDirector) { diff --git a/src/Orleans.Runtime/Versions/Selector/VersionDirectorManager.cs b/src/Orleans.Runtime/Versions/Selector/VersionDirectorManager.cs index 088bd4f529..2eb6ac4d8d 100644 --- a/src/Orleans.Runtime/Versions/Selector/VersionDirectorManager.cs +++ b/src/Orleans.Runtime/Versions/Selector/VersionDirectorManager.cs @@ -1,6 +1,8 @@ -using System; +using System; using System.Collections.Generic; using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; +using Orleans.Hosting; using Orleans.Runtime.Configuration; using Orleans.Versions.Selector; @@ -14,11 +16,11 @@ internal class VersionSelectorManager public IVersionSelector Default { get; set; } - public VersionSelectorManager(IServiceProvider serviceProvider, GlobalConfiguration configuration) + public VersionSelectorManager(IServiceProvider serviceProvider, IOptions options) { this.serviceProvider = serviceProvider; - this.strategyFromConfig = configuration.DefaultVersionSelectorStrategy; - Default = ResolveVersionSelector(serviceProvider, strategyFromConfig); + this.strategyFromConfig = serviceProvider.GetRequiredServiceByName(options.Value.DefaultVersionSelectorStrategy); + Default = ResolveVersionSelector(serviceProvider, this.strategyFromConfig); versionSelectors = new Dictionary(); } @@ -53,8 +55,7 @@ public void SetSelector(int interfaceId, VersionSelectorStrategy strategy) VersionSelectorStrategy strategy) { var policyType = strategy.GetType(); - var directorType = typeof(IVersionSelector<>).MakeGenericType(policyType); - return (IVersionSelector)serviceProvider.GetRequiredService(directorType); + return serviceProvider.GetRequiredServiceByKey(policyType); } } } \ No newline at end of file diff --git a/src/Orleans.TelemetryConsumers.AI/Orleans.TelemetryConsumers.AI.csproj b/src/Orleans.TelemetryConsumers.AI/Orleans.TelemetryConsumers.AI.csproj index 76679b0d7b..0b6321ffec 100644 --- a/src/Orleans.TelemetryConsumers.AI/Orleans.TelemetryConsumers.AI.csproj +++ b/src/Orleans.TelemetryConsumers.AI/Orleans.TelemetryConsumers.AI.csproj @@ -17,6 +17,7 @@ + diff --git a/src/Orleans.TelemetryConsumers.Counters/OrleansPerfCounterTelemetryConsumer.cs b/src/Orleans.TelemetryConsumers.Counters/OrleansPerfCounterTelemetryConsumer.cs index 3aa68d71ca..197355cc71 100644 --- a/src/Orleans.TelemetryConsumers.Counters/OrleansPerfCounterTelemetryConsumer.cs +++ b/src/Orleans.TelemetryConsumers.Counters/OrleansPerfCounterTelemetryConsumer.cs @@ -1,4 +1,4 @@ -using Orleans; +using Orleans; using Orleans.Runtime; using System; using System.Collections.Generic; @@ -31,9 +31,9 @@ public OrleansPerfCounterTelemetryConsumer(ILoggerFactory loggerFactory) { this.logger = loggerFactory.CreateLogger(); this.isInitialized = new Lazy(this.Initialize, true); - if (!AreWindowsPerfCountersAvailable(logger)) + if (!AreWindowsPerfCountersAvailable(this.logger)) { - logger.Warn(ErrorCode.PerfCounterNotFound, "Windows perf counters not found -- defaulting to in-memory counters. " + ExplainHowToCreateOrleansPerfCounters); + this.logger.Warn(ErrorCode.PerfCounterNotFound, "Windows perf counters not found -- defaulting to in-memory counters. " + ExplainHowToCreateOrleansPerfCounters); } } @@ -65,7 +65,7 @@ public static bool AreWindowsPerfCountersAvailable(ILogger logger) private PerformanceCounter CreatePerfCounter(string perfCounterName) { - logger.Debug(ErrorCode.PerfCounterRegistering, "Creating perf counter {0}", perfCounterName); + this.logger.Debug(ErrorCode.PerfCounterRegistering, "Creating perf counter {0}", perfCounterName); return new PerformanceCounter(CATEGORY_NAME, perfCounterName, false); } @@ -83,17 +83,17 @@ internal void InstallCounters() if (PerformanceCounterCategory.Exists(CATEGORY_NAME)) DeleteCounters(); - isInstalling = true; - if (!isInitialized.Value) + this.isInstalling = true; + if (!this.isInitialized.Value) { var msg = "Unable to install Windows Performance counters"; - logger.Warn(ErrorCode.PerfCounterNotFound, msg); + this.logger.Warn(ErrorCode.PerfCounterNotFound, msg); throw new InvalidOperationException(msg); } var collection = new CounterCreationDataCollection(); - foreach (PerfCounterConfigData cd in perfCounterData) + foreach (PerfCounterConfigData cd in this.perfCounterData) { var perfCounterName = GetPerfCounterName(cd); var description = cd.Name.Name; @@ -122,7 +122,7 @@ internal void DeleteCounters() private PerfCounterConfigData GetCounter(string counterName) { - return perfCounterData.Where(pcd => GetPerfCounterName(pcd) == counterName).SingleOrDefault(); + return this.perfCounterData.Where(pcd => GetPerfCounterName(pcd) == counterName).SingleOrDefault(); } #endregion @@ -226,7 +226,7 @@ private bool Initialize() private void WriteMetric(string name, UpdateMode mode = UpdateMode.Increment, double? value = null) { - if (!isInitialized.Value) + if (!this.isInitialized.Value) return; // Attempt to initialize grain-specific counters if they haven't been initialized yet. @@ -245,7 +245,7 @@ private void WriteMetric(string name, UpdateMode mode = UpdateMode.Increment, do try { - if (logger.IsEnabled(LogLevel.Trace)) logger.Trace(ErrorCode.PerfCounterWriting, "Writing perf counter {0}", perfCounterName); + if (this.logger.IsEnabled(LogLevel.Trace)) this.logger.Trace(ErrorCode.PerfCounterWriting, "Writing perf counter {0}", perfCounterName); switch (mode) { @@ -276,7 +276,7 @@ private void WriteMetric(string name, UpdateMode mode = UpdateMode.Increment, do } catch (Exception ex) { - logger.Error(ErrorCode.PerfCounterUnableToWrite, string.Format("Unable to write to Windows perf counter '{0}'", statsName), ex); + this.logger.Error(ErrorCode.PerfCounterUnableToWrite, string.Format("Unable to write to Windows perf counter '{0}'", statsName), ex); } } diff --git a/src/Orleans.TelemetryConsumers.Counters/PerfCountersConfigurationExtensions.cs b/src/Orleans.TelemetryConsumers.Counters/PerfCountersConfigurationExtensions.cs index 56d71ccc20..44fb9db20a 100644 --- a/src/Orleans.TelemetryConsumers.Counters/PerfCountersConfigurationExtensions.cs +++ b/src/Orleans.TelemetryConsumers.Counters/PerfCountersConfigurationExtensions.cs @@ -1,25 +1,9 @@ -using OrleansTelemetryConsumers.Counters; -using System.Linq; +using OrleansTelemetryConsumers.Counters; namespace Orleans.Runtime.Configuration { public static class PerfCountersConfigurationExtensions { - /// - /// Adds a metrics telemetric consumer provider of type . - /// - /// The cluster configuration object to add the telemetry consumer to. - public static void AddPerfCountersTelemetryConsumer(this ClusterConfiguration config) - { - string typeName = typeof(OrleansPerfCounterTelemetryConsumer).FullName; - string assemblyName = typeof(OrleansPerfCounterTelemetryConsumer).Assembly.GetName().Name; - - foreach (var nodeConfig in config.Overrides.Values.Union(new[] { config.Defaults })) - { - nodeConfig.TelemetryConfiguration.Add(typeName, assemblyName, null); - } - } - /// /// Adds a metrics telemetric consumer provider of type . /// diff --git a/src/Orleans.TelemetryConsumers.NewRelic/Orleans.TelemetryConsumers.NewRelic.csproj b/src/Orleans.TelemetryConsumers.NewRelic/Orleans.TelemetryConsumers.NewRelic.csproj index 4501a52f56..19c525c5bf 100644 --- a/src/Orleans.TelemetryConsumers.NewRelic/Orleans.TelemetryConsumers.NewRelic.csproj +++ b/src/Orleans.TelemetryConsumers.NewRelic/Orleans.TelemetryConsumers.NewRelic.csproj @@ -18,6 +18,7 @@ + diff --git a/src/Orleans.TestingHost/LegacyTestClusterConfiguration.cs b/src/Orleans.TestingHost/LegacyTestClusterConfiguration.cs index c6450d84fc..8f5dbb0b7f 100644 --- a/src/Orleans.TestingHost/LegacyTestClusterConfiguration.cs +++ b/src/Orleans.TestingHost/LegacyTestClusterConfiguration.cs @@ -71,7 +71,7 @@ public ClusterConfiguration BuildClusterConfiguration() var nodeConfig = config.GetOrCreateNodeConfigurationForSilo(siloConfig.SiloName); nodeConfig.Port = siloConfig.SiloPort; nodeConfig.SiloName = siloConfig.SiloName; - var address = ClusterConfiguration.ResolveIPAddress(nodeConfig.HostNameOrIPAddress, nodeConfig.Subnet, nodeConfig.AddressType).GetAwaiter().GetResult(); + var address = ConfigUtilities.ResolveIPAddress(nodeConfig.HostNameOrIPAddress, nodeConfig.Subnet, nodeConfig.AddressType).GetAwaiter().GetResult(); nodeConfig.ProxyGatewayEndpoint = new IPEndPoint(address, siloConfig.GatewayPort); nodeConfig.IsPrimaryNode = i == 0; } @@ -154,7 +154,7 @@ internal static SerializationManager CreateLegacyConfigurationSerializer() internal static string Serialize(SerializationManager serializationManager, object config) { - BufferPool.InitGlobalBufferPool(Options.Create(new MessagingOptions())); + BufferPool.InitGlobalBufferPool(new SiloMessagingOptions()); var writer = new BinaryTokenStreamWriter(); serializationManager.Serialize(config, writer); string serialized = Convert.ToBase64String(writer.ToByteArray()); diff --git a/src/Orleans.TestingHost/Orleans.TestingHost.csproj b/src/Orleans.TestingHost/Orleans.TestingHost.csproj index b3d75f62b4..dfb8255555 100644 --- a/src/Orleans.TestingHost/Orleans.TestingHost.csproj +++ b/src/Orleans.TestingHost/Orleans.TestingHost.csproj @@ -19,6 +19,8 @@ + + diff --git a/src/Orleans.Transactions/InClusterTM/TransactionManager.cs b/src/Orleans.Transactions/InClusterTM/TransactionManager.cs index 2e6c46e48c..8d5bef12b8 100644 --- a/src/Orleans.Transactions/InClusterTM/TransactionManager.cs +++ b/src/Orleans.Transactions/InClusterTM/TransactionManager.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Threading.Tasks; using System.Collections.Concurrent; @@ -8,6 +8,7 @@ using Orleans.Runtime; using Orleans.Transactions.Abstractions; using Orleans.Runtime.Configuration; +using Orleans.Hosting; namespace Orleans.Transactions { @@ -47,7 +48,7 @@ public class TransactionManager : ITransactionManager private Task transactionLogMaintenanceTask; private TransactionManagerMetrics metrics; public TransactionManager(TransactionLog transactionLog, IOptions configOption, ILoggerFactory loggerFactory, ITelemetryProducer telemetryProducer, - Factory getNodeConfig, TimeSpan? logMaintenanceInterval = null) + IOptions statisticsOptions, TimeSpan? logMaintenanceInterval = null) { this.transactionLog = transactionLog; this.options = configOption.Value; @@ -68,7 +69,7 @@ public class TransactionManager : ITransactionManager this.resources = new Dictionary(); this.transactions = new List(); this.metrics = - new TransactionManagerMetrics(telemetryProducer, getNodeConfig().StatisticsMetricsTableWriteInterval); + new TransactionManagerMetrics(telemetryProducer, statisticsOptions.Value.MetricsTableWriteInterval); this.checkpointedLSN = 0; this.IsRunning = false; } diff --git a/src/OrleansManager/Program.cs b/src/OrleansManager/Program.cs index b96d1969bc..65ad6b3c69 100644 --- a/src/OrleansManager/Program.cs +++ b/src/OrleansManager/Program.cs @@ -272,7 +272,7 @@ private static void SetSelStrategyArgs(string[] args) { int? interfaceId; VersionSelectorStrategy strategy; - if (!GetStrategyArgs(args, VersionSelectorStrategy.Parse, out strategy, out interfaceId)) + if (!GetStrategyArgs(args, ParseVersionSelectorStrategy, out strategy, out interfaceId)) return; if (interfaceId != null) systemManagement.SetSelectorStrategy(interfaceId.Value, strategy); @@ -280,11 +280,23 @@ private static void SetSelStrategyArgs(string[] args) systemManagement.SetSelectorStrategy(strategy); } + private static VersionSelectorStrategy ParseVersionSelectorStrategy(string str) + { + // TODO - what about custom? + if (str.Equals(typeof(AllCompatibleVersions).Name)) + return AllCompatibleVersions.Singleton; + if (str.Equals(typeof(LatestVersion).Name)) + return LatestVersion.Singleton; + if (str.Equals(typeof(MinimumVersion).Name)) + return MinimumVersion.Singleton; + return null; + } + private static void SetCompatibilityStrategy(string[] args) { int? interfaceId; CompatibilityStrategy strategy; - if (!GetStrategyArgs(args, CompatibilityStrategy.Parse, out strategy, out interfaceId)) + if (!GetStrategyArgs(args, ParseCompatibilityStrategy, out strategy, out interfaceId)) return; if (interfaceId != null) systemManagement.SetCompatibilityStrategy(interfaceId.Value, strategy); @@ -292,6 +304,18 @@ private static void SetCompatibilityStrategy(string[] args) systemManagement.SetCompatibilityStrategy(strategy); } + private static CompatibilityStrategy ParseCompatibilityStrategy(string str) + { + // TODO - what about custom? + if (str.Equals(typeof(AllVersionsCompatible).Name)) + return AllVersionsCompatible.Singleton; + if (str.Equals(typeof(BackwardCompatible).Name)) + return BackwardCompatible.Singleton; + if (str.Equals(typeof(StrictVersionCompatible).Name)) + return StrictVersionCompatible.Singleton; + return null; + } + private static bool GetStrategyArgs(string[] args, Func strategyParser, out T strategy, out int? interfaceId) { if (args.Length < 1 || args.Length > 2) diff --git a/src/OrleansProviders/Streams/Common/Monitors/DefaultBlockPoolMonitor.cs b/src/OrleansProviders/Streams/Common/Monitors/DefaultBlockPoolMonitor.cs index d552bc646c..9f61fe7a16 100644 --- a/src/OrleansProviders/Streams/Common/Monitors/DefaultBlockPoolMonitor.cs +++ b/src/OrleansProviders/Streams/Common/Monitors/DefaultBlockPoolMonitor.cs @@ -1,4 +1,4 @@ -using Orleans.Runtime; +using Orleans.Runtime; using System; using System.Collections.Generic; using System.Linq; @@ -26,7 +26,6 @@ public DefaultBlockPoolMonitor(BlockPoolMonitorDimensions dimensions, ITelemetry this.LogProperties = new Dictionary { {"BlockPoolId", dimensions.BlockPoolId}, - {"HostName", dimensions.NodeConfig.HostNameOrIPAddress } }; } /// diff --git a/src/OrleansProviders/Streams/Common/Monitors/DefaultCacheMonitor.cs b/src/OrleansProviders/Streams/Common/Monitors/DefaultCacheMonitor.cs index a6062921b6..073a89cfba 100644 --- a/src/OrleansProviders/Streams/Common/Monitors/DefaultCacheMonitor.cs +++ b/src/OrleansProviders/Streams/Common/Monitors/DefaultCacheMonitor.cs @@ -1,4 +1,4 @@ -using Orleans.Runtime; +using Orleans.Runtime; using System; using System.Collections.Generic; using System.Linq; @@ -26,7 +26,6 @@ public DefaultCacheMonitor(CacheMonitorDimensions dimensions, ITelemetryProducer this.LogProperties = new Dictionary { {"QueueId", dimensions.QueueId}, - {"HostName", dimensions.NodeConfig.HostNameOrIPAddress} }; } /// diff --git a/src/OrleansProviders/Streams/Common/Monitors/DefaultQueueAdapterReceiverMonitor.cs b/src/OrleansProviders/Streams/Common/Monitors/DefaultQueueAdapterReceiverMonitor.cs index d5507a6efc..760450564f 100644 --- a/src/OrleansProviders/Streams/Common/Monitors/DefaultQueueAdapterReceiverMonitor.cs +++ b/src/OrleansProviders/Streams/Common/Monitors/DefaultQueueAdapterReceiverMonitor.cs @@ -1,4 +1,4 @@ -using Orleans.Runtime; +using Orleans.Runtime; using System; using System.Collections.Generic; using System.Linq; @@ -26,7 +26,6 @@ public DefaultQueueAdapterReceiverMonitor(ReceiverMonitorDimensions dimensions, this.LogProperties = new Dictionary { {"QueueId", dimensions.QueueId}, - {"HostName", dimensions.NodeConfig.HostNameOrIPAddress } }; } /// diff --git a/src/OrleansProviders/Streams/Common/Monitors/MonitorAggregationDimensions.cs b/src/OrleansProviders/Streams/Common/Monitors/MonitorAggregationDimensions.cs index 1f945566e4..f2a8d4a946 100644 --- a/src/OrleansProviders/Streams/Common/Monitors/MonitorAggregationDimensions.cs +++ b/src/OrleansProviders/Streams/Common/Monitors/MonitorAggregationDimensions.cs @@ -1,49 +1,10 @@ -using Orleans.Runtime.Configuration; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace Orleans.Providers.Streams.Common { - /// - /// Base class for holding monitor aggregation dimensions - /// - public class MonitorAggregationDimensions - { - /// - /// Data object holding Silo global configuration parameters. - /// - public GlobalConfiguration GlobalConfig { get; set; } - - /// - /// Individual node-specific silo configuration parameters. - /// - public NodeConfiguration NodeConfig { get; set; } - - /// - /// Constructor - /// - /// - /// - public MonitorAggregationDimensions(GlobalConfiguration globalConfig, NodeConfiguration nodeConfig) - { - this.GlobalConfig = globalConfig; - this.NodeConfig = nodeConfig; - } - - /// - /// Constructor - /// - public MonitorAggregationDimensions() - { } - } - /// /// Aggregation dimensions for receiver monitor /// - public class ReceiverMonitorDimensions : MonitorAggregationDimensions + public class ReceiverMonitorDimensions { /// /// Eventhub partition @@ -53,10 +14,8 @@ public class ReceiverMonitorDimensions : MonitorAggregationDimensions /// /// Constructor /// - /// /// - public ReceiverMonitorDimensions(MonitorAggregationDimensions dimensions, string queueId) - : base(dimensions.GlobalConfig, dimensions.NodeConfig) + public ReceiverMonitorDimensions(string queueId) { this.QueueId = queueId; } @@ -79,8 +38,8 @@ public class CacheMonitorDimensions : ReceiverMonitorDimensions /// public string BlockPoolId { get; set; } - public CacheMonitorDimensions(MonitorAggregationDimensions dimensions, string queueId, string blockPoolId) - :base(dimensions, queueId) + public CacheMonitorDimensions(string queueId, string blockPoolId) + :base(queueId) { this.BlockPoolId = blockPoolId; } @@ -89,15 +48,14 @@ public CacheMonitorDimensions(MonitorAggregationDimensions dimensions, string qu /// /// Aggregation dimensions for block pool monitors /// - public class BlockPoolMonitorDimensions : MonitorAggregationDimensions + public class BlockPoolMonitorDimensions { /// /// Block pool Id /// public string BlockPoolId { get; set; } - public BlockPoolMonitorDimensions(MonitorAggregationDimensions dimensions, string blockPoolId) - :base(dimensions.GlobalConfig, dimensions.NodeConfig) + public BlockPoolMonitorDimensions(string blockPoolId) { this.BlockPoolId = blockPoolId; } diff --git a/src/OrleansProviders/Streams/Generator/GeneratorAdapterFactory.cs b/src/OrleansProviders/Streams/Generator/GeneratorAdapterFactory.cs index ea29ba3c79..a8feedc3c8 100644 --- a/src/OrleansProviders/Streams/Generator/GeneratorAdapterFactory.cs +++ b/src/OrleansProviders/Streams/Generator/GeneratorAdapterFactory.cs @@ -8,7 +8,6 @@ using Orleans.Runtime; using Orleans.Serialization; using Orleans.Streams; -using Orleans.Runtime.Configuration; using System.Diagnostics; using Microsoft.Extensions.Logging; @@ -46,7 +45,6 @@ public class GeneratorAdapterFactory : IQueueAdapterFactory, IQueueAdapter, IQue private SerializationManager serializationManager; private ITelemetryProducer telemetryProducer; private BlockPoolMonitorDimensions blockPoolMonitorDimensions; - private MonitorAggregationDimensions sharedDimensions; private ILoggerFactory loggerFactory; private string providerName; /// @@ -110,7 +108,6 @@ public void Init(IProviderConfiguration providerConfig, string providerName, IS } generatorConfig.PopulateFromProviderConfig(providerConfig); } - this.sharedDimensions = new MonitorAggregationDimensions(serviceProvider.GetService(), serviceProvider.GetService()); } private void CreateBufferPoolIfNotCreatedYet() @@ -118,7 +115,7 @@ private void CreateBufferPoolIfNotCreatedYet() if (this.bufferPool == null) { // 1 meg block size pool - this.blockPoolMonitorDimensions = new BlockPoolMonitorDimensions(this.sharedDimensions, $"BlockPool-{Guid.NewGuid()}"); + this.blockPoolMonitorDimensions = new BlockPoolMonitorDimensions($"BlockPool-{Guid.NewGuid()}"); var oneMb = 1 << 20; var objectPoolMonitor = new ObjectPoolMonitorBridge(this.BlockPoolMonitorFactory(blockPoolMonitorDimensions, this.telemetryProducer), oneMb); this.bufferPool = new ObjectPool(() => new FixedSizeBuffer(oneMb), objectPoolMonitor, this.adapterConfig.StatisticMonitorWriteInterval); @@ -190,7 +187,7 @@ public Task GetDeliveryFailureHandler(QueueId queueId) /// public IQueueAdapterReceiver CreateReceiver(QueueId queueId) { - var dimensions = new ReceiverMonitorDimensions(this.sharedDimensions, queueId.ToString()); + var dimensions = new ReceiverMonitorDimensions(queueId.ToString()); var receiverMonitor = this.ReceiverMonitorFactory(dimensions, this.telemetryProducer); Receiver receiver = receivers.GetOrAdd(queueId, qid => new Receiver(receiverMonitor)); SetGeneratorOnReciever(receiver); @@ -298,7 +295,7 @@ public IQueueCache CreateQueueCache(QueueId queueId) { //move block pool creation from init method to here, to avoid unnecessary block pool creation when stream provider is initialized in client side. CreateBufferPoolIfNotCreatedYet(); - var dimensions = new CacheMonitorDimensions(this.sharedDimensions, queueId.ToString(), this.blockPoolMonitorDimensions.BlockPoolId); + var dimensions = new CacheMonitorDimensions(queueId.ToString(), this.blockPoolMonitorDimensions.BlockPoolId); var cacheMonitor = this.CacheMonitorFactory(dimensions, this.telemetryProducer); return new GeneratorPooledCache(bufferPool, this.loggerFactory.CreateLogger($"{typeof(GeneratorPooledCache).FullName}.{this.providerName}.{queueId}"), serializationManager, cacheMonitor, this.adapterConfig.StatisticMonitorWriteInterval); diff --git a/src/OrleansProviders/Streams/LoadShedQueueFlowController.cs b/src/OrleansProviders/Streams/LoadShedQueueFlowController.cs index fcf9557942..e614c97dd5 100644 --- a/src/OrleansProviders/Streams/LoadShedQueueFlowController.cs +++ b/src/OrleansProviders/Streams/LoadShedQueueFlowController.cs @@ -1,5 +1,6 @@ - + using System; +using Orleans.Hosting; using Orleans.Runtime; using Orleans.Runtime.Configuration; @@ -11,12 +12,7 @@ namespace Orleans.Streams /// public class LoadShedQueueFlowController : IQueueFlowController { - /// - /// Default percentage of silo load shedding limit. - /// - public const int DefaultPercentOfLoadSheddingLimit = 95; - - private readonly Factory getNodeConfig; + private readonly SiloStatisticsOptions options; private readonly double loadSheddingLimit; private FloatValueStatistic cpuStatistic; @@ -25,14 +21,14 @@ public class LoadShedQueueFlowController : IQueueFlowController /// This is intended to reduce queue read rate prior to causing the silo to shed load. /// Note: Triggered only when load shedding is enabled. /// - /// The method used to get the current node configuration. + /// The silo satistics options. /// Percentage of load shed limit which triggers a reduction of queue read rate. /// - public static IQueueFlowController CreateAsPercentOfLoadSheddingLimit(Factory getNodeConfig, int percentOfSiloSheddingLimit = DefaultPercentOfLoadSheddingLimit) + public static IQueueFlowController CreateAsPercentOfLoadSheddingLimit(SiloStatisticsOptions options, int percentOfSiloSheddingLimit = SiloStatisticsOptions.DEFAULT_LOAD_SHEDDING_LIMIT) { if (percentOfSiloSheddingLimit < 0.0 || percentOfSiloSheddingLimit > 100.0) throw new ArgumentOutOfRangeException(nameof(percentOfSiloSheddingLimit), "Percent value must be between 0-100"); // Start shedding before silo reaches shedding limit. - return new LoadShedQueueFlowController((int)(getNodeConfig().LoadSheddingLimit * (percentOfSiloSheddingLimit / 100.0)), getNodeConfig); + return new LoadShedQueueFlowController((int)(options.LoadSheddingLimit * (percentOfSiloSheddingLimit / 100.0)), options); } /// @@ -40,12 +36,12 @@ public static IQueueFlowController CreateAsPercentOfLoadSheddingLimit(Factory /// Percentage of CPU which triggers queue read rate reduction - /// The method used to get the current node configuration. + /// The silo satistics options. /// - public static IQueueFlowController CreateAsPercentageOfCPU(int loadSheddingLimit, Factory getNodeConfig) + public static IQueueFlowController CreateAsPercentageOfCPU(int loadSheddingLimit, SiloStatisticsOptions options) { if (loadSheddingLimit < 0 || loadSheddingLimit > 100) throw new ArgumentOutOfRangeException(nameof(loadSheddingLimit), "Value must be between 0-100"); - return new LoadShedQueueFlowController(loadSheddingLimit, getNodeConfig); + return new LoadShedQueueFlowController(loadSheddingLimit, options); } /// @@ -53,9 +49,9 @@ public static IQueueFlowController CreateAsPercentageOfCPU(int loadSheddingLimit /// /// /// The method used to get the current node configuration. - private LoadShedQueueFlowController(int loadSheddingLimit, Factory getNodeConfig) + private LoadShedQueueFlowController(int loadSheddingLimit, SiloStatisticsOptions options) { - this.getNodeConfig = getNodeConfig; + this.options = options; if (loadSheddingLimit < 0 || loadSheddingLimit > 100) throw new ArgumentOutOfRangeException(nameof(loadSheddingLimit), "Value must be between 0-100"); this.loadSheddingLimit = loadSheddingLimit != 0 ? loadSheddingLimit : int.MaxValue; } @@ -65,7 +61,7 @@ private LoadShedQueueFlowController(int loadSheddingLimit, Factory public int GetMaxAddCount() { - return getNodeConfig().LoadSheddingEnabled && GetCpuUsage() > loadSheddingLimit ? 0 : int.MaxValue; + return options.LoadSheddingEnabled && GetCpuUsage() > loadSheddingLimit ? 0 : int.MaxValue; } private float GetCpuUsage() diff --git a/src/OrleansProviders/Streams/Memory/MemoryAdapterFactory.cs b/src/OrleansProviders/Streams/Memory/MemoryAdapterFactory.cs index 70b2d6ab91..eb535050ba 100644 --- a/src/OrleansProviders/Streams/Memory/MemoryAdapterFactory.cs +++ b/src/OrleansProviders/Streams/Memory/MemoryAdapterFactory.cs @@ -1,4 +1,4 @@ - + using System; using System.Collections.Concurrent; using System.Collections.Generic; @@ -7,7 +7,6 @@ using Orleans.Providers.Streams.Common; using Orleans.Runtime; using Orleans.Streams; -using Orleans.Runtime.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; @@ -27,7 +26,6 @@ public class MemoryAdapterFactory : IQueueAdapterFactory, IQueueAda private ConcurrentDictionary queueGrains; private IObjectPool bufferPool; private BlockPoolMonitorDimensions blockPoolMonitorDimensions; - private MonitorAggregationDimensions sharedDimensions; private IStreamFailureHandler streamFailureHandler; private IServiceProvider serviceProvider; private MemoryAdapterConfig adapterConfig; @@ -103,7 +101,6 @@ public void Init(IProviderConfiguration providerConfig, string name, IServicePro adapterConfig.PopulateFromProviderConfig(providerConfig); streamQueueMapper = new HashRingBasedStreamQueueMapper(adapterConfig.TotalQueueCount, adapterConfig.StreamProviderName); - this.sharedDimensions = new MonitorAggregationDimensions(serviceProvider.GetService(), serviceProvider.GetService()); this.serializer = MemoryMessageBodySerializerFactory.GetOrCreateSerializer(svcProvider); } @@ -112,7 +109,7 @@ private void CreateBufferPoolIfNotCreatedYet() if (this.bufferPool == null) { // 1 meg block size pool - this.blockPoolMonitorDimensions = new BlockPoolMonitorDimensions(this.sharedDimensions, $"BlockPool-{Guid.NewGuid()}"); + this.blockPoolMonitorDimensions = new BlockPoolMonitorDimensions($"BlockPool-{Guid.NewGuid()}"); var oneMb = 1 << 20; var objectPoolMonitor = new ObjectPoolMonitorBridge(this.BlockPoolMonitorFactory(blockPoolMonitorDimensions, this.telemetryProducer), oneMb); this.bufferPool = new ObjectPool(() => new FixedSizeBuffer(oneMb), objectPoolMonitor, this.adapterConfig.StatisticMonitorWriteInterval); @@ -153,7 +150,7 @@ public IStreamQueueMapper GetStreamQueueMapper() /// public IQueueAdapterReceiver CreateReceiver(QueueId queueId) { - var dimensions = new ReceiverMonitorDimensions(this.sharedDimensions, queueId.ToString()); + var dimensions = new ReceiverMonitorDimensions(queueId.ToString()); var receiverLogger = this.loggerFactory.CreateLogger($"{typeof(MemoryAdapterReceiver).FullName}.{this.providerName}.{queueId}"); var receiverMonitor = this.ReceiverMonitorFactory(dimensions, this.telemetryProducer); IQueueAdapterReceiver receiver = new MemoryAdapterReceiver(GetQueueGrain(queueId), receiverLogger, this.serializer, receiverMonitor); @@ -196,7 +193,7 @@ public IQueueCache CreateQueueCache(QueueId queueId) //move block pool creation from init method to here, to avoid unnecessary block pool creation when stream provider is initialized in client side. CreateBufferPoolIfNotCreatedYet(); var logger = this.loggerFactory.CreateLogger($"{typeof(MemoryPooledCache).FullName}.{this.providerName}.{queueId}"); - var monitor = this.CacheMonitorFactory(new CacheMonitorDimensions(this.sharedDimensions, queueId.ToString(), this.blockPoolMonitorDimensions.BlockPoolId), this.telemetryProducer); + var monitor = this.CacheMonitorFactory(new CacheMonitorDimensions(queueId.ToString(), this.blockPoolMonitorDimensions.BlockPoolId), this.telemetryProducer); return new MemoryPooledCache(bufferPool, purgePredicate, logger, this.serializer, monitor, this.adapterConfig.StatisticMonitorWriteInterval); } diff --git a/test/AWSUtils.Tests/Reminder/DynamoDBRemindersTableTests.cs b/test/AWSUtils.Tests/Reminder/DynamoDBRemindersTableTests.cs index 8740adb025..33c0882d6c 100644 --- a/test/AWSUtils.Tests/Reminder/DynamoDBRemindersTableTests.cs +++ b/test/AWSUtils.Tests/Reminder/DynamoDBRemindersTableTests.cs @@ -1,4 +1,4 @@ -using System.Threading.Tasks; +using System.Threading.Tasks; using AWSUtils.Tests.StorageTests; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; @@ -25,7 +25,7 @@ protected override IReminderTable CreateRemindersTable() if (!AWSTestConstants.IsDynamoDbAvailable) throw new SkipException("Unable to connect to AWS DynamoDB simulator"); - return new DynamoDBReminderTable(this.ClusterFixture.Services.GetRequiredService(), this.loggerFactory, this.siloOptions); + return new DynamoDBReminderTable(this.ClusterFixture.Services.GetRequiredService(), this.loggerFactory, this.siloOptions, this.storageOptions); } protected override Task GetConnectionString() diff --git a/test/Benchmarks/Benchmarks/TransactionManager/TransactionManagerBentchmarks.cs b/test/Benchmarks/Benchmarks/TransactionManager/TransactionManagerBentchmarks.cs index 6b71dfa13b..93291870d8 100644 --- a/test/Benchmarks/Benchmarks/TransactionManager/TransactionManagerBentchmarks.cs +++ b/test/Benchmarks/Benchmarks/TransactionManager/TransactionManagerBentchmarks.cs @@ -1,4 +1,4 @@ - + using System; using System.Linq; using System.Threading.Tasks; @@ -8,6 +8,7 @@ using Microsoft.Extensions.Logging.Abstractions; using Orleans; using Orleans.Runtime.Configuration; +using Orleans.Hosting; using Orleans.Transactions.Abstractions; using Orleans.Transactions; using Orleans.Transactions.Development; @@ -23,7 +24,7 @@ public class TransactionManagerBenchmarks private const int ConcurrentTransactionsTransactions = TransactionsPerRun/10; private static readonly TimeSpan LogMaintenanceInterval = TimeSpan.FromMilliseconds(10); private static readonly TimeSpan TransactionTimeout = TimeSpan.FromSeconds(10); - List TransactionBatchTimeouts = Enumerable.Range(0, ConcurrentTransactionsTransactions) + List transactionBatchTimeouts = Enumerable.Range(0, ConcurrentTransactionsTransactions) .Select(i => TransactionTimeout) .ToList(); @@ -40,7 +41,7 @@ public void RunAgainstAzure() private async Task Run(Factory> storageFactory) { - ITransactionManager tm = new Orleans.Transactions.TransactionManager(new TransactionLog(storageFactory), Options.Create(new TransactionsOptions()), NullLoggerFactory.Instance, NullTelemetryProducer.Instance, () => new NodeConfiguration(), LogMaintenanceInterval); + ITransactionManager tm = new Orleans.Transactions.TransactionManager(new TransactionLog(storageFactory), Options.Create(new TransactionsOptions()), NullLoggerFactory.Instance, NullTelemetryProducer.Instance, Options.Create(new SiloStatisticsOptions()), LogMaintenanceInterval); await tm.StartAsync(); ITransactionManagerService tms = new TransactionManagerService(tm); Stopwatch sw; @@ -53,9 +54,9 @@ private async Task Run(Factory> storageFactory) while (generatedTransactions < TransactionsPerRun) { int generateCount = Math.Min(TransactionsPerRun - generatedTransactions, ConcurrentTransactionsTransactions - transactionsInFlight.Count); - StartTransactionsResponse startResponse = await tms.StartTransactions(TransactionBatchTimeouts.Take(generateCount).ToList()); + StartTransactionsResponse startResponse = await tms.StartTransactions(this.transactionBatchTimeouts.Take(generateCount).ToList()); List newTransactions = startResponse.TransactionId - .Select(MakeTransactionInfo) + .Select(this.MakeTransactionInfo) .ToList(); generatedTransactions += newTransactions.Count; Console.WriteLine($"Generated {newTransactions.Count} Transactions."); diff --git a/test/NetCore.Tests/NetCore.Tests.csproj b/test/NetCore.Tests/NetCore.Tests.csproj index eaa922dfe8..c71e3804d7 100644 --- a/test/NetCore.Tests/NetCore.Tests.csproj +++ b/test/NetCore.Tests/NetCore.Tests.csproj @@ -12,6 +12,7 @@ + diff --git a/test/NonSilo.Tests/OrleansRuntime/ExceptionsTests.cs b/test/NonSilo.Tests/OrleansRuntime/ExceptionsTests.cs index c1f1c7af38..97c7ec7306 100644 --- a/test/NonSilo.Tests/OrleansRuntime/ExceptionsTests.cs +++ b/test/NonSilo.Tests/OrleansRuntime/ExceptionsTests.cs @@ -15,7 +15,7 @@ public class ExceptionsTests public ExceptionsTests(TestEnvironmentFixture fixture) { this.fixture = fixture; - BufferPool.InitGlobalBufferPool(Options.Create(new ClientMessagingOptions())); + BufferPool.InitGlobalBufferPool(new ClientMessagingOptions()); } [Fact, TestCategory("Functional"), TestCategory("Serialization")] diff --git a/test/NonSilo.Tests/SchedulerTests/OrleansTaskSchedulerAdvancedTests.cs b/test/NonSilo.Tests/SchedulerTests/OrleansTaskSchedulerAdvancedTests.cs index 4286283d86..da65314df4 100644 --- a/test/NonSilo.Tests/SchedulerTests/OrleansTaskSchedulerAdvancedTests.cs +++ b/test/NonSilo.Tests/SchedulerTests/OrleansTaskSchedulerAdvancedTests.cs @@ -4,8 +4,9 @@ using System.Threading; using System.Threading.Tasks; using Microsoft.Extensions.Logging; -using Microsoft.Extensions.Logging.Abstractions; +using Microsoft.Extensions.Options; using Orleans; +using Orleans.Hosting; using Orleans.Runtime; using Orleans.Runtime.Counters; using Orleans.Runtime.Scheduler; @@ -29,21 +30,21 @@ public class OrleansTaskSchedulerAdvancedTests : MarshalByRefObject, IDisposable private static readonly TimeSpan OneSecond = TimeSpan.FromSeconds(1); private static readonly TimeSpan TwoSeconds = TimeSpan.FromSeconds(2); - private static readonly int waitFactor = Debugger.IsAttached ? 100 : 1; + private static readonly int WaitFactor = Debugger.IsAttached ? 100 : 1; private ILoggerFactory loggerFactory; public OrleansTaskSchedulerAdvancedTests(ITestOutputHelper output) { this.output = output; - loggerFactory = OrleansTaskSchedulerBasicTests.InitSchedulerLogging(); - this.performanceMetrics = new SiloPerformanceMetrics(new NoOpHostEnvironmentStatistics(loggerFactory), new AppEnvironmentStatistics(), this.loggerFactory); + this.loggerFactory = OrleansTaskSchedulerBasicTests.InitSchedulerLogging(); + this.performanceMetrics = new SiloPerformanceMetrics(new NoOpHostEnvironmentStatistics(this.loggerFactory), new AppEnvironmentStatistics(), this.loggerFactory, Options.Create(new SiloStatisticsOptions())); } public void Dispose() { - if (orleansTaskScheduler != null) + if (this.orleansTaskScheduler != null) { - orleansTaskScheduler.Stop(); + this.orleansTaskScheduler.Stop(); } this.loggerFactory.Dispose(); this.performanceMetrics.Dispose(); @@ -55,17 +56,17 @@ public void Sched_AC_Test() int n = 0; bool insideTask = false; UnitTestSchedulingContext context = new UnitTestSchedulingContext(); - orleansTaskScheduler = TestInternalHelper.InitializeSchedulerForTesting(context, this.performanceMetrics, loggerFactory); + this.orleansTaskScheduler = TestInternalHelper.InitializeSchedulerForTesting(context, this.performanceMetrics, this.loggerFactory); - output.WriteLine("Running Main in Context=" + RuntimeContext.Current); - orleansTaskScheduler.QueueWorkItem(new ClosureWorkItem(() => + this.output.WriteLine("Running Main in Context=" + RuntimeContext.Current); + this.orleansTaskScheduler.QueueWorkItem(new ClosureWorkItem(() => { for (int i = 0; i < 10; i++) { Task.Factory.StartNew(() => { // ReSharper disable AccessToModifiedClosure - output.WriteLine("Starting " + i + " in Context=" + RuntimeContext.Current); + this.output.WriteLine("Starting " + i + " in Context=" + RuntimeContext.Current); Assert.False(insideTask, $"Starting new task when I am already inside task of iteration {n}"); insideTask = true; int k = n; @@ -91,32 +92,32 @@ public async Task Sched_AC_WaitTest() int n = 0; bool insideTask = false; UnitTestSchedulingContext context = new UnitTestSchedulingContext(); - orleansTaskScheduler = TestInternalHelper.InitializeSchedulerForTesting(context, this.performanceMetrics, loggerFactory); + this.orleansTaskScheduler = TestInternalHelper.InitializeSchedulerForTesting(context, this.performanceMetrics, this.loggerFactory); var result = new TaskCompletionSource(); - orleansTaskScheduler.QueueWorkItem(new ClosureWorkItem(() => + this.orleansTaskScheduler.QueueWorkItem(new ClosureWorkItem(() => { var task1 = Task.Factory.StartNew(() => { - output.WriteLine("Starting 1"); + this.output.WriteLine("Starting 1"); Assert.False(insideTask, $"Starting new task when I am already inside task of iteration {n}"); insideTask = true; - output.WriteLine("===> 1a"); - Thread.Sleep(1000); n = n + 3; - output.WriteLine("===> 1b"); + this.output.WriteLine("===> 1a"); + Thread.Sleep(1000); n = n + 3; + this.output.WriteLine("===> 1b"); insideTask = false; }); var task2 = Task.Factory.StartNew(() => { - output.WriteLine("Starting 2"); + this.output.WriteLine("Starting 2"); Assert.False(insideTask, $"Starting new task when I am already inside task of iteration {n}"); insideTask = true; - output.WriteLine("===> 2a"); + this.output.WriteLine("===> 2a"); task1.Wait(); - output.WriteLine("===> 2b"); + this.output.WriteLine("===> 2b"); n = n * 5; - output.WriteLine("===> 2c"); + this.output.WriteLine("===> 2c"); insideTask = false; result.SetResult(true); }); @@ -141,7 +142,7 @@ public async Task Sched_AC_WaitTest() [Fact, TestCategory("Functional"), TestCategory("Scheduler")] public void Sched_AC_MainTurnWait_Test() { - orleansTaskScheduler = TestInternalHelper.InitializeSchedulerForTesting(new UnitTestSchedulingContext(), this.performanceMetrics, loggerFactory); + this.orleansTaskScheduler = TestInternalHelper.InitializeSchedulerForTesting(new UnitTestSchedulingContext(), this.performanceMetrics, this.loggerFactory); var promise = Task.Factory.StartNew(() => { Thread.Sleep(1000); @@ -151,17 +152,17 @@ public void Sched_AC_MainTurnWait_Test() private void SubProcess1(int n) { - string msg = string.Format("1-{0} MainDone={1} inside Task {2}", n, mainDone, Task.CurrentId); - output.WriteLine("1 ===> " + msg); - Assert.True(mainDone, msg + " -- Main turn should be finished"); - stageNum1 = n; + string msg = string.Format("1-{0} MainDone={1} inside Task {2}", n, this.mainDone, Task.CurrentId); + this.output.WriteLine("1 ===> " + msg); + Assert.True(this.mainDone, msg + " -- Main turn should be finished"); + this.stageNum1 = n; } private void SubProcess2(int n) { - string msg = string.Format("2-{0} MainDone={1} inside Task {2}", n, mainDone, Task.CurrentId); - output.WriteLine("2 ===> " + msg); - Assert.True(mainDone, msg + " -- Main turn should be finished"); - stageNum2 = n; + string msg = string.Format("2-{0} MainDone={1} inside Task {2}", n, this.mainDone, Task.CurrentId); + this.output.WriteLine("2 ===> " + msg); + Assert.True(this.mainDone, msg + " -- Main turn should be finished"); + this.stageNum2 = n; } [Fact, TestCategory("Functional"), TestCategory("Scheduler")] @@ -172,15 +173,15 @@ public async Task Sched_AC_Turn_Execution_Order() // You test that no CW/StartNew runs until the main turn is fully done. And run in stress. UnitTestSchedulingContext context = new UnitTestSchedulingContext(); - orleansTaskScheduler = TestInternalHelper.InitializeSchedulerForTesting(context, this.performanceMetrics, loggerFactory); + this.orleansTaskScheduler = TestInternalHelper.InitializeSchedulerForTesting(context, this.performanceMetrics, this.loggerFactory); var result1 = new TaskCompletionSource(); var result2 = new TaskCompletionSource(); - orleansTaskScheduler.QueueWorkItem(new ClosureWorkItem(() => + this.orleansTaskScheduler.QueueWorkItem(new ClosureWorkItem(() => { - mainDone = false; - stageNum1 = stageNum2 = 0; + this.mainDone = false; + this.stageNum1 = this.stageNum2 = 0; Task task1 = Task.Factory.StartNew(() => SubProcess1(11)); Task task2 = task1.ContinueWith((_) => SubProcess1(12)); @@ -193,7 +194,7 @@ public async Task Sched_AC_Turn_Execution_Order() task22.Ignore(); Thread.Sleep(TimeSpan.FromSeconds(1)); - mainDone = true; + this.mainDone = true; }), context); try { await result1.Task.WithTimeout(TimeSpan.FromSeconds(3)); } @@ -201,10 +202,10 @@ public async Task Sched_AC_Turn_Execution_Order() try { await result2.Task.WithTimeout(TimeSpan.FromSeconds(3)); } catch (TimeoutException) { Assert.True(false, "Timeout-2"); } - Assert.NotEqual(0, stageNum1); // "Work items did not get executed-1" - Assert.NotEqual(0, stageNum2); // "Work items did not get executed-2" - Assert.Equal(14, stageNum1); // "Work items executed out of order-1" - Assert.Equal(22, stageNum2); // "Work items executed out of order-2" + Assert.NotEqual(0, this.stageNum1); // "Work items did not get executed-1" + Assert.NotEqual(0, this.stageNum2); // "Work items did not get executed-2" + Assert.Equal(14, this.stageNum1); // "Work items executed out of order-1" + Assert.Equal(22, this.stageNum2); // "Work items executed out of order-2" } [Fact, TestCategory("Functional"), TestCategory("Scheduler")] @@ -215,12 +216,12 @@ public void Sched_Task_Turn_Execution_Order() // You test that no CW/StartNew runs until the main turn is fully done. And run in stress. UnitTestSchedulingContext context = new UnitTestSchedulingContext(); - OrleansTaskScheduler masterScheduler = orleansTaskScheduler = TestInternalHelper.InitializeSchedulerForTesting(context, this.performanceMetrics, loggerFactory); - WorkItemGroup workItemGroup = orleansTaskScheduler.GetWorkItemGroup(context); + OrleansTaskScheduler masterScheduler = this.orleansTaskScheduler = TestInternalHelper.InitializeSchedulerForTesting(context, this.performanceMetrics, this.loggerFactory); + WorkItemGroup workItemGroup = this.orleansTaskScheduler.GetWorkItemGroup(context); ActivationTaskScheduler activationScheduler = workItemGroup.TaskRunner; - mainDone = false; - stageNum1 = stageNum2 = 0; + this.mainDone = false; + this.stageNum1 = this.stageNum2 = 0; var result1 = new TaskCompletionSource(); var result2 = new TaskCompletionSource(); @@ -298,37 +299,37 @@ public void Sched_Task_Turn_Execution_Order() Log(15, "Outer ClosureWorkItem Task Id=" + Task.CurrentId + " awake"); Log(16, "Finished Outer ClosureWorkItem Task Id=" + wrapper.Id); - mainDone = true; + this.mainDone = true; }), context); Log(17, "Waiting for ClosureWorkItem to spawn wrapper Task"); - for (int i = 0; i < 5 * waitFactor; i++) + for (int i = 0; i < 5 * WaitFactor; i++) { if (wrapper != null) break; - Thread.Sleep(TimeSpan.FromSeconds(1).Multiply(waitFactor)); + Thread.Sleep(TimeSpan.FromSeconds(1).Multiply(WaitFactor)); } Assert.NotNull(wrapper); // Wrapper Task was not created Log(18, "Waiting for wrapper Task Id=" + wrapper.Id + " to complete"); - bool finished = wrapper.Wait(TimeSpan.FromSeconds(4 * waitFactor)); + bool finished = wrapper.Wait(TimeSpan.FromSeconds(4 * WaitFactor)); Log(19, "Done waiting for wrapper Task Id=" + wrapper.Id + " Finished=" + finished); if (!finished) throw new TimeoutException(); Assert.False(wrapper.IsFaulted, "Wrapper Task faulted: " + wrapper.Exception); Assert.True(wrapper.IsCompleted, "Wrapper Task should be completed"); Log(20, "Waiting for TaskWorkItem to complete"); - for (int i = 0; i < 15 * waitFactor; i++) + for (int i = 0; i < 15 * WaitFactor; i++) { - if (mainDone) break; - Thread.Sleep(1000 * waitFactor); + if (this.mainDone) break; + Thread.Sleep(1000 * WaitFactor); } - Log(21, "Done waiting for TaskWorkItem to complete MainDone=" + mainDone); - Assert.True(mainDone, "Main Task should be completed"); + Log(21, "Done waiting for TaskWorkItem to complete MainDone=" + this.mainDone); + Assert.True(this.mainDone, "Main Task should be completed"); Assert.NotNull(finalTask1); // Task chain #1 not created Assert.NotNull(finalPromise2); // Task chain #2 not created Log(22, "Waiting for final task #1 to complete"); - bool ok = finalTask1.Wait(TimeSpan.FromSeconds(4 * waitFactor)); + bool ok = finalTask1.Wait(TimeSpan.FromSeconds(4 * WaitFactor)); Log(23, "Done waiting for final task #1 complete Ok=" + ok); if (!ok) throw new TimeoutException(); Assert.False(finalTask1.IsFaulted, "Final Task faulted: " + finalTask1.Exception); @@ -336,28 +337,28 @@ public void Sched_Task_Turn_Execution_Order() Assert.True(result1.Task.Result, "Timeout-1"); Log(24, "Waiting for final promise #2 to complete"); - finalPromise2.Wait(TimeSpan.FromSeconds(4 * waitFactor)); + finalPromise2.Wait(TimeSpan.FromSeconds(4 * WaitFactor)); Log(25, "Done waiting for final promise #2"); Assert.False(finalPromise2.IsFaulted, "Final Task faulted: " + finalPromise2.Exception); Assert.True(finalPromise2.IsCompleted, "Final Task completed"); Assert.True(result2.Task.Result, "Timeout-2"); - Assert.NotEqual(0, stageNum1); // "Work items did not get executed-1" - Assert.Equal(14, stageNum1); // "Work items executed out of order-1" - Assert.NotEqual(0, stageNum2); // "Work items did not get executed-2" - Assert.Equal(22, stageNum2); // "Work items executed out of order-2" + Assert.NotEqual(0, this.stageNum1); // "Work items did not get executed-1" + Assert.Equal(14, this.stageNum1); // "Work items executed out of order-1" + Assert.NotEqual(0, this.stageNum2); // "Work items did not get executed-2" + Assert.Equal(22, this.stageNum2); // "Work items executed out of order-2" } [Fact, TestCategory("Functional"), TestCategory("Scheduler")] public void Sched_AC_Current_TaskScheduler() { UnitTestSchedulingContext context = new UnitTestSchedulingContext(); - OrleansTaskScheduler orleansTaskScheduler = orleansTaskScheduler = TestInternalHelper.InitializeSchedulerForTesting(context, this.performanceMetrics, loggerFactory); + OrleansTaskScheduler orleansTaskScheduler = orleansTaskScheduler = TestInternalHelper.InitializeSchedulerForTesting(context, this.performanceMetrics, this.loggerFactory); ActivationTaskScheduler activationScheduler = orleansTaskScheduler.GetWorkItemGroup(context).TaskRunner; // RuntimeContext.InitializeThread(masterScheduler); - mainDone = false; + this.mainDone = false; var result = new TaskCompletionSource(); @@ -407,60 +408,60 @@ public void Sched_AC_Current_TaskScheduler() Log(11, "Outer ClosureWorkItem Task Id=" + Task.CurrentId + " awake"); Log(12, "Finished Outer TaskWorkItem Task Id=" + wrapper.Id); - mainDone = true; + this.mainDone = true; }), context); Log(13, "Waiting for ClosureWorkItem to spawn wrapper Task"); - for (int i = 0; i < 5 * waitFactor; i++) + for (int i = 0; i < 5 * WaitFactor; i++) { if (wrapper != null) break; - Thread.Sleep(TimeSpan.FromSeconds(1).Multiply(waitFactor)); + Thread.Sleep(TimeSpan.FromSeconds(1).Multiply(WaitFactor)); } Assert.NotNull(wrapper); // Wrapper Task was not created Log(14, "Waiting for wrapper Task Id=" + wrapper.Id + " to complete"); - bool finished = wrapper.Wait(TimeSpan.FromSeconds(4 * waitFactor)); + bool finished = wrapper.Wait(TimeSpan.FromSeconds(4 * WaitFactor)); Log(15, "Done waiting for wrapper Task Id=" + wrapper.Id + " Finished=" + finished); if (!finished) throw new TimeoutException(); Assert.False(wrapper.IsFaulted, "Wrapper Task faulted: " + wrapper.Exception); Assert.True(wrapper.IsCompleted, "Wrapper Task should be completed"); Log(16, "Waiting for TaskWorkItem to complete"); - for (int i = 0; i < 15 * waitFactor; i++) + for (int i = 0; i < 15 * WaitFactor; i++) { - if (mainDone) break; - Thread.Sleep(1000 * waitFactor); + if (this.mainDone) break; + Thread.Sleep(1000 * WaitFactor); } - Log(17, "Done waiting for TaskWorkItem to complete MainDone=" + mainDone); - Assert.True(mainDone, "Main Task should be completed"); + Log(17, "Done waiting for TaskWorkItem to complete MainDone=" + this.mainDone); + Assert.True(this.mainDone, "Main Task should be completed"); Assert.NotNull(finalPromise); // AC chain not created Log(18, "Waiting for final AC promise to complete"); - finalPromise.Wait(TimeSpan.FromSeconds(4 * waitFactor)); + finalPromise.Wait(TimeSpan.FromSeconds(4 * WaitFactor)); Log(19, "Done waiting for final promise"); Assert.False(finalPromise.IsFaulted, "Final AC faulted: " + finalPromise.Exception); Assert.True(finalPromise.IsCompleted, "Final AC completed"); Assert.True(result.Task.Result, "Timeout-1"); - Assert.NotEqual(0, stageNum1); // "Work items did not get executed-1" - Assert.Equal(3, stageNum1); // "Work items executed out of order-1" + Assert.NotEqual(0, this.stageNum1); // "Work items did not get executed-1" + Assert.Equal(3, this.stageNum1); // "Work items executed out of order-1" } [Fact, TestCategory("Functional"), TestCategory("Scheduler")] public void Sched_AC_ContinueWith_1_Test() { UnitTestSchedulingContext context = new UnitTestSchedulingContext(); - orleansTaskScheduler = TestInternalHelper.InitializeSchedulerForTesting(context, this.performanceMetrics, loggerFactory); + this.orleansTaskScheduler = TestInternalHelper.InitializeSchedulerForTesting(context, this.performanceMetrics, this.loggerFactory); var result = new TaskCompletionSource(); int n = 0; // ReSharper disable AccessToModifiedClosure - orleansTaskScheduler.QueueWorkItem(new ClosureWorkItem(() => + this.orleansTaskScheduler.QueueWorkItem(new ClosureWorkItem(() => { - Task task1 = Task.Factory.StartNew(() => { output.WriteLine("===> 1a"); Thread.Sleep(OneSecond); n = n + 3; output.WriteLine("===> 1b"); }); - Task task2 = task1.ContinueWith((_) => { n = n * 5; output.WriteLine("===> 2"); }); - Task task3 = task2.ContinueWith((_) => { n = n / 5; output.WriteLine("===> 3"); }); - Task task4 = task3.ContinueWith((_) => { n = n - 2; output.WriteLine("===> 4"); result.SetResult(true); }); + Task task1 = Task.Factory.StartNew(() => { this.output.WriteLine("===> 1a"); Thread.Sleep(OneSecond); n = n + 3; this.output.WriteLine("===> 1b"); }); + Task task2 = task1.ContinueWith((_) => { n = n * 5; this.output.WriteLine("===> 2"); }); + Task task3 = task2.ContinueWith((_) => { n = n / 5; this.output.WriteLine("===> 3"); }); + Task task4 = task3.ContinueWith((_) => { n = n - 2; this.output.WriteLine("===> 4"); result.SetResult(true); }); task4.Ignore(); }), context); // ReSharper restore AccessToModifiedClosure @@ -481,15 +482,15 @@ public void Sched_Task_JoinAll() stopwatch.Start(); UnitTestSchedulingContext context = new UnitTestSchedulingContext(); - orleansTaskScheduler = TestInternalHelper.InitializeSchedulerForTesting(context, this.performanceMetrics, loggerFactory); + this.orleansTaskScheduler = TestInternalHelper.InitializeSchedulerForTesting(context, this.performanceMetrics, this.loggerFactory); // ReSharper disable AccessToModifiedClosure - orleansTaskScheduler.QueueWorkItem(new ClosureWorkItem(() => + this.orleansTaskScheduler.QueueWorkItem(new ClosureWorkItem(() => { - Task task1 = Task.Factory.StartNew(() => { output.WriteLine("===> 1a"); Thread.Sleep(OneSecond); n = n + 3; output.WriteLine("===> 1b"); return 1; }); - Task task2 = Task.Factory.StartNew(() => { output.WriteLine("===> 2a"); Thread.Sleep(OneSecond); n = n + 3; output.WriteLine("===> 2b"); return 2; }); - Task task3 = Task.Factory.StartNew(() => { output.WriteLine("===> 3a"); Thread.Sleep(OneSecond); n = n + 3; output.WriteLine("===> 3b"); return 3; }); - Task task4 = Task.Factory.StartNew(() => { output.WriteLine("===> 4a"); Thread.Sleep(OneSecond); n = n + 3; output.WriteLine("===> 4b"); return 4; }); + Task task1 = Task.Factory.StartNew(() => { this.output.WriteLine("===> 1a"); Thread.Sleep(OneSecond); n = n + 3; this.output.WriteLine("===> 1b"); return 1; }); + Task task2 = Task.Factory.StartNew(() => { this.output.WriteLine("===> 2a"); Thread.Sleep(OneSecond); n = n + 3; this.output.WriteLine("===> 2b"); return 2; }); + Task task3 = Task.Factory.StartNew(() => { this.output.WriteLine("===> 3a"); Thread.Sleep(OneSecond); n = n + 3; this.output.WriteLine("===> 3b"); return 3; }); + Task task4 = Task.Factory.StartNew(() => { this.output.WriteLine("===> 4a"); Thread.Sleep(OneSecond); n = n + 3; this.output.WriteLine("===> 4b"); return 4; }); tasks = new Task[] {task1, task2, task3, task4}; result.SetResult(true); }),context); @@ -524,31 +525,31 @@ public void Sched_Task_JoinAll() [Fact, TestCategory("Functional"), TestCategory("Scheduler")] public void Sched_AC_ContinueWith_2_OrleansSched() { - orleansTaskScheduler = TestInternalHelper.InitializeSchedulerForTesting(new UnitTestSchedulingContext(), this.performanceMetrics, loggerFactory); + this.orleansTaskScheduler = TestInternalHelper.InitializeSchedulerForTesting(new UnitTestSchedulingContext(), this.performanceMetrics, this.loggerFactory); var result1 = new TaskCompletionSource(); var result2 = new TaskCompletionSource(); bool failed1 = false; bool failed2 = false; - Task task1 = Task.Factory.StartNew(() => { output.WriteLine("===> 1a"); Thread.Sleep(OneSecond); throw new ArgumentException(); }); + Task task1 = Task.Factory.StartNew(() => { this.output.WriteLine("===> 1a"); Thread.Sleep(OneSecond); throw new ArgumentException(); }); Task task2 = task1.ContinueWith((Task t) => { - if (!t.IsFaulted) output.WriteLine("===> 2"); + if (!t.IsFaulted) this.output.WriteLine("===> 2"); else { - output.WriteLine("===> 3"); + this.output.WriteLine("===> 3"); failed1 = true; result1.SetResult(true); } }); Task task3 = task1.ContinueWith((Task t) => { - if (!t.IsFaulted) output.WriteLine("===> 4"); + if (!t.IsFaulted) this.output.WriteLine("===> 4"); else { - output.WriteLine("===> 5"); + this.output.WriteLine("===> 5"); failed2 = true; result2.SetResult(true); } @@ -567,8 +568,8 @@ public void Sched_AC_ContinueWith_2_OrleansSched() public void Sched_Task_SchedulingContext() { UnitTestSchedulingContext context = new UnitTestSchedulingContext(); - orleansTaskScheduler = TestInternalHelper.InitializeSchedulerForTesting(context, this.performanceMetrics, loggerFactory); - ActivationTaskScheduler scheduler = orleansTaskScheduler.GetWorkItemGroup(context).TaskRunner; + this.orleansTaskScheduler = TestInternalHelper.InitializeSchedulerForTesting(context, this.performanceMetrics, this.loggerFactory); + ActivationTaskScheduler scheduler = this.orleansTaskScheduler.GetWorkItemGroup(context).TaskRunner; var result = new TaskCompletionSource(); Task endOfChain = null; @@ -581,28 +582,28 @@ public void Sched_Task_SchedulingContext() // ReSharper disable AccessToModifiedClosure Task task1 = Task.Factory.StartNew(() => { - output.WriteLine("===> 1a "); + this.output.WriteLine("===> 1a "); CheckRuntimeContext(context); Thread.Sleep(1000); - n = n + 3; - output.WriteLine("===> 1b"); + n = n + 3; + this.output.WriteLine("===> 1b"); CheckRuntimeContext(context); }); Task task2 = task1.ContinueWith(task => { - output.WriteLine("===> 2"); + this.output.WriteLine("===> 2"); CheckRuntimeContext(context); n = n * 5; }); Task task3 = task2.ContinueWith(task => { - output.WriteLine("===> 3"); + this.output.WriteLine("===> 3"); n = n / 5; CheckRuntimeContext(context); }); Task task4 = task3.ContinueWith(task => { - output.WriteLine("===> 4"); + this.output.WriteLine("===> 4"); n = n - 2; result.SetResult(true); CheckRuntimeContext(context); @@ -610,7 +611,7 @@ public void Sched_Task_SchedulingContext() // ReSharper restore AccessToModifiedClosure endOfChain = task4.ContinueWith(task => { - output.WriteLine("Done Faulted={0}", task.IsFaulted); + this.output.WriteLine("Done Faulted={0}", task.IsFaulted); CheckRuntimeContext(context); Assert.False(task.IsFaulted, "Faulted with Exception=" + task.Exception); }); @@ -631,7 +632,7 @@ public void Sched_Task_SchedulingContext() private void Log(int level, string what) { - output.WriteLine("#{0} - {1} -- Thread={2} Worker={3} TaskScheduler.Current={4}", + this.output.WriteLine("#{0} - {1} -- Thread={2} Worker={3} TaskScheduler.Current={4}", level, what, Thread.CurrentThread.ManagedThreadId, WorkerPoolThread.CurrentWorkerThread == null ? "Null" : WorkerPoolThread.CurrentWorkerThread.Name, diff --git a/test/NonSilo.Tests/SchedulerTests/OrleansTaskSchedulerAdvancedTests_Set2.cs b/test/NonSilo.Tests/SchedulerTests/OrleansTaskSchedulerAdvancedTests_Set2.cs index 13cdc94f53..e83ad239b9 100644 --- a/test/NonSilo.Tests/SchedulerTests/OrleansTaskSchedulerAdvancedTests_Set2.cs +++ b/test/NonSilo.Tests/SchedulerTests/OrleansTaskSchedulerAdvancedTests_Set2.cs @@ -7,6 +7,7 @@ using Microsoft.Extensions.Logging.Abstractions; using Microsoft.Extensions.Options; using Orleans; +using Orleans.Hosting; using Orleans.Runtime; using Orleans.Runtime.Configuration; using Orleans.Runtime.Counters; @@ -22,9 +23,9 @@ namespace UnitTests.SchedulerTests { public class OrleansTaskSchedulerAdvancedTests_Set2 : IDisposable { - private static readonly object lockable = new object(); - private static readonly int waitFactor = Debugger.IsAttached ? 100 : 1; - private static readonly SafeRandom random = new SafeRandom(); + private static readonly object Lockable = new object(); + private static readonly int WaitFactor = Debugger.IsAttached ? 100 : 1; + private static readonly SafeRandom Random = new SafeRandom(); private readonly ITestOutputHelper output; private readonly OrleansTaskScheduler masterScheduler; private readonly UnitTestSchedulingContext context; @@ -33,15 +34,15 @@ public class OrleansTaskSchedulerAdvancedTests_Set2 : IDisposable public OrleansTaskSchedulerAdvancedTests_Set2(ITestOutputHelper output) { this.output = output; - loggerFactory = OrleansTaskSchedulerBasicTests.InitSchedulerLogging(); - context = new UnitTestSchedulingContext(); - this.performanceMetrics = new SiloPerformanceMetrics(new NoOpHostEnvironmentStatistics(loggerFactory), new AppEnvironmentStatistics(), this.loggerFactory); - masterScheduler = TestInternalHelper.InitializeSchedulerForTesting(context, this.performanceMetrics, loggerFactory); + this.loggerFactory = OrleansTaskSchedulerBasicTests.InitSchedulerLogging(); + this.context = new UnitTestSchedulingContext(); + this.performanceMetrics = new SiloPerformanceMetrics(new NoOpHostEnvironmentStatistics(this.loggerFactory), new AppEnvironmentStatistics(), this.loggerFactory, Options.Create(new SiloStatisticsOptions())); + this.masterScheduler = TestInternalHelper.InitializeSchedulerForTesting(this.context, this.performanceMetrics, this.loggerFactory); } public void Dispose() { - masterScheduler.Stop(); + this.masterScheduler.Stop(); this.loggerFactory.Dispose(); this.performanceMetrics.Dispose(); } @@ -51,7 +52,7 @@ public void ActivationSched_SimpleFifoTest() { // This is not a great test because there's a 50/50 shot that it will work even if the scheduling // is completely and thoroughly broken and both closures are executed "simultaneously" - TaskScheduler scheduler = masterScheduler.GetWorkItemGroup(context).TaskRunner; + TaskScheduler scheduler = this.masterScheduler.GetWorkItemGroup(this.context).TaskRunner; int n = 0; // ReSharper disable AccessToModifiedClosure @@ -73,16 +74,16 @@ public void ActivationSched_SimpleFifoTest() [Fact, TestCategory("Functional"), TestCategory("Scheduler")] public void ActivationSched_NewTask_ContinueWith_Wrapped() { - TaskScheduler scheduler = masterScheduler.GetWorkItemGroup(context).TaskRunner; + TaskScheduler scheduler = this.masterScheduler.GetWorkItemGroup(this.context).TaskRunner; Task wrapped = new Task(() => { - output.WriteLine("#0 - new Task - SynchronizationContext.Current={0} TaskScheduler.Current={1}", + this.output.WriteLine("#0 - new Task - SynchronizationContext.Current={0} TaskScheduler.Current={1}", SynchronizationContext.Current, TaskScheduler.Current); Task t0 = new Task(() => { - output.WriteLine("#1 - new Task - SynchronizationContext.Current={0} TaskScheduler.Current={1}", + this.output.WriteLine("#1 - new Task - SynchronizationContext.Current={0} TaskScheduler.Current={1}", SynchronizationContext.Current, TaskScheduler.Current); Assert.Equal(scheduler, TaskScheduler.Current); // "TaskScheduler.Current #1" }); @@ -90,7 +91,7 @@ public void ActivationSched_NewTask_ContinueWith_Wrapped() { Assert.False(task.IsFaulted, "Task #1 Faulted=" + task.Exception); - output.WriteLine("#2 - new Task - SynchronizationContext.Current={0} TaskScheduler.Current={1}", + this.output.WriteLine("#2 - new Task - SynchronizationContext.Current={0} TaskScheduler.Current={1}", SynchronizationContext.Current, TaskScheduler.Current); Assert.Equal(scheduler, TaskScheduler.Current); // "TaskScheduler.Current #2" }); @@ -105,7 +106,7 @@ public void ActivationSched_NewTask_ContinueWith_Wrapped() [Fact, TestCategory("Functional"), TestCategory("Scheduler")] public void ActivationSched_SubTaskExecutionSequencing() { - TaskScheduler scheduler = masterScheduler.GetWorkItemGroup(context).TaskRunner; + TaskScheduler scheduler = this.masterScheduler.GetWorkItemGroup(this.context).TaskRunner; LogContext("Main-task " + Task.CurrentId); @@ -125,9 +126,9 @@ public void ActivationSched_SubTaskExecutionSequencing() // ReSharper disable AccessToModifiedClosure LogContext("Sub-task " + id + " n=" + n); int k = n; - output.WriteLine("Sub-task " + id + " sleeping"); + this.output.WriteLine("Sub-task " + id + " sleeping"); Thread.Sleep(100); - output.WriteLine("Sub-task " + id + " awake"); + this.output.WriteLine("Sub-task " + id + " awake"); n = k + 1; // ReSharper restore AccessToModifiedClosure }) @@ -135,7 +136,7 @@ public void ActivationSched_SubTaskExecutionSequencing() { LogContext("Sub-task " + id + "-ContinueWith"); - output.WriteLine("Sub-task " + id + " Done"); + this.output.WriteLine("Sub-task " + id + " Done"); }); } }; @@ -145,9 +146,9 @@ public void ActivationSched_SubTaskExecutionSequencing() t.Start(scheduler); // Pause to let things run - output.WriteLine("Main-task sleeping"); + this.output.WriteLine("Main-task sleeping"); Thread.Sleep(TimeSpan.FromSeconds(2)); - output.WriteLine("Main-task awake"); + this.output.WriteLine("Main-task awake"); // N should be 10, because all tasks should execute serially Assert.True(n != 0, "Work items did not get executed"); @@ -157,7 +158,7 @@ public void ActivationSched_SubTaskExecutionSequencing() [Fact, TestCategory("Functional"), TestCategory("Scheduler")] public async Task ActivationSched_ContinueWith_1_Test() { - TaskScheduler scheduler = masterScheduler.GetWorkItemGroup(context).TaskRunner; + TaskScheduler scheduler = this.masterScheduler.GetWorkItemGroup(this.context).TaskRunner; var result = new TaskCompletionSource(); int n = 0; @@ -165,14 +166,14 @@ public async Task ActivationSched_ContinueWith_1_Test() Task wrapper = new Task(() => { // ReSharper disable AccessToModifiedClosure - Task task1 = Task.Factory.StartNew(() => { output.WriteLine("===> 1a"); Thread.Sleep(1000); n = n + 3; output.WriteLine("===> 1b"); }); - Task task2 = task1.ContinueWith(task => { n = n * 5; output.WriteLine("===> 2"); }); - Task task3 = task2.ContinueWith(task => { n = n / 5; output.WriteLine("===> 3"); }); - Task task4 = task3.ContinueWith(task => { n = n - 2; output.WriteLine("===> 4"); result.SetResult(true); }); + Task task1 = Task.Factory.StartNew(() => { this.output.WriteLine("===> 1a"); Thread.Sleep(1000); n = n + 3; this.output.WriteLine("===> 1b"); }); + Task task2 = task1.ContinueWith(task => { n = n * 5; this.output.WriteLine("===> 2"); }); + Task task3 = task2.ContinueWith(task => { n = n / 5; this.output.WriteLine("===> 3"); }); + Task task4 = task3.ContinueWith(task => { n = n - 2; this.output.WriteLine("===> 4"); result.SetResult(true); }); // ReSharper restore AccessToModifiedClosure task4.ContinueWith(task => { - output.WriteLine("Done Faulted={0}", task.IsFaulted); + this.output.WriteLine("Done Faulted={0}", task.IsFaulted); Assert.False(task.IsFaulted, "Faulted with Exception=" + task.Exception); }); }); @@ -195,7 +196,7 @@ public async Task ActivationSched_ContinueWith_1_Test() [Fact, TestCategory("Functional"), TestCategory("Scheduler")] public async Task ActivationSched_WhenAny() { - TaskScheduler scheduler = masterScheduler.GetWorkItemGroup(context).TaskRunner; + TaskScheduler scheduler = this.masterScheduler.GetWorkItemGroup(this.context).TaskRunner; ManualResetEvent pause1 = new ManualResetEvent(false); ManualResetEvent pause2 = new ManualResetEvent(false); @@ -207,18 +208,18 @@ public async Task ActivationSched_WhenAny() { task1 = Task.Factory.StartNew(() => { - output.WriteLine("Task-1 Started"); + this.output.WriteLine("Task-1 Started"); Assert.Equal(scheduler, TaskScheduler.Current); // "TaskScheduler.Current=" + TaskScheduler.Current pause1.WaitOne(); - output.WriteLine("Task-1 Done"); + this.output.WriteLine("Task-1 Done"); return 1; }); task2 = Task.Factory.StartNew(() => { - output.WriteLine("Task-2 Started"); + this.output.WriteLine("Task-2 Started"); Assert.Equal(scheduler, TaskScheduler.Current); pause2.WaitOne(); - output.WriteLine("Task-2 Done"); + this.output.WriteLine("Task-2 Done"); return 2; }); @@ -251,7 +252,7 @@ public async Task ActivationSched_WhenAny() [Fact, TestCategory("Functional"), TestCategory("Scheduler")] public async Task ActivationSched_WhenAny_Timeout() { - TaskScheduler scheduler = masterScheduler.GetWorkItemGroup(context).TaskRunner; + TaskScheduler scheduler = this.masterScheduler.GetWorkItemGroup(this.context).TaskRunner; ManualResetEvent pause1 = new ManualResetEvent(false); ManualResetEvent pause2 = new ManualResetEvent(false); @@ -263,18 +264,18 @@ public async Task ActivationSched_WhenAny_Timeout() { task1 = Task.Factory.StartNew(() => { - output.WriteLine("Task-1 Started"); + this.output.WriteLine("Task-1 Started"); Assert.Equal(scheduler, TaskScheduler.Current); pause1.WaitOne(); - output.WriteLine("Task-1 Done"); + this.output.WriteLine("Task-1 Done"); return 1; }); task2 = Task.Factory.StartNew(() => { - output.WriteLine("Task-2 Started"); + this.output.WriteLine("Task-2 Started"); Assert.Equal(scheduler, TaskScheduler.Current); pause2.WaitOne(); - output.WriteLine("Task-2 Done"); + this.output.WriteLine("Task-2 Done"); return 2; }); @@ -310,7 +311,7 @@ public async Task ActivationSched_WhenAny_Timeout() [Fact, TestCategory("Functional"), TestCategory("Scheduler")] public async Task ActivationSched_WhenAny_Busy_Timeout() { - TaskScheduler scheduler = masterScheduler.GetWorkItemGroup(context).TaskRunner; + TaskScheduler scheduler = this.masterScheduler.GetWorkItemGroup(this.context).TaskRunner; var pause1 = new TaskCompletionSource(); var pause2 = new TaskCompletionSource(); @@ -322,26 +323,26 @@ public async Task ActivationSched_WhenAny_Busy_Timeout() { task1 = Task.Factory.StartNew(() => { - output.WriteLine("Task-1 Started"); + this.output.WriteLine("Task-1 Started"); Assert.Equal(scheduler, TaskScheduler.Current); int num1 = 1; while (!pause1.Task.Result) // Infinite busy loop { - num1 = random.Next(); + num1 = Random.Next(); } - output.WriteLine("Task-1 Done"); + this.output.WriteLine("Task-1 Done"); return num1; }); task2 = Task.Factory.StartNew(() => { - output.WriteLine("Task-2 Started"); + this.output.WriteLine("Task-2 Started"); Assert.Equal(scheduler, TaskScheduler.Current); int num2 = 2; while (!pause2.Task.Result) // Infinite busy loop { - num2 = random.Next(); + num2 = Random.Next(); } - output.WriteLine("Task-2 Done"); + this.output.WriteLine("Task-2 Done"); return num2; }); @@ -374,7 +375,7 @@ public async Task ActivationSched_WhenAny_Busy_Timeout() [Fact, TestCategory("Functional"), TestCategory("Scheduler")] public async Task ActivationSched_Task_Run() { - TaskScheduler scheduler = masterScheduler.GetWorkItemGroup(context).TaskRunner; + TaskScheduler scheduler = this.masterScheduler.GetWorkItemGroup(this.context).TaskRunner; ManualResetEvent pause1 = new ManualResetEvent(false); ManualResetEvent pause2 = new ManualResetEvent(false); @@ -386,27 +387,27 @@ public async Task ActivationSched_Task_Run() { task1 = Task.Run(() => { - output.WriteLine("Task-1 Started"); + this.output.WriteLine("Task-1 Started"); Assert.NotEqual(scheduler, TaskScheduler.Current); pause1.WaitOne(); - output.WriteLine("Task-1 Done"); + this.output.WriteLine("Task-1 Done"); return 1; }); task2 = Task.Run(() => { - output.WriteLine("Task-2 Started"); + this.output.WriteLine("Task-2 Started"); Assert.NotEqual(scheduler, TaskScheduler.Current); pause2.WaitOne(); - output.WriteLine("Task-2 Done"); + this.output.WriteLine("Task-2 Done"); return 2; }); join = Task.WhenAll(task1, task2).ContinueWith(t => { - output.WriteLine("Join Started"); + this.output.WriteLine("Join Started"); if (t.IsFaulted) throw t.Exception; Assert.Equal(scheduler, TaskScheduler.Current); - output.WriteLine("Join Done"); + this.output.WriteLine("Join Done"); }); finish.SetResult(true); @@ -435,7 +436,7 @@ public async Task ActivationSched_Task_Run() [Fact, TestCategory("Functional"), TestCategory("Scheduler")] public async Task ActivationSched_Task_Run_Delay() { - TaskScheduler scheduler = masterScheduler.GetWorkItemGroup(context).TaskRunner; + TaskScheduler scheduler = this.masterScheduler.GetWorkItemGroup(this.context).TaskRunner; ManualResetEvent pause1 = new ManualResetEvent(false); ManualResetEvent pause2 = new ManualResetEvent(false); @@ -447,31 +448,31 @@ public async Task ActivationSched_Task_Run_Delay() { task1 = Task.Run(() => { - output.WriteLine("Task-1 Started"); + this.output.WriteLine("Task-1 Started"); Assert.NotEqual(scheduler, TaskScheduler.Current); Task.Delay(1); Assert.NotEqual(scheduler, TaskScheduler.Current); pause1.WaitOne(); - output.WriteLine("Task-1 Done"); + this.output.WriteLine("Task-1 Done"); return 1; }); task2 = Task.Run(() => { - output.WriteLine("Task-2 Started"); + this.output.WriteLine("Task-2 Started"); Assert.NotEqual(scheduler, TaskScheduler.Current); Task.Delay(1); Assert.NotEqual(scheduler, TaskScheduler.Current); pause2.WaitOne(); - output.WriteLine("Task-2 Done"); + this.output.WriteLine("Task-2 Done"); return 2; }); join = Task.WhenAll(task1, task2).ContinueWith(t => { - output.WriteLine("Join Started"); + this.output.WriteLine("Join Started"); if (t.IsFaulted) throw t.Exception; Assert.Equal(scheduler, TaskScheduler.Current); - output.WriteLine("Join Done"); + this.output.WriteLine("Join Done"); }); finish.SetResult(true); @@ -500,7 +501,7 @@ public async Task ActivationSched_Task_Run_Delay() [Fact, TestCategory("Functional"), TestCategory("Scheduler")] public async Task ActivationSched_Task_Delay() { - TaskScheduler scheduler = masterScheduler.GetWorkItemGroup(context).TaskRunner; + TaskScheduler scheduler = this.masterScheduler.GetWorkItemGroup(this.context).TaskRunner; Task wrapper = new Task(async () => { @@ -519,9 +520,9 @@ private async Task DoDelay(int i) { try { - output.WriteLine("Before Task.Delay #{0} TaskScheduler.Current={1}", i, TaskScheduler.Current); + this.output.WriteLine("Before Task.Delay #{0} TaskScheduler.Current={1}", i, TaskScheduler.Current); await Task.Delay(1); - output.WriteLine("After Task.Delay #{0} TaskScheduler.Current={1}", i, TaskScheduler.Current); + this.output.WriteLine("After Task.Delay #{0} TaskScheduler.Current={1}", i, TaskScheduler.Current); } catch (ObjectDisposedException) { @@ -532,7 +533,7 @@ private async Task DoDelay(int i) [Fact, TestCategory("Functional"), TestCategory("Scheduler")] public async Task ActivationSched_Turn_Execution_Order_Loop() { - TaskScheduler scheduler = masterScheduler.GetWorkItemGroup(context).TaskRunner; + TaskScheduler scheduler = this.masterScheduler.GetWorkItemGroup(this.context).TaskRunner; const int NumChains = 100; const int ChainLength = 3; @@ -578,7 +579,7 @@ public async Task ActivationSched_Turn_Execution_Order_Loop() task = task.ContinueWith(t => { if (t.IsFaulted) throw t.Exception; - output.WriteLine("Inside Chain {0} Task {1}", chainNum, taskNum); + this.output.WriteLine("Inside Chain {0} Task {1}", chainNum, taskNum); try { Assert.Equal(-1, executingGlobal); // "Detected unexpected other execution in chain " + chainNum + " Task " + taskNum @@ -601,7 +602,7 @@ public async Task ActivationSched_Turn_Execution_Order_Loop() taskChainEnds[chainNum] = task.ContinueWith(t => { if (t.IsFaulted) throw t.Exception; - output.WriteLine("Inside Chain {0} Final Task", chainNum); + this.output.WriteLine("Inside Chain {0} Final Task", chainNum); resultHandles[chainNum].SetResult(true); }, scheduler); } @@ -613,7 +614,7 @@ public async Task ActivationSched_Turn_Execution_Order_Loop() for (int i = 0; i < NumChains; i++) { - TimeSpan waitCheckTime = TimeSpan.FromMilliseconds(150 * ChainLength * NumChains * waitFactor); + TimeSpan waitCheckTime = TimeSpan.FromMilliseconds(150 * ChainLength * NumChains * WaitFactor); try { @@ -646,7 +647,7 @@ public async Task ActivationSched_Turn_Execution_Order_Loop() [Fact, TestCategory("Functional"), TestCategory("Scheduler")] public async Task ActivationSched_Test1() { - TaskScheduler scheduler = masterScheduler.GetWorkItemGroup(context).TaskRunner; + TaskScheduler scheduler = this.masterScheduler.GetWorkItemGroup(this.context).TaskRunner; await Run_ActivationSched_Test1(scheduler, false); } @@ -654,7 +655,7 @@ public async Task ActivationSched_Test1() [Fact, TestCategory("Functional"), TestCategory("Scheduler")] public async Task ActivationSched_Test1_Bounce() { - TaskScheduler scheduler = masterScheduler.GetWorkItemGroup(context).TaskRunner; + TaskScheduler scheduler = this.masterScheduler.GetWorkItemGroup(this.context).TaskRunner; await Run_ActivationSched_Test1(scheduler, true); } @@ -663,7 +664,7 @@ public async Task ActivationSched_Test1_Bounce() public async Task OrleansSched_Test1() { UnitTestSchedulingContext context = new UnitTestSchedulingContext(); - OrleansTaskScheduler orleansTaskScheduler = TestInternalHelper.InitializeSchedulerForTesting(context, this.performanceMetrics, loggerFactory); + OrleansTaskScheduler orleansTaskScheduler = TestInternalHelper.InitializeSchedulerForTesting(context, this.performanceMetrics, this.loggerFactory); ActivationTaskScheduler scheduler = orleansTaskScheduler.GetWorkItemGroup(context).TaskRunner; await Run_ActivationSched_Test1(scheduler, false); @@ -672,7 +673,7 @@ public async Task OrleansSched_Test1() public async Task OrleansSched_Test1_Bounce() { UnitTestSchedulingContext context = new UnitTestSchedulingContext(); - OrleansTaskScheduler orleansTaskScheduler = TestInternalHelper.InitializeSchedulerForTesting(context, this.performanceMetrics, loggerFactory); + OrleansTaskScheduler orleansTaskScheduler = TestInternalHelper.InitializeSchedulerForTesting(context, this.performanceMetrics, this.loggerFactory); ActivationTaskScheduler scheduler = orleansTaskScheduler.GetWorkItemGroup(context).TaskRunner; await Run_ActivationSched_Test1(scheduler, true); @@ -693,7 +694,7 @@ internal async Task Run_ActivationSched_Test1(TaskScheduler scheduler, bool boun var wrappedDone = new TaskCompletionSource(); Task wrapper = new Task(() => { - output.WriteLine("#0 - new Task - SynchronizationContext.Current={0} TaskScheduler.Current={1}", + this.output.WriteLine("#0 - new Task - SynchronizationContext.Current={0} TaskScheduler.Current={1}", SynchronizationContext.Current, TaskScheduler.Current); Task t1 = grain.Test1(); @@ -749,9 +750,9 @@ internal async Task Run_ActivationSched_Test1(TaskScheduler scheduler, bool boun private void LogContext(string what) { - lock (lockable) + lock (Lockable) { - output.WriteLine( + this.output.WriteLine( "{0}\n" + " TaskScheduler.Current={1}\n" + " Task.Factory.Scheduler={2}\n" diff --git a/test/NonSilo.Tests/SchedulerTests/OrleansTaskSchedulerBasicTests.cs b/test/NonSilo.Tests/SchedulerTests/OrleansTaskSchedulerBasicTests.cs index d340e50c18..4b180986a9 100644 --- a/test/NonSilo.Tests/SchedulerTests/OrleansTaskSchedulerBasicTests.cs +++ b/test/NonSilo.Tests/SchedulerTests/OrleansTaskSchedulerBasicTests.cs @@ -16,6 +16,8 @@ using Orleans; using Orleans.TestingHost.Utils; using Orleans.Statistics; +using Orleans.Hosting; +using Microsoft.Extensions.Options; // ReSharper disable ConvertToConstant.Local @@ -45,7 +47,7 @@ public bool Equals(ISchedulingContext other) public class OrleansTaskSchedulerBasicTests : IDisposable { private readonly ITestOutputHelper output; - private static readonly object lockable = new object(); + private static readonly object Lockable = new object(); private readonly SiloPerformanceMetrics performanceMetrics; private readonly UnitTestSchedulingContext rootContext; private readonly OrleansTaskScheduler scheduler; @@ -54,10 +56,10 @@ public OrleansTaskSchedulerBasicTests(ITestOutputHelper output) { this.output = output; SynchronizationContext.SetSynchronizationContext(null); - loggerFactory = InitSchedulerLogging(); - this.performanceMetrics = new SiloPerformanceMetrics(new NoOpHostEnvironmentStatistics(loggerFactory), new AppEnvironmentStatistics(), this.loggerFactory); + this.loggerFactory = InitSchedulerLogging(); + this.performanceMetrics = new SiloPerformanceMetrics(new NoOpHostEnvironmentStatistics(this.loggerFactory), new AppEnvironmentStatistics(), this.loggerFactory, Options.Create(new SiloStatisticsOptions())); this.rootContext = new UnitTestSchedulingContext(); - this.scheduler = TestInternalHelper.InitializeSchedulerForTesting(rootContext, this.performanceMetrics, loggerFactory); + this.scheduler = TestInternalHelper.InitializeSchedulerForTesting(this.rootContext, this.performanceMetrics, this.loggerFactory); } public void Dispose() @@ -73,7 +75,7 @@ public void Async_Task_Start_OrleansTaskScheduler() int expected = 2; bool done = false; Task t = new Task(() => { done = true; return expected; }); - t.Start(scheduler); + t.Start(this.scheduler); int received = t.Result; Assert.True(t.IsCompleted, "Task should have completed"); @@ -85,7 +87,7 @@ public void Async_Task_Start_OrleansTaskScheduler() [Fact, TestCategory("AsynchronyPrimitives")] public void Async_Task_Start_ActivationTaskScheduler() { - ActivationTaskScheduler activationScheduler = scheduler.GetWorkItemGroup(rootContext).TaskRunner; + ActivationTaskScheduler activationScheduler = this.scheduler.GetWorkItemGroup(this.rootContext).TaskRunner; int expected = 2; bool done = false; @@ -104,15 +106,15 @@ public void Sched_SimpleFifoTest() { // This is not a great test because there's a 50/50 shot that it will work even if the scheduling // is completely and thoroughly broken and both closures are executed "simultaneously" - ActivationTaskScheduler activationScheduler = scheduler.GetWorkItemGroup(rootContext).TaskRunner; + ActivationTaskScheduler activationScheduler = this.scheduler.GetWorkItemGroup(this.rootContext).TaskRunner; int n = 0; // ReSharper disable AccessToModifiedClosure IWorkItem item1 = new ClosureWorkItem(() => { n = n + 5; }); IWorkItem item2 = new ClosureWorkItem(() => { n = n * 3; }); // ReSharper restore AccessToModifiedClosure - scheduler.QueueWorkItem(item1, rootContext); - scheduler.QueueWorkItem(item2, rootContext); + this.scheduler.QueueWorkItem(item1, this.rootContext); + this.scheduler.QueueWorkItem(item2, this.rootContext); // Pause to let things run Thread.Sleep(1000); @@ -120,7 +122,7 @@ public void Sched_SimpleFifoTest() // N should be 15, because the two tasks should execute in order Assert.True(n != 0, "Work items did not get executed"); Assert.Equal(15, n); - output.WriteLine("Test executed OK."); + this.output.WriteLine("Test executed OK."); } [Fact] @@ -128,7 +130,7 @@ public async Task Sched_Task_TplFifoTest() { // This is not a great test because there's a 50/50 shot that it will work even if the scheduling // is completely and thoroughly broken and both closures are executed "simultaneously" - ActivationTaskScheduler activationScheduler = scheduler.GetWorkItemGroup(rootContext).TaskRunner; + ActivationTaskScheduler activationScheduler = this.scheduler.GetWorkItemGroup(this.rootContext).TaskRunner; int n = 0; @@ -152,11 +154,11 @@ public async Task Sched_Task_StartTask_1() { ManualResetEvent pause1 = new ManualResetEvent(false); ManualResetEvent pause2 = new ManualResetEvent(false); - Task task1 = new Task(() => { pause1.WaitOne(); output.WriteLine("Task-1"); }); - Task task2 = new Task(() => { pause2.WaitOne(); output.WriteLine("Task-2"); }); + Task task1 = new Task(() => { pause1.WaitOne(); this.output.WriteLine("Task-1"); }); + Task task2 = new Task(() => { pause2.WaitOne(); this.output.WriteLine("Task-2"); }); - task1.Start(scheduler); - task2.Start(scheduler); + task1.Start(this.scheduler); + task2.Start(this.scheduler); pause1.Set(); await task1.WithTimeout(TimeSpan.FromMilliseconds(100)); @@ -174,18 +176,18 @@ public async Task Sched_Task_StartTask_2() { ManualResetEvent pause1 = new ManualResetEvent(false); ManualResetEvent pause2 = new ManualResetEvent(false); - Task task1 = new Task(() => { pause1.WaitOne(); output.WriteLine("Task-1"); }); - Task task2 = new Task(() => { pause2.WaitOne(); output.WriteLine("Task-2"); }); + Task task1 = new Task(() => { pause1.WaitOne(); this.output.WriteLine("Task-1"); }); + Task task2 = new Task(() => { pause2.WaitOne(); this.output.WriteLine("Task-2"); }); pause1.Set(); - task1.Start(scheduler); + task1.Start(this.scheduler); await task1.WithTimeout(TimeSpan.FromMilliseconds(100)); Assert.True(task1.IsCompleted, "Task.IsCompleted-1"); Assert.False(task1.IsFaulted, "Task.IsFaulted-1"); - task2.Start(scheduler); + task2.Start(this.scheduler); pause2.Set(); await task2.WithTimeout(TimeSpan.FromMilliseconds(100)); @@ -198,28 +200,28 @@ public async Task Sched_Task_StartTask_Wrapped() { ManualResetEvent pause1 = new ManualResetEvent(false); ManualResetEvent pause2 = new ManualResetEvent(false); - Task task1 = new Task(() => { pause1.WaitOne(); output.WriteLine("Task-1"); }); - Task task2 = new Task(() => { pause2.WaitOne(); output.WriteLine("Task-2"); }); + Task task1 = new Task(() => { pause1.WaitOne(); this.output.WriteLine("Task-1"); }); + Task task2 = new Task(() => { pause2.WaitOne(); this.output.WriteLine("Task-2"); }); Task wrapper1 = new Task(() => { - task1.Start(scheduler); + task1.Start(this.scheduler); task1.WaitWithThrow(TimeSpan.FromSeconds(10)); }); Task wrapper2 = new Task(() => { - task2.Start(scheduler); + task2.Start(this.scheduler); task2.WaitWithThrow(TimeSpan.FromSeconds(10)); }); pause1.Set(); - wrapper1.Start(scheduler); + wrapper1.Start(this.scheduler); await wrapper1.WithTimeout(TimeSpan.FromSeconds(10)); Assert.True(task1.IsCompleted, "Task.IsCompleted-1"); Assert.False(task1.IsFaulted, "Task.IsFaulted-1"); - wrapper2.Start(scheduler); + wrapper2.Start(this.scheduler); pause2.Set(); await wrapper2.WithTimeout(TimeSpan.FromSeconds(10)); @@ -242,8 +244,8 @@ public void Sched_Task_StartTask_Wait_Wrapped() for (int i = 0; i < NumTasks; i++) { int taskNum = i; // Capture - tasks[i] = new Task(() => { output.WriteLine("Inside Task-" + taskNum); flags[taskNum].WaitOne(); }); - output.WriteLine("Created Task-" + taskNum + " Id=" + tasks[taskNum].Id); + tasks[i] = new Task(() => { this.output.WriteLine("Inside Task-" + taskNum); flags[taskNum].WaitOne(); }); + this.output.WriteLine("Created Task-" + taskNum + " Id=" + tasks[taskNum].Id); } Task[] wrappers = new Task[NumTasks]; @@ -252,18 +254,18 @@ public void Sched_Task_StartTask_Wait_Wrapped() int taskNum = i; // Capture wrappers[i] = new Task(() => { - output.WriteLine("Inside Wrapper-" + taskNum); - tasks[taskNum].Start(scheduler); + this.output.WriteLine("Inside Wrapper-" + taskNum); + tasks[taskNum].Start(this.scheduler); }); wrappers[i].ContinueWith(t => { Assert.False(t.IsFaulted, "Warpper.IsFaulted-" + taskNum + " " + t.Exception); Assert.True(t.IsCompleted, "Wrapper.IsCompleted-" + taskNum); }); - output.WriteLine("Created Wrapper-" + taskNum + " Task.Id=" + wrappers[taskNum].Id); + this.output.WriteLine("Created Wrapper-" + taskNum + " Task.Id=" + wrappers[taskNum].Id); } - foreach (var wrapper in wrappers) wrapper.Start(scheduler); + foreach (var wrapper in wrappers) wrapper.Start(this.scheduler); foreach (var flag in flags) flag.Set(); for (int i = 0; i < wrappers.Length; i++) { @@ -295,7 +297,7 @@ public void Sched_Task_ClosureWorkItem_Wait() for (int i = 0; i < NumTasks; i++) { int taskNum = i; // Capture - tasks[i] = new Task(() => { output.WriteLine("Inside Task-" + taskNum); flags[taskNum].WaitOne(); }); + tasks[i] = new Task(() => { this.output.WriteLine("Inside Task-" + taskNum); flags[taskNum].WaitOne(); }); } ClosureWorkItem[] workItems = new ClosureWorkItem[NumTasks]; @@ -304,14 +306,14 @@ public void Sched_Task_ClosureWorkItem_Wait() int taskNum = i; // Capture workItems[i] = new ClosureWorkItem(() => { - output.WriteLine("Inside ClosureWorkItem-" + taskNum); - tasks[taskNum].Start(scheduler); + this.output.WriteLine("Inside ClosureWorkItem-" + taskNum); + tasks[taskNum].Start(this.scheduler); bool ok = tasks[taskNum].Wait(TimeSpan.FromMilliseconds(NumTasks * 100)); Assert.True(ok, "Wait completed successfully inside ClosureWorkItem-" + taskNum); }); } - foreach (var workItem in workItems) scheduler.QueueWorkItem(workItem, rootContext); + foreach (var workItem in workItems) this.scheduler.QueueWorkItem(workItem, this.rootContext); foreach (var flag in flags) flag.Set(); for (int i = 0; i < tasks.Length; i++) { @@ -330,23 +332,23 @@ public void Sched_Task_ClosureWorkItem_Wait() [Fact] public async Task Sched_Task_TaskWorkItem_CurrentScheduler() { - ActivationTaskScheduler activationScheduler = scheduler.GetWorkItemGroup(rootContext).TaskRunner; + ActivationTaskScheduler activationScheduler = this.scheduler.GetWorkItemGroup(this.rootContext).TaskRunner; var result0 = new TaskCompletionSource(); var result1 = new TaskCompletionSource(); Task t1 = null; - scheduler.QueueWorkItem(new ClosureWorkItem(() => + this.scheduler.QueueWorkItem(new ClosureWorkItem(() => { try { - output.WriteLine("#0 - TaskWorkItem - SynchronizationContext.Current={0} TaskScheduler.Current={1}", + this.output.WriteLine("#0 - TaskWorkItem - SynchronizationContext.Current={0} TaskScheduler.Current={1}", SynchronizationContext.Current, TaskScheduler.Current); Assert.Equal(activationScheduler, TaskScheduler.Current); // t1 = new Task(() => { - output.WriteLine("#1 - new Task - SynchronizationContext.Current={0} TaskScheduler.Current={1}", + this.output.WriteLine("#1 - new Task - SynchronizationContext.Current={0} TaskScheduler.Current={1}", SynchronizationContext.Current, TaskScheduler.Current); Assert.Equal(activationScheduler, TaskScheduler.Current); // "TaskScheduler.Current #1" result1.SetResult(true); @@ -359,7 +361,7 @@ public async Task Sched_Task_TaskWorkItem_CurrentScheduler() { result0.SetException(exc); } - }), rootContext); + }), this.rootContext); await result0.Task.WithTimeout(TimeSpan.FromMinutes(1)); Assert.True(result0.Task.Exception == null, "Task-0 should not throw exception: " + result0.Task.Exception); @@ -378,28 +380,28 @@ public async Task Sched_Task_TaskWorkItem_CurrentScheduler() [Fact] public async Task Sched_Task_ClosureWorkItem_SpecificScheduler() { - ActivationTaskScheduler activationScheduler = scheduler.GetWorkItemGroup(rootContext).TaskRunner; + ActivationTaskScheduler activationScheduler = this.scheduler.GetWorkItemGroup(this.rootContext).TaskRunner; var result0 = new TaskCompletionSource(); var result1 = new TaskCompletionSource(); Task t1 = null; - scheduler.QueueWorkItem(new ClosureWorkItem(() => + this.scheduler.QueueWorkItem(new ClosureWorkItem(() => { try { - output.WriteLine("#0 - TaskWorkItem - SynchronizationContext.Current={0} TaskScheduler.Current={1}", + this.output.WriteLine("#0 - TaskWorkItem - SynchronizationContext.Current={0} TaskScheduler.Current={1}", SynchronizationContext.Current, TaskScheduler.Current); Assert.Equal(activationScheduler, TaskScheduler.Current); // "TaskScheduler.Current #0" t1 = new Task(() => { - output.WriteLine("#1 - new Task - SynchronizationContext.Current={0} TaskScheduler.Current={1}", + this.output.WriteLine("#1 - new Task - SynchronizationContext.Current={0} TaskScheduler.Current={1}", SynchronizationContext.Current, TaskScheduler.Current); - Assert.Equal(scheduler, TaskScheduler.Current); // "TaskScheduler.Current #1" + Assert.Equal(this.scheduler, TaskScheduler.Current); // "TaskScheduler.Current #1" result1.SetResult(true); }); - t1.Start(scheduler); + t1.Start(this.scheduler); result0.SetResult(true); } @@ -407,7 +409,7 @@ public async Task Sched_Task_ClosureWorkItem_SpecificScheduler() { result0.SetException(exc); } - }), rootContext); + }), this.rootContext); await result0.Task.WithTimeout(TimeSpan.FromMinutes(1)); Assert.True(result0.Task.Exception == null, "Task-0 should not throw exception: " + result0.Task.Exception); @@ -428,28 +430,28 @@ public void Sched_Task_NewTask_ContinueWith_Wrapped_OrleansTaskScheduler() { Task wrapped = new Task(() => { - output.WriteLine("#0 - new Task - SynchronizationContext.Current={0} TaskScheduler.Current={1}", + this.output.WriteLine("#0 - new Task - SynchronizationContext.Current={0} TaskScheduler.Current={1}", SynchronizationContext.Current, TaskScheduler.Current); Task t0 = new Task(() => { - output.WriteLine("#1 - new Task - SynchronizationContext.Current={0} TaskScheduler.Current={1}", + this.output.WriteLine("#1 - new Task - SynchronizationContext.Current={0} TaskScheduler.Current={1}", SynchronizationContext.Current, TaskScheduler.Current); - Assert.Equal(scheduler, TaskScheduler.Current); // "TaskScheduler.Current #1" + Assert.Equal(this.scheduler, TaskScheduler.Current); // "TaskScheduler.Current #1" }); Task t1 = t0.ContinueWith(task => { Assert.False(task.IsFaulted, "Task #1 Faulted=" + task.Exception); - output.WriteLine("#2 - new Task - SynchronizationContext.Current={0} TaskScheduler.Current={1}", + this.output.WriteLine("#2 - new Task - SynchronizationContext.Current={0} TaskScheduler.Current={1}", SynchronizationContext.Current, TaskScheduler.Current); - Assert.Equal(scheduler, TaskScheduler.Current); // "TaskScheduler.Current #2" + Assert.Equal(this.scheduler, TaskScheduler.Current); // "TaskScheduler.Current #2" }); - t0.Start(scheduler); + t0.Start(this.scheduler); bool ok = t1.Wait(TimeSpan.FromSeconds(15)); if (!ok) throw new TimeoutException(); }); - wrapped.Start(scheduler); + wrapped.Start(this.scheduler); bool finished = wrapped.Wait(TimeSpan.FromSeconds(30)); if (!finished) throw new TimeoutException(); } @@ -457,47 +459,47 @@ public void Sched_Task_NewTask_ContinueWith_Wrapped_OrleansTaskScheduler() [Fact] public void Sched_Task_NewTask_ContinueWith_TaskScheduler() { - output.WriteLine("#0 - new Task - SynchronizationContext.Current={0} TaskScheduler.Current={1}", + this.output.WriteLine("#0 - new Task - SynchronizationContext.Current={0} TaskScheduler.Current={1}", SynchronizationContext.Current, TaskScheduler.Current); Task t0 = new Task(() => { - output.WriteLine("#1 - new Task - SynchronizationContext.Current={0} TaskScheduler.Current={1}", + this.output.WriteLine("#1 - new Task - SynchronizationContext.Current={0} TaskScheduler.Current={1}", SynchronizationContext.Current, TaskScheduler.Current); - Assert.Equal(scheduler, TaskScheduler.Current); // "TaskScheduler.Current #1" + Assert.Equal(this.scheduler, TaskScheduler.Current); // "TaskScheduler.Current #1" }); Task t1 = t0.ContinueWith(task => { Assert.False(task.IsFaulted, "Task #1 Faulted=" + task.Exception); - output.WriteLine("#2 - new Task - SynchronizationContext.Current={0} TaskScheduler.Current={1}", + this.output.WriteLine("#2 - new Task - SynchronizationContext.Current={0} TaskScheduler.Current={1}", SynchronizationContext.Current, TaskScheduler.Current); - Assert.Equal(scheduler, TaskScheduler.Current); // "TaskScheduler.Current #2" - }, scheduler); - t0.Start(scheduler); + Assert.Equal(this.scheduler, TaskScheduler.Current); // "TaskScheduler.Current #2" + }, this.scheduler); + t0.Start(this.scheduler); t1.WaitWithThrow(TimeSpan.FromSeconds(30)); } [Fact] public void Sched_Task_StartNew_ContinueWith_TaskScheduler() { - output.WriteLine("#0 - StartNew - SynchronizationContext.Current={0} TaskScheduler.Current={1}", + this.output.WriteLine("#0 - StartNew - SynchronizationContext.Current={0} TaskScheduler.Current={1}", SynchronizationContext.Current, TaskScheduler.Current); Task t0 = Task.Factory.StartNew(state => { - output.WriteLine("#1 - StartNew - SynchronizationContext.Current={0} TaskScheduler.Current={1}", + this.output.WriteLine("#1 - StartNew - SynchronizationContext.Current={0} TaskScheduler.Current={1}", SynchronizationContext.Current, TaskScheduler.Current); - Assert.Equal(scheduler, TaskScheduler.Current); // "TaskScheduler.Current #1" - }, null, CancellationToken.None, TaskCreationOptions.None, scheduler); + Assert.Equal(this.scheduler, TaskScheduler.Current); // "TaskScheduler.Current #1" + }, null, CancellationToken.None, TaskCreationOptions.None, this.scheduler); Task t1 = t0.ContinueWith(task => { Assert.False(task.IsFaulted, "Task #1 Faulted=" + task.Exception); - output.WriteLine("#2 - StartNew - SynchronizationContext.Current={0} TaskScheduler.Current={1}", + this.output.WriteLine("#2 - StartNew - SynchronizationContext.Current={0} TaskScheduler.Current={1}", SynchronizationContext.Current, TaskScheduler.Current); - Assert.Equal(scheduler, TaskScheduler.Current); // "TaskScheduler.Current #2" - }, scheduler); + Assert.Equal(this.scheduler, TaskScheduler.Current); // "TaskScheduler.Current #2" + }, this.scheduler); t1.WaitWithThrow(TimeSpan.FromSeconds(30)); } @@ -505,7 +507,7 @@ public void Sched_Task_StartNew_ContinueWith_TaskScheduler() public void Sched_Task_SubTaskExecutionSequencing() { UnitTestSchedulingContext context = new UnitTestSchedulingContext(); - scheduler.RegisterWorkContext(context); + this.scheduler.RegisterWorkContext(context); LogContext("Main-task " + Task.CurrentId); @@ -526,9 +528,9 @@ public void Sched_Task_SubTaskExecutionSequencing() LogContext("Sub-task " + id + " n=" + n); int k = n; - output.WriteLine("Sub-task " + id + " sleeping"); + this.output.WriteLine("Sub-task " + id + " sleeping"); Thread.Sleep(100); - output.WriteLine("Sub-task " + id + " awake"); + this.output.WriteLine("Sub-task " + id + " awake"); n = k + 1; // ReSharper restore AccessToModifiedClosure }; @@ -536,24 +538,24 @@ public void Sched_Task_SubTaskExecutionSequencing() { LogContext("Sub-task " + id + "-ContinueWith"); - output.WriteLine("Sub-task " + id + " Done"); + this.output.WriteLine("Sub-task " + id + " Done"); }); } }; IWorkItem workItem = new ClosureWorkItem(closure); - scheduler.QueueWorkItem(workItem, context); + this.scheduler.QueueWorkItem(workItem, context); // Pause to let things run - output.WriteLine("Main-task sleeping"); + this.output.WriteLine("Main-task sleeping"); Thread.Sleep(TimeSpan.FromSeconds(2)); - output.WriteLine("Main-task awake"); + this.output.WriteLine("Main-task awake"); // N should be 10, because all tasks should execute serially Assert.True(n != 0, "Work items did not get executed"); Assert.Equal(10, n); // "Work items executed concurrently" - scheduler.Stop(); + this.scheduler.Stop(); } // blocked on upgrate RequestContext to corelre compaible [Fact] @@ -563,21 +565,21 @@ public void Sched_Task_RequestContext_NewTask_ContinueWith() int val = TestConstants.random.Next(); RequestContext.Set(key, val); - output.WriteLine("Initial - SynchronizationContext.Current={0} TaskScheduler.Current={1} Thread={2}", + this.output.WriteLine("Initial - SynchronizationContext.Current={0} TaskScheduler.Current={1} Thread={2}", SynchronizationContext.Current, TaskScheduler.Current, Thread.CurrentThread.ManagedThreadId); Assert.Equal(val, RequestContext.Get(key)); // "RequestContext.Get Initial" Task t0 = new Task(() => { - output.WriteLine("#0 - new Task - SynchronizationContext.Current={0} TaskScheduler.Current={1} Thread={2}", + this.output.WriteLine("#0 - new Task - SynchronizationContext.Current={0} TaskScheduler.Current={1} Thread={2}", SynchronizationContext.Current, TaskScheduler.Current, Thread.CurrentThread.ManagedThreadId); Assert.Equal(val, RequestContext.Get(key)); // "RequestContext.Get #0" Task t1 = new Task(() => { - output.WriteLine("#1 - new Task - SynchronizationContext.Current={0} TaskScheduler.Current={1} Thread={2}", + this.output.WriteLine("#1 - new Task - SynchronizationContext.Current={0} TaskScheduler.Current={1} Thread={2}", SynchronizationContext.Current, TaskScheduler.Current, Thread.CurrentThread.ManagedThreadId); Assert.Equal(val, RequestContext.Get(key)); // "RequestContext.Get #1" }); @@ -585,14 +587,14 @@ public void Sched_Task_RequestContext_NewTask_ContinueWith() { Assert.False(task.IsFaulted, "Task #1 FAULTED=" + task.Exception); - output.WriteLine("#2 - new Task - SynchronizationContext.Current={0} TaskScheduler.Current={1} Thread={2}", + this.output.WriteLine("#2 - new Task - SynchronizationContext.Current={0} TaskScheduler.Current={1} Thread={2}", SynchronizationContext.Current, TaskScheduler.Current, Thread.CurrentThread.ManagedThreadId); Assert.Equal(val, RequestContext.Get(key)); // "RequestContext.Get #2" }); - t1.Start(scheduler); + t1.Start(this.scheduler); t2.WaitWithThrow(TimeSpan.FromSeconds(5)); }); - t0.Start(scheduler); + t0.Start(this.scheduler); t0.WaitWithThrow(TimeSpan.FromSeconds(10)); Assert.False(t0.IsFaulted, "Task #0 FAULTED=" + t0.Exception); } @@ -604,27 +606,27 @@ public void Sched_AC_RequestContext_StartNew_ContinueWith() int val = TestConstants.random.Next(); RequestContext.Set(key, val); - output.WriteLine("Initial - SynchronizationContext.Current={0} TaskScheduler.Current={1}", + this.output.WriteLine("Initial - SynchronizationContext.Current={0} TaskScheduler.Current={1}", SynchronizationContext.Current, TaskScheduler.Current); Assert.Equal(val, RequestContext.Get(key)); // "RequestContext.Get Initial" Task t0 = Task.Factory.StartNew(() => { - output.WriteLine("#0 - new Task - SynchronizationContext.Current={0} TaskScheduler.Current={1}", + this.output.WriteLine("#0 - new Task - SynchronizationContext.Current={0} TaskScheduler.Current={1}", SynchronizationContext.Current, TaskScheduler.Current); Assert.Equal(val, RequestContext.Get(key)); // "RequestContext.Get #0" Task t1 = Task.Factory.StartNew(() => { - output.WriteLine("#1 - new Task - SynchronizationContext.Current={0} TaskScheduler.Current={1}", + this.output.WriteLine("#1 - new Task - SynchronizationContext.Current={0} TaskScheduler.Current={1}", SynchronizationContext.Current, TaskScheduler.Current); Assert.Equal(val, RequestContext.Get(key)); // "RequestContext.Get #1" }); Task t2 = t1.ContinueWith((_) => { - output.WriteLine("#2 - new Task - SynchronizationContext.Current={0} TaskScheduler.Current={1}", + this.output.WriteLine("#2 - new Task - SynchronizationContext.Current={0} TaskScheduler.Current={1}", SynchronizationContext.Current, TaskScheduler.Current); Assert.Equal(val, RequestContext.Get(key)); // "RequestContext.Get #2" }); @@ -684,9 +686,9 @@ private Task NonAsyncCheckClearRequestContext(string key) private void LogContext(string what) { - lock (lockable) + lock (Lockable) { - output.WriteLine( + this.output.WriteLine( "{0}\n" + " TaskScheduler.Current={1}\n" + " Task.Factory.Scheduler={2}\n" diff --git a/test/Orleans.Transactions.Azure.Test/GoldenPathTransactionManagerTest.cs b/test/Orleans.Transactions.Azure.Test/GoldenPathTransactionManagerTest.cs index 118c927e58..306b11dac1 100644 --- a/test/Orleans.Transactions.Azure.Test/GoldenPathTransactionManagerTest.cs +++ b/test/Orleans.Transactions.Azure.Test/GoldenPathTransactionManagerTest.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Threading.Tasks; using Xunit.Abstractions; using Microsoft.Extensions.Logging.Abstractions; @@ -8,6 +8,7 @@ using Orleans.Transactions.Tests; using TestExtensions; using Orleans.TestingHost.Utils; +using Orleans.Hosting; namespace Orleans.Transactions.AzureStorage.Tests { @@ -25,7 +26,7 @@ public GoldenPathTransactionManagerTest(ITestOutputHelper output) private static ITransactionManager MakeTransactionManager() { TestFixture.CheckForAzureStorage(TestDefaultConfiguration.DataConnectionString); - ITransactionManager tm = new TransactionManager(new TransactionLog(StorageFactory), Options.Create(new TransactionsOptions()), NullLoggerFactory.Instance, NullTelemetryProducer.Instance, () => new NodeConfiguration(), LogMaintenanceInterval); + ITransactionManager tm = new TransactionManager(new TransactionLog(StorageFactory), Options.Create(new TransactionsOptions()), NullLoggerFactory.Instance, NullTelemetryProducer.Instance, Options.Create(new SiloStatisticsOptions()), LogMaintenanceInterval); tm.StartAsync().GetAwaiter().GetResult(); return tm; } diff --git a/test/Orleans.Transactions.Tests/Memory/GoldenPathTransactionManagerMemoryTests.cs b/test/Orleans.Transactions.Tests/Memory/GoldenPathTransactionManagerMemoryTests.cs index 60801de4d2..3fc8910485 100644 --- a/test/Orleans.Transactions.Tests/Memory/GoldenPathTransactionManagerMemoryTests.cs +++ b/test/Orleans.Transactions.Tests/Memory/GoldenPathTransactionManagerMemoryTests.cs @@ -1,4 +1,4 @@ - + using System; using System.Threading.Tasks; using Xunit.Abstractions; @@ -6,8 +6,8 @@ using Microsoft.Extensions.Logging.Abstractions; using Orleans.Transactions.Abstractions; using Orleans.Transactions.Development; -using Orleans.Runtime.Configuration; using Orleans.TestingHost.Utils; +using Orleans.Hosting; namespace Orleans.Transactions.Tests { @@ -25,7 +25,7 @@ public GoldenPathTransactionManagerMemoryTests(ITestOutputHelper output) private static ITransactionManager MakeTransactionManager() { Factory> storageFactory = () => Task.FromResult(new InMemoryTransactionLogStorage()); - ITransactionManager tm = new TransactionManager(new TransactionLog(storageFactory), Options.Create(new TransactionsOptions()), NullLoggerFactory.Instance, NullTelemetryProducer.Instance, ()=>new NodeConfiguration(), LogMaintenanceInterval); + ITransactionManager tm = new TransactionManager(new TransactionLog(storageFactory), Options.Create(new TransactionsOptions()), NullLoggerFactory.Instance, NullTelemetryProducer.Instance, Options.Create(new SiloStatisticsOptions()), LogMaintenanceInterval); tm.StartAsync().GetAwaiter().GetResult(); return tm; } diff --git a/test/Orleans.Transactions.Tests/Orleans.Transactions.Tests.csproj b/test/Orleans.Transactions.Tests/Orleans.Transactions.Tests.csproj index 7fec1ff4f9..75049f797a 100644 --- a/test/Orleans.Transactions.Tests/Orleans.Transactions.Tests.csproj +++ b/test/Orleans.Transactions.Tests/Orleans.Transactions.Tests.csproj @@ -14,6 +14,8 @@ + + diff --git a/test/ServiceBus.Tests/EvictionStrategyTests/EHPurgeLogicTests.cs b/test/ServiceBus.Tests/EvictionStrategyTests/EHPurgeLogicTests.cs index 4dc07eb6a4..ba93032274 100644 --- a/test/ServiceBus.Tests/EvictionStrategyTests/EHPurgeLogicTests.cs +++ b/test/ServiceBus.Tests/EvictionStrategyTests/EHPurgeLogicTests.cs @@ -1,4 +1,4 @@ -using Orleans; +using Orleans; using Orleans.Providers.Streams.Common; using Orleans.Runtime; using Orleans.Runtime.Configuration; @@ -18,6 +18,7 @@ using TestExtensions; using Xunit; using Orleans.ServiceBus.Providers.Testing; +using Orleans.Hosting; namespace ServiceBus.Tests.EvictionStrategyTests { @@ -39,9 +40,11 @@ public class EHPurgeLogicTests public EHPurgeLogicTests() { //an mock eh settings - this.ehSettings = new EventHubPartitionSettings(); - ehSettings.Hub = new EventHubSettings(); - ehSettings.Partition = "MockPartition"; + this.ehSettings = new EventHubPartitionSettings + { + Hub = new EventHubSettings(), + Partition = "MockPartition" + }; //set up cache pressure monitor and purge predicate this.cachePressureInjectionMonitor = new CachePressureInjectionMonitor(); @@ -198,16 +201,16 @@ private void InitForTesting() { this.cacheList = new ConcurrentBag(); this.evictionStrategyList = new List(); - var monitorDimensions = new EventHubReceiverMonitorDimensions(); - monitorDimensions.EventHubPartition = ehSettings.Partition; - monitorDimensions.EventHubPath = ehSettings.Hub.Path; - monitorDimensions.GlobalConfig = null; - monitorDimensions.NodeConfig = null; - - this.receiver1 = new EventHubAdapterReceiver(ehSettings, this.CacheFactory, this.CheckPointerFactory, NullLoggerFactory.Instance, - new DefaultEventHubReceiverMonitor(monitorDimensions, this.telemetryProducer), this.GetNodeConfiguration, this.telemetryProducer); - this.receiver2 = new EventHubAdapterReceiver(ehSettings, this.CacheFactory, this.CheckPointerFactory, NullLoggerFactory.Instance, - new DefaultEventHubReceiverMonitor(monitorDimensions, this.telemetryProducer), this.GetNodeConfiguration, this.telemetryProducer); + var monitorDimensions = new EventHubReceiverMonitorDimensions + { + EventHubPartition = this.ehSettings.Partition, + EventHubPath = this.ehSettings.Hub.Path, + }; + + this.receiver1 = new EventHubAdapterReceiver(this.ehSettings, this.CacheFactory, this.CheckPointerFactory, NullLoggerFactory.Instance, + new DefaultEventHubReceiverMonitor(monitorDimensions, this.telemetryProducer), new SiloStatisticsOptions(), this.telemetryProducer); + this.receiver2 = new EventHubAdapterReceiver(this.ehSettings, this.CacheFactory, this.CheckPointerFactory, NullLoggerFactory.Instance, + new DefaultEventHubReceiverMonitor(monitorDimensions, this.telemetryProducer), new SiloStatisticsOptions(), this.telemetryProducer); this.receiver1.Initialize(this.timeOut); this.receiver2.Initialize(this.timeOut); } diff --git a/test/ServiceBus.Tests/PluggableQueueBalancerTests.cs b/test/ServiceBus.Tests/PluggableQueueBalancerTests.cs index 48f062df17..eff77cd290 100644 --- a/test/ServiceBus.Tests/PluggableQueueBalancerTests.cs +++ b/test/ServiceBus.Tests/PluggableQueueBalancerTests.cs @@ -20,8 +20,8 @@ namespace ServiceBus.Tests public class PluggableQueueBalancerTestsWithEHStreamProvider : PluggableQueueBalancerTestBase, IClassFixture { private const string StreamProviderName = "EventHubStreamProvider"; - private static readonly int totalQueueCount = 6; - private static readonly short siloCount = 2; + private static readonly int TotalQueueCount = 6; + private static readonly short SiloCount = 2; public static readonly EventHubGeneratorStreamProviderSettings ProviderSettings = new EventHubGeneratorStreamProviderSettings(StreamProviderName); @@ -31,8 +31,8 @@ public class Fixture : BaseTestClusterFixture { protected override void ConfigureTestCluster(TestClusterBuilder builder) { - builder.Options.InitialSilosCount = siloCount; - ProviderSettings.EventHubPartitionCount = totalQueueCount; + builder.Options.InitialSilosCount = SiloCount; + ProviderSettings.EventHubPartitionCount = TotalQueueCount; builder.AddSiloBuilderConfigurator(); builder.ConfigureLegacyConfiguration(legacy => { @@ -62,7 +62,7 @@ public PluggableQueueBalancerTestsWithEHStreamProvider(Fixture fixture) [Fact, TestCategory("BVT")] public Task PluggableQueueBalancerTest_ShouldUseInjectedQueueBalancerAndBalanceCorrectly() { - return base.ShouldUseInjectedQueueBalancerAndBalanceCorrectly(this.fixture, StreamProviderName, siloCount, totalQueueCount); + return base.ShouldUseInjectedQueueBalancerAndBalanceCorrectly(this.fixture, StreamProviderName, SiloCount, TotalQueueCount); } } } diff --git a/test/ServiceBus.Tests/StatisticMonitorTests/EHStatisticMonitorTests.cs b/test/ServiceBus.Tests/StatisticMonitorTests/EHStatisticMonitorTests.cs index a1d726ef16..18aae2d667 100644 --- a/test/ServiceBus.Tests/StatisticMonitorTests/EHStatisticMonitorTests.cs +++ b/test/ServiceBus.Tests/StatisticMonitorTests/EHStatisticMonitorTests.cs @@ -1,22 +1,16 @@ using System; using System.Collections.Generic; using System.Threading.Tasks; -using Microsoft.WindowsAzure.Storage.Table; -using Orleans.AzureUtils; using Orleans.Runtime; using Orleans.Runtime.Configuration; -using Orleans.ServiceBus.Providers; using Orleans.ServiceBus.Providers.Testing; using Orleans.Storage; using Orleans.Streams; using Orleans.TestingHost; using ServiceBus.Tests.TestStreamProviders; using TestExtensions; -using UnitTests.GrainInterfaces; using UnitTests.Grains.ProgrammaticSubscribe; using Xunit; -using Orleans.TestingHost.Utils; -using UnitTests.Grains; using ServiceBus.Tests.SlowConsumingTests; namespace ServiceBus.Tests.MonitorTests @@ -124,7 +118,7 @@ private void AssertCacheMonitorCallCounters(CacheMonitorCounters totalCacheMonit private void AssertReceiverMonitorCallCounters(EventHubReceiverMonitorCounters totalReceiverMonitorCallCounters) { - Assert.Equal(totalReceiverMonitorCallCounters.TrackInitializationCallCounter, ehPartitionCountPerSilo); + Assert.Equal(ehPartitionCountPerSilo, totalReceiverMonitorCallCounters.TrackInitializationCallCounter); Assert.True(totalReceiverMonitorCallCounters.TrackMessagesReceivedCallCounter > 0); Assert.True(totalReceiverMonitorCallCounters.TrackReadCallCounter > 0); Assert.Equal(0, totalReceiverMonitorCallCounters.TrackShutdownCallCounter); diff --git a/test/ServiceBus.Tests/StatisticMonitorTests/EventHubReceiverMonitorForTesting.cs b/test/ServiceBus.Tests/StatisticMonitorTests/EventHubReceiverMonitorForTesting.cs index 717c6f5545..5d6c4f1e0b 100644 --- a/test/ServiceBus.Tests/StatisticMonitorTests/EventHubReceiverMonitorForTesting.cs +++ b/test/ServiceBus.Tests/StatisticMonitorTests/EventHubReceiverMonitorForTesting.cs @@ -1,15 +1,6 @@ -using Orleans; using Orleans.Providers.Streams.Common; -using Orleans.Runtime; -using Orleans.ServiceBus.Providers; using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; using System.Threading; -using System.Threading.Tasks; -using UnitTests.GrainInterfaces; -using UnitTests.Grains; namespace ServiceBus.Tests.MonitorTests { @@ -23,12 +14,12 @@ private EventHubReceiverMonitorForTesting() } public void TrackInitialization(bool success, TimeSpan callTime, Exception exception) { - Interlocked.Increment(ref this.CallCounters.TrackInitializationCallCounter); + if(success) Interlocked.Increment(ref this.CallCounters.TrackInitializationCallCounter); } public void TrackRead(bool success, TimeSpan callTime, Exception exception) { - Interlocked.Increment(ref this.CallCounters.TrackReadCallCounter); + if (success) Interlocked.Increment(ref this.CallCounters.TrackReadCallCounter); } public void TrackMessagesReceived(long count, DateTime? oldestEnqueueTime, DateTime? newestEnqueueTime) diff --git a/test/ServiceBus.Tests/TestStreamProviders/EHStreamProviderForMonitorTests.cs b/test/ServiceBus.Tests/TestStreamProviders/EHStreamProviderForMonitorTests.cs index dc5c2f65c7..7446bc80fa 100644 --- a/test/ServiceBus.Tests/TestStreamProviders/EHStreamProviderForMonitorTests.cs +++ b/test/ServiceBus.Tests/TestStreamProviders/EHStreamProviderForMonitorTests.cs @@ -1,4 +1,4 @@ -using Orleans.Providers; +using Orleans.Providers; using Orleans.Providers.Streams.Common; using Orleans.Runtime; using Orleans.ServiceBus.Providers; @@ -35,19 +35,17 @@ public override void Init(IProviderConfiguration providerCfg, string providerNam private void ChangeCachePressure() { - cachePressureInjectionMonitor.isUnderPressure = !cachePressureInjectionMonitor.isUnderPressure; + this.cachePressureInjectionMonitor.UnderPressure = !this.cachePressureInjectionMonitor.UnderPressure; } protected override IEventHubQueueCacheFactory CreateCacheFactory(EventHubStreamProviderSettings providerSettings) { - var globalConfig = this.serviceProvider.GetRequiredService(); - var nodeConfig = this.serviceProvider.GetRequiredService(); - var loggerFactory = serviceProvider.GetRequiredService(); - var eventHubPath = hubSettings.Path; - var sharedDimensions = new EventHubMonitorAggregationDimensions(globalConfig, nodeConfig, eventHubPath); + var loggerFactory = this.serviceProvider.GetRequiredService(); + var eventHubPath = this.hubSettings.Path; + var sharedDimensions = new EventHubMonitorAggregationDimensions(eventHubPath); Func cacheMonitorFactory = (dimensions, logger, telemetryProducer) => CacheMonitorForTesting.Instance; Func blockPoolMonitorFactory = (dimensions, logger, telemetryProducer) =>BlockPoolMonitorForTesting.Instance; - return new CacheFactoryForMonitorTesting(this.cachePressureInjectionMonitor, providerSettings, SerializationManager, + return new CacheFactoryForMonitorTesting(this.cachePressureInjectionMonitor, providerSettings, this.SerializationManager, sharedDimensions, loggerFactory, cacheMonitorFactory, blockPoolMonitorFactory); } @@ -105,13 +103,13 @@ public override Task ExecuteCommand(int command, object arg) public class CachePressureInjectionMonitor : ICachePressureMonitor { - public bool isUnderPressure { get; set; } + public bool UnderPressure { get; set; } private bool wasUnderPressur; public ICacheMonitor CacheMonitor { set; private get; } public CachePressureInjectionMonitor() { - this.isUnderPressure = false; - this.wasUnderPressur = this.isUnderPressure; + this.UnderPressure = false; + this.wasUnderPressur = this.UnderPressure; } public void RecordCachePressureContribution(double cachePressureContribution) @@ -121,12 +119,12 @@ public void RecordCachePressureContribution(double cachePressureContribution) public bool IsUnderPressure(DateTime utcNow) { - if (this.wasUnderPressur != this.isUnderPressure) + if (this.wasUnderPressur != this.UnderPressure) { - this.CacheMonitor?.TrackCachePressureMonitorStatusChange(this.GetType().Name, this.isUnderPressure, null, null, null); - this.wasUnderPressur = this.isUnderPressure; + this.CacheMonitor?.TrackCachePressureMonitorStatusChange(this.GetType().Name, this.UnderPressure, null, null, null); + this.wasUnderPressur = this.UnderPressure; } - return this.isUnderPressure; + return this.UnderPressure; } } } diff --git a/test/ServiceBus.Tests/TestStreamProviders/EHStreamProviderWithCreatedCacheList.cs b/test/ServiceBus.Tests/TestStreamProviders/EHStreamProviderWithCreatedCacheList.cs index 4dece40d0b..5ec79b272d 100644 --- a/test/ServiceBus.Tests/TestStreamProviders/EHStreamProviderWithCreatedCacheList.cs +++ b/test/ServiceBus.Tests/TestStreamProviders/EHStreamProviderWithCreatedCacheList.cs @@ -1,4 +1,4 @@ -using System; +using System; using Orleans.Providers; using Orleans.Providers.Streams.Common; using Orleans.Runtime; @@ -25,16 +25,14 @@ public class AdapterFactory : EventDataGeneratorStreamProvider.AdapterFactory public AdapterFactory() { - createdCaches = new ConcurrentBag(); + this.createdCaches = new ConcurrentBag(); } protected override IEventHubQueueCacheFactory CreateCacheFactory(EventHubStreamProviderSettings providerSettings) { - var globalConfig = this.serviceProvider.GetRequiredService(); - var nodeConfig = this.serviceProvider.GetRequiredService(); - var eventHubPath = hubSettings.Path; - var sharedDimensions = new EventHubMonitorAggregationDimensions(globalConfig, nodeConfig, eventHubPath); - return new CacheFactoryForTesting(providerSettings, SerializationManager, this.createdCaches, sharedDimensions, serviceProvider.GetRequiredService()); + var eventHubPath = this.hubSettings.Path; + var sharedDimensions = new EventHubMonitorAggregationDimensions(eventHubPath); + return new CacheFactoryForTesting(providerSettings, this.SerializationManager, this.createdCaches, sharedDimensions, this.serviceProvider.GetRequiredService()); } private class CacheFactoryForTesting : EventHubQueueCacheFactory @@ -51,7 +49,7 @@ private class CacheFactoryForTesting : EventHubQueueCacheFactory this.caches = caches; } - private const int defaultMaxAddCount = 10; + private const int DefaultMaxAddCount = 10; protected override IEventHubQueueCache CreateCache(string partition, EventHubStreamProviderSettings providerSettings, IStreamQueueCheckpointer checkpointer, ILoggerFactory loggerFactory, IObjectPool bufferPool, string blockPoolId, TimePurgePredicate timePurge, SerializationManager serializationManager, EventHubMonitorAggregationDimensions sharedDimensions, ITelemetryProducer telemetryProducer) @@ -60,7 +58,7 @@ private class CacheFactoryForTesting : EventHubQueueCacheFactory var cacheMonitor = this.CacheMonitorFactory(cacheMonitorDimensions, loggerFactory, telemetryProducer); var cacheLogger = loggerFactory.CreateLogger($"{typeof(EventHubQueueCache).FullName}.{providerSettings.StreamProviderName}.{partition}"); //set defaultMaxAddCount to 10 so TryCalculateCachePressureContribution will start to calculate real contribution shortly - var cache = new QueueCacheForTesting(defaultMaxAddCount, checkpointer, new EventHubDataAdapter(serializationManager, bufferPool), + var cache = new QueueCacheForTesting(DefaultMaxAddCount, checkpointer, new EventHubDataAdapter(serializationManager, bufferPool), EventHubDataComparer.Instance, cacheLogger, new EventHubCacheEvictionStrategy(cacheLogger, timePurge, cacheMonitor, providerSettings.StatisticMonitorWriteInterval), cacheMonitor, providerSettings.StatisticMonitorWriteInterval); this.caches.Add(cache); @@ -101,7 +99,7 @@ public override Task ExecuteCommand(int command, object arg) switch (command) { case IsCacheBackPressureTriggeredCommand: - return Task.FromResult(createdCaches.Any(cache => cache.IsUnderPressure)); + return Task.FromResult(this.createdCaches.Any(cache => cache.IsUnderPressure)); default: return base.ExecuteCommand(command, arg); } } diff --git a/test/TestGrainInterfaces/CustomPlacement.cs b/test/TestGrainInterfaces/CustomPlacement.cs index 7347c2df84..870c36a720 100644 --- a/test/TestGrainInterfaces/CustomPlacement.cs +++ b/test/TestGrainInterfaces/CustomPlacement.cs @@ -39,16 +39,6 @@ internal TestCustomPlacementStrategy(CustomPlacementScenario scenario) { Scenario = scenario; } - - public override bool Equals(object obj) - { - return obj is TestCustomPlacementStrategy && Scenario == ((TestCustomPlacementStrategy)obj).Scenario; - } - - public override int GetHashCode() - { - return GetType().GetHashCode() ^ Scenario.GetHashCode(); - } } [AttributeUsage(AttributeTargets.Class, AllowMultiple = false)] diff --git a/test/TestGrainInterfaces/VersionAwarePlacementDirector.cs b/test/TestGrainInterfaces/VersionAwarePlacementDirector.cs index 97b3b19897..d2ca526b47 100644 --- a/test/TestGrainInterfaces/VersionAwarePlacementDirector.cs +++ b/test/TestGrainInterfaces/VersionAwarePlacementDirector.cs @@ -1,8 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +using System; using Orleans.Placement; using Orleans.Runtime; @@ -21,18 +17,5 @@ public VersionAwareStrategyAttribute() public class VersionAwarePlacementStrategy : PlacementStrategy { internal static VersionAwarePlacementStrategy Singleton { get; } = new VersionAwarePlacementStrategy(); - - private VersionAwarePlacementStrategy() - { } - - public override bool Equals(object obj) - { - return obj is VersionAwarePlacementStrategy; - } - - public override int GetHashCode() - { - return GetType().GetHashCode(); - } } } diff --git a/test/TestGrains/TestPlacementStrategyFixedSiloDirector.cs b/test/TestGrains/TestPlacementStrategyFixedSiloDirector.cs index d91cab8d90..51f793f80d 100644 --- a/test/TestGrains/TestPlacementStrategyFixedSiloDirector.cs +++ b/test/TestGrains/TestPlacementStrategyFixedSiloDirector.cs @@ -6,7 +6,7 @@ namespace UnitTests.GrainInterfaces { - public class TestPlacementStrategyFixedSiloDirector : IPlacementDirector + public class TestPlacementStrategyFixedSiloDirector : IPlacementDirector { public const string TARGET_SILO_INDEX = "TARGET_SILO_INDEX"; @@ -30,7 +30,6 @@ public Task OnAddActivation(PlacementStrategy strategy, PlacementTa default: throw new InvalidOperationException(); // should never get here, only to make compiler happy } - } } } diff --git a/test/TestGrains/VersionAwarePlacementDirector.cs b/test/TestGrains/VersionAwarePlacementDirector.cs index e26fa76c7d..e62a0bc102 100644 --- a/test/TestGrains/VersionAwarePlacementDirector.cs +++ b/test/TestGrains/VersionAwarePlacementDirector.cs @@ -1,15 +1,12 @@ -using Orleans.Runtime; +using Orleans.Runtime; using Orleans.Runtime.Placement; using System; using System.Collections.Generic; -using System.Linq; -using System.Text; using System.Threading.Tasks; -using UnitTests.GrainInterfaces; namespace UnitTests.Grains { - public class VersionAwarePlacementDirector : IPlacementDirector + public class VersionAwarePlacementDirector : IPlacementDirector { private readonly Random random = new Random(); diff --git a/test/TestInternalGrains/PlacementTestGrain.cs b/test/TestInternalGrains/PlacementTestGrain.cs index d254da8982..337426c270 100644 --- a/test/TestInternalGrains/PlacementTestGrain.cs +++ b/test/TestInternalGrains/PlacementTestGrain.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using System.Net; @@ -151,8 +151,8 @@ internal class DefaultPlacementGrain : Grain, IDefaultPlacementGrain { public Task GetDefaultPlacement() { - var defaultStrategy = this.ServiceProvider.GetRequiredService(); - return Task.FromResult(defaultStrategy.PlacementStrategy); + var defaultStrategy = this.ServiceProvider.GetRequiredService(); + return Task.FromResult(defaultStrategy); } } diff --git a/test/TestInternalGrains/ReminderTestGrain2.cs b/test/TestInternalGrains/ReminderTestGrain2.cs index d0aad6a28f..fda31a2316 100644 --- a/test/TestInternalGrains/ReminderTestGrain2.cs +++ b/test/TestInternalGrains/ReminderTestGrain2.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Globalization; using System.IO; @@ -25,7 +25,7 @@ public class ReminderTestGrain2 : Grain, IReminderTestGrain2, IRemindable Dictionary sequence; private TimeSpan period; - private static long ACCURACY = 50 * TimeSpan.TicksPerMillisecond; // when we use ticks to compute sequence numbers, we might get wrong results as timeouts don't happen with precision of ticks ... we keep this as a leeway + private static long aCCURACY = 50 * TimeSpan.TicksPerMillisecond; // when we use ticks to compute sequence numbers, we might get wrong results as timeouts don't happen with precision of ticks ... we keep this as a leeway private Logger logger; private string myId; // used to distinguish during debugging between multiple activations of the same grain @@ -40,38 +40,38 @@ public ReminderTestGrain2(IServiceProvider services, IReminderTable reminderTabl public override Task OnActivateAsync() { - myId = Data.ActivationId.ToString();// new Random().Next(); - allReminders = new Dictionary(); - sequence = new Dictionary(); - logger = this.GetLogger(string.Format("ReminderTestGrain {0}_{1}", RuntimeIdentity.ToString(), Identity)); - period = GetDefaultPeriod(logger); - logger.Info("OnActivateAsync."); - filePrefix = "g" + Identity.PrimaryKey + "_"; + this.myId = this.Data.ActivationId.ToString();// new Random().Next(); + this.allReminders = new Dictionary(); + this.sequence = new Dictionary(); + this.logger = this.GetLogger(string.Format("ReminderTestGrain {0}_{1}", this.RuntimeIdentity.ToString(), this.Identity)); + this.period = GetDefaultPeriod(this.logger); + this.logger.Info("OnActivateAsync."); + this.filePrefix = "g" + this.Identity.PrimaryKey + "_"; return GetMissingReminders(); } public override Task OnDeactivateAsync() { - logger.Info("OnDeactivateAsync"); + this.logger.Info("OnDeactivateAsync"); return Task.CompletedTask; } public async Task StartReminder(string reminderName, TimeSpan? p = null, bool validate = false) { - TimeSpan usePeriod = p ?? period; - logger.Info("Starting reminder {0}.", reminderName); + TimeSpan usePeriod = p ?? this.period; + this.logger.Info("Starting reminder {0}.", reminderName); IGrainReminder r = null; if (validate) r = await RegisterOrUpdateReminder(reminderName, usePeriod - TimeSpan.FromSeconds(2), usePeriod); else r = await this.unvalidatedReminderRegistry.RegisterOrUpdateReminder(reminderName, usePeriod - TimeSpan.FromSeconds(2), usePeriod); - allReminders[reminderName] = r; - sequence[reminderName] = 0; + this.allReminders[reminderName] = r; + this.sequence[reminderName] = 0; string fileName = GetFileName(reminderName); File.Delete(fileName); // if successfully started, then remove any old data - logger.Info("Started reminder {0}", r); + this.logger.Info("Started reminder {0}", r); return r; } @@ -81,11 +81,11 @@ public Task ReceiveReminder(string reminderName, TickStatus status) // it doesn't know which reminders were registered against the grain // hence, this activation may receive a reminder that it didn't register itself, but // the previous activation (incarnation of the grain) registered... so, play it safe - if (!sequence.ContainsKey(reminderName)) + if (!this.sequence.ContainsKey(reminderName)) { // allReminders.Add(reminderName, r); // not using allReminders at the moment //counters.Add(reminderName, 0); - sequence.Add(reminderName, 0); // we'll get upto date to the latest sequence number while processing this tick + this.sequence.Add(reminderName, 0); // we'll get upto date to the latest sequence number while processing this tick } // calculating tick sequence number @@ -94,25 +94,25 @@ public Task ReceiveReminder(string reminderName, TickStatus status) // using dateTime.Ticks is not accurate as between two invocations of ReceiveReminder(), there maybe < period.Ticks // if # of ticks between two consecutive ReceiveReminder() is larger than period.Ticks, everything is fine... the problem is when its less // thus, we reduce our accuracy by ACCURACY ... here, we are preparing all used variables for the given accuracy - long now = status.CurrentTickTime.Ticks / ACCURACY; //DateTime.UtcNow.Ticks / ACCURACY; - long first = status.FirstTickTime.Ticks / ACCURACY; - long per = status.Period.Ticks / ACCURACY; + long now = status.CurrentTickTime.Ticks / aCCURACY; //DateTime.UtcNow.Ticks / ACCURACY; + long first = status.FirstTickTime.Ticks / aCCURACY; + long per = status.Period.Ticks / aCCURACY; long sequenceNumber = 1 + ((now - first) / per); // end of calculating tick sequence number // do switch-ing here - if (sequenceNumber < sequence[reminderName]) + if (sequenceNumber < this.sequence[reminderName]) { - logger.Info("ReceiveReminder: {0} Incorrect tick {1} vs. {2} with status {3}.", reminderName, sequence[reminderName], sequenceNumber, status); + this.logger.Info("ReceiveReminder: {0} Incorrect tick {1} vs. {2} with status {3}.", reminderName, this.sequence[reminderName], sequenceNumber, status); return Task.CompletedTask; } - sequence[reminderName] = sequenceNumber; - logger.Info("ReceiveReminder: {0} Sequence # {1} with status {2}.", reminderName, sequence[reminderName], status); + this.sequence[reminderName] = sequenceNumber; + this.logger.Info("ReceiveReminder: {0} Sequence # {1} with status {2}.", reminderName, this.sequence[reminderName], status); string fileName = GetFileName(reminderName); - string counterValue = sequence[reminderName].ToString(CultureInfo.InvariantCulture); + string counterValue = this.sequence[reminderName].ToString(CultureInfo.InvariantCulture); File.WriteAllText(fileName, counterValue); return Task.CompletedTask; @@ -120,11 +120,11 @@ public Task ReceiveReminder(string reminderName, TickStatus status) public async Task StopReminder(string reminderName) { - logger.Info("Stopping reminder {0}.", reminderName); + this.logger.Info("Stopping reminder {0}.", reminderName); // we dont reset counter as we want the test methods to be able to read it even after stopping the reminder //return UnregisterReminder(allReminders[reminderName]); IGrainReminder reminder = null; - if (allReminders.TryGetValue(reminderName, out reminder)) + if (this.allReminders.TryGetValue(reminderName, out reminder)) { await UnregisterReminder(reminder); } @@ -133,7 +133,7 @@ public async Task StopReminder(string reminderName) // during failures, there may be reminders registered by an earlier activation that we dont have cached locally // therefore, we need to update our local cache await GetMissingReminders(); - if (allReminders.TryGetValue(reminderName, out reminder)) + if (this.allReminders.TryGetValue(reminderName, out reminder)) { await UnregisterReminder(reminder); } @@ -141,7 +141,7 @@ public async Task StopReminder(string reminderName) { //var reminders = await this.GetRemindersList(); throw new OrleansException(string.Format( - "Could not find reminder {0} in grain {1}", reminderName, IdentityString)); + "Could not find reminder {0} in grain {1}", reminderName, this.IdentityString)); } } } @@ -149,12 +149,12 @@ public async Task StopReminder(string reminderName) private async Task GetMissingReminders() { List reminders = await base.GetReminders(); - logger.Info("Got missing reminders {0}", Utils.EnumerableToString(reminders)); + this.logger.Info("Got missing reminders {0}", Utils.EnumerableToString(reminders)); foreach (IGrainReminder l in reminders) { - if (!allReminders.ContainsKey(l.ReminderName)) + if (!this.allReminders.ContainsKey(l.ReminderName)) { - allReminders.Add(l.ReminderName, l); + this.allReminders.Add(l.ReminderName, l); } } } @@ -162,14 +162,14 @@ private async Task GetMissingReminders() public async Task StopReminder(IGrainReminder reminder) { - logger.Info("Stopping reminder (using ref) {0}.", reminder); + this.logger.Info("Stopping reminder (using ref) {0}.", reminder); // we dont reset counter as we want the test methods to be able to read it even after stopping the reminder await UnregisterReminder(reminder); } public Task GetReminderPeriod(string reminderName) { - return Task.FromResult(period); + return Task.FromResult(this.period); } public Task GetCounter(string name) @@ -191,7 +191,7 @@ public async Task> GetRemindersList() private string GetFileName(string reminderName) { - return string.Format("{0}{1}", filePrefix, reminderName); + return string.Format("{0}{1}", this.filePrefix, reminderName); } public static TimeSpan GetDefaultPeriod(Logger log) @@ -232,7 +232,7 @@ public class ReminderTestCopyGrain : Grain, IReminderTestCopyGrain, IRemindable Dictionary sequence; private TimeSpan period; - private static long ACCURACY = 50 * TimeSpan.TicksPerMillisecond; // when we use ticks to compute sequence numbers, we might get wrong results as timeouts don't happen with precision of ticks ... we keep this as a leeway + private static long aCCURACY = 50 * TimeSpan.TicksPerMillisecond; // when we use ticks to compute sequence numbers, we might get wrong results as timeouts don't happen with precision of ticks ... we keep this as a leeway private Logger logger; private long myId; // used to distinguish during debugging between multiple activations of the same grain @@ -246,26 +246,26 @@ public ReminderTestCopyGrain(IServiceProvider services) public override async Task OnActivateAsync() { - myId = new Random().Next(); - allReminders = new Dictionary(); - sequence = new Dictionary(); - logger = this.GetLogger(string.Format("ReminderCopyGrain {0}_{1}", myId, Identity)); - period = ReminderTestGrain2.GetDefaultPeriod(logger); - logger.Info("OnActivateAsync."); - filePrefix = "gc" + Identity.PrimaryKey + "_"; + this.myId = new Random().Next(); + this.allReminders = new Dictionary(); + this.sequence = new Dictionary(); + this.logger = this.GetLogger(string.Format("ReminderCopyGrain {0}_{1}", this.myId, this.Identity)); + this.period = ReminderTestGrain2.GetDefaultPeriod(this.logger); + this.logger.Info("OnActivateAsync."); + this.filePrefix = "gc" + this.Identity.PrimaryKey + "_"; await GetMissingReminders(); } public override Task OnDeactivateAsync() { - logger.Info("OnDeactivateAsync."); + this.logger.Info("OnDeactivateAsync."); return Task.CompletedTask; } public async Task StartReminder(string reminderName, TimeSpan? p = null, bool validate = false) { - TimeSpan usePeriod = p ?? period; - logger.Info("Starting reminder {0} for {1}", reminderName, Identity); + TimeSpan usePeriod = p ?? this.period; + this.logger.Info("Starting reminder {0} for {1}", reminderName, this.Identity); IGrainReminder r = null; if (validate) r = await RegisterOrUpdateReminder(reminderName, /*TimeSpan.FromSeconds(3)*/usePeriod - TimeSpan.FromSeconds(2), usePeriod); @@ -274,19 +274,19 @@ public async Task StartReminder(string reminderName, TimeSpan? p reminderName, usePeriod - TimeSpan.FromSeconds(2), usePeriod); - if (allReminders.ContainsKey(reminderName)) + if (this.allReminders.ContainsKey(reminderName)) { - allReminders[reminderName] = r; - sequence[reminderName] = 0; + this.allReminders[reminderName] = r; + this.sequence[reminderName] = 0; } else { - allReminders.Add(reminderName, r); - sequence.Add(reminderName, 0); + this.allReminders.Add(reminderName, r); + this.sequence.Add(reminderName, 0); } File.Delete(GetFileName(reminderName)); // if successfully started, then remove any old data - logger.Info("Started reminder {0}.", r); + this.logger.Info("Started reminder {0}.", r); return r; } @@ -296,11 +296,11 @@ public Task ReceiveReminder(string reminderName, TickStatus status) // it doesn't know which reminders were registered against the grain // hence, this activation may receive a reminder that it didn't register itself, but // the previous activation (incarnation of the grain) registered... so, play it safe - if (!sequence.ContainsKey(reminderName)) + if (!this.sequence.ContainsKey(reminderName)) { // allReminders.Add(reminderName, r); // not using allReminders at the moment //counters.Add(reminderName, 0); - sequence.Add(reminderName, 0); // we'll get upto date to the latest sequence number while processing this tick + this.sequence.Add(reminderName, 0); // we'll get upto date to the latest sequence number while processing this tick } // calculating tick sequence number @@ -309,35 +309,35 @@ public Task ReceiveReminder(string reminderName, TickStatus status) // using dateTime.Ticks is not accurate as between two invocations of ReceiveReminder(), there maybe < period.Ticks // if # of ticks between two consecutive ReceiveReminder() is larger than period.Ticks, everything is fine... the problem is when its less // thus, we reduce our accuracy by ACCURACY ... here, we are preparing all used variables for the given accuracy - long now = status.CurrentTickTime.Ticks / ACCURACY; //DateTime.UtcNow.Ticks / ACCURACY; - long first = status.FirstTickTime.Ticks / ACCURACY; - long per = status.Period.Ticks / ACCURACY; + long now = status.CurrentTickTime.Ticks / aCCURACY; //DateTime.UtcNow.Ticks / ACCURACY; + long first = status.FirstTickTime.Ticks / aCCURACY; + long per = status.Period.Ticks / aCCURACY; long sequenceNumber = 1 + ((now - first) / per); // end of calculating tick sequence number // do switch-ing here - if (sequenceNumber < sequence[reminderName]) + if (sequenceNumber < this.sequence[reminderName]) { - logger.Info("{0} Incorrect tick {1} vs. {2} with status {3}.", reminderName, sequence[reminderName], sequenceNumber, status); + this.logger.Info("{0} Incorrect tick {1} vs. {2} with status {3}.", reminderName, this.sequence[reminderName], sequenceNumber, status); return Task.CompletedTask; } - sequence[reminderName] = sequenceNumber; - logger.Info("{0} Sequence # {1} with status {2}.", reminderName, sequence[reminderName], status); + this.sequence[reminderName] = sequenceNumber; + this.logger.Info("{0} Sequence # {1} with status {2}.", reminderName, this.sequence[reminderName], status); - File.WriteAllText(GetFileName(reminderName), sequence[reminderName].ToString()); + File.WriteAllText(GetFileName(reminderName), this.sequence[reminderName].ToString()); return Task.CompletedTask; } public async Task StopReminder(string reminderName) { - logger.Info("Stoping reminder {0}.", reminderName); + this.logger.Info("Stoping reminder {0}.", reminderName); // we dont reset counter as we want the test methods to be able to read it even after stopping the reminder //return UnregisterReminder(allReminders[reminderName]); IGrainReminder reminder = null; - if (allReminders.TryGetValue(reminderName, out reminder)) + if (this.allReminders.TryGetValue(reminderName, out reminder)) { await UnregisterReminder(reminder); } @@ -346,7 +346,7 @@ public async Task StopReminder(string reminderName) // during failures, there may be reminders registered by an earlier activation that we dont have cached locally // therefore, we need to update our local cache await GetMissingReminders(); - await UnregisterReminder(allReminders[reminderName]); + await UnregisterReminder(this.allReminders[reminderName]); } } @@ -355,23 +355,23 @@ private async Task GetMissingReminders() List reminders = await base.GetReminders(); foreach (IGrainReminder l in reminders) { - if (!allReminders.ContainsKey(l.ReminderName)) + if (!this.allReminders.ContainsKey(l.ReminderName)) { - allReminders.Add(l.ReminderName, l); + this.allReminders.Add(l.ReminderName, l); } } } public async Task StopReminder(IGrainReminder reminder) { - logger.Info("Stoping reminder (using ref) {0}.", reminder); + this.logger.Info("Stoping reminder (using ref) {0}.", reminder); // we dont reset counter as we want the test methods to be able to read it even after stopping the reminder await UnregisterReminder(reminder); } public Task GetReminderPeriod(string reminderName) { - return Task.FromResult(period); + return Task.FromResult(this.period); } public Task GetCounter(string name) @@ -390,7 +390,7 @@ public async Task> GetRemindersList() private string GetFileName(string reminderName) { - return string.Format("{0}{1}", filePrefix, reminderName); + return string.Format("{0}{1}", this.filePrefix, reminderName); } } @@ -404,16 +404,16 @@ public class WrongReminderGrain : Grain, IReminderGrainWrong public override Task OnActivateAsync() { - logger = this.GetLogger(String.Format("WrongReminderGrain_{0}", Identity)); - logger.Info("OnActivateAsync."); + this.logger = this.GetLogger(string.Format("WrongReminderGrain_{0}", this.Identity)); + this.logger.Info("OnActivateAsync."); return Task.CompletedTask; } public async Task StartReminder(string reminderName) { - logger.Info("Starting reminder {0}.", reminderName); + this.logger.Info("Starting reminder {0}.", reminderName); IGrainReminder r = await RegisterOrUpdateReminder(reminderName, TimeSpan.FromSeconds(2), TimeSpan.FromSeconds(3)); - logger.Info("Started reminder {0}. It shouldn't have succeeded!", r); + this.logger.Info("Started reminder {0}. It shouldn't have succeeded!", r); return true; } } diff --git a/test/TestInternalGrains/StressTestGrain.cs b/test/TestInternalGrains/StressTestGrain.cs index 8471a81b2d..69d70bc883 100644 --- a/test/TestInternalGrains/StressTestGrain.cs +++ b/test/TestInternalGrains/StressTestGrain.cs @@ -21,16 +21,16 @@ public override Task OnActivateAsync() if (this.GetPrimaryKeyLong() == -2) throw new ArgumentException("Primary key cannot be -2 for this test case"); - logger = this.GetLogger("StressTestGrain " + base.RuntimeIdentity); - label = this.GetPrimaryKeyLong().ToString(); - logger.Info("OnActivateAsync"); + this.logger = this.GetLogger("StressTestGrain " + base.RuntimeIdentity); + this.label = this.GetPrimaryKeyLong().ToString(); + this.logger.Info("OnActivateAsync"); return Task.CompletedTask; } public Task GetLabel() { - return Task.FromResult(label); + return Task.FromResult(this.label); } public Task SetLabel(string label) @@ -51,7 +51,7 @@ public Task PingOthers(long[] others) List promises = new List(); foreach (long key in others) { - IStressTestGrain g1 = GrainFactory.GetGrain(key); + IStressTestGrain g1 = this.GrainFactory.GetGrain(key); Task promise = g1.GetLabel(); promises.Add(promise); } @@ -68,7 +68,7 @@ public Task PingOthers(long[] others) var reply = new List>(); for (int i = 0; i < 10; i++) { - var siloAddress = SiloAddress.New(new IPEndPoint(ClusterConfiguration.GetLocalIPAddress(),0), 0); + var siloAddress = SiloAddress.New(new IPEndPoint(ConfigUtilities.GetLocalIPAddress(),0), 0); reply.Add(new Tuple(siloAddress, ActivationId.NewId())); } list.Add(new Tuple>>(id, 3, reply)); @@ -111,15 +111,15 @@ internal class ReentrantStressTestGrain : Grain, IReentrantStressTestGrain public override Task OnActivateAsync() { - label = this.GetPrimaryKeyLong().ToString(); - logger = this.GetLogger("ReentrantStressTestGrain " + base.Data.Address.ToString()); - logger.Info("OnActivateAsync"); + this.label = this.GetPrimaryKeyLong().ToString(); + this.logger = this.GetLogger("ReentrantStressTestGrain " + base.Data.Address.ToString()); + this.logger.Info("OnActivateAsync"); return Task.CompletedTask; } public Task GetRuntimeInstanceId() { - return Task.FromResult(RuntimeIdentity); + return Task.FromResult(this.RuntimeIdentity); } public Task Echo(byte[] data) @@ -143,9 +143,9 @@ public Task PingMutableArray(byte[] data, long nextGrain, bool nextGrainIsRemote { if (nextGrainIsRemote) { - return GrainFactory.GetGrain(nextGrain).PingMutableArray(data, -1, false); + return this.GrainFactory.GetGrain(nextGrain).PingMutableArray(data, -1, false); } - return GrainFactory.GetGrain(nextGrain) + return this.GrainFactory.GetGrain(nextGrain) .PingMutableArray(data, -1, false); } return Task.CompletedTask; @@ -157,10 +157,10 @@ public Task PingImmutableArray(Immutable data, long nextGrain, bool next { if (nextGrainIsRemote) { - return GrainFactory.GetGrain(nextGrain) + return this.GrainFactory.GetGrain(nextGrain) .PingImmutableArray(data, -1, false); } - return GrainFactory.GetGrain(nextGrain) + return this.GrainFactory.GetGrain(nextGrain) .PingImmutableArray(data, -1, false); } return Task.CompletedTask; @@ -172,10 +172,10 @@ public Task PingMutableDictionary(Dictionary data, long nextGrain, { if (nextGrainIsRemote) { - return GrainFactory.GetGrain(nextGrain) + return this.GrainFactory.GetGrain(nextGrain) .PingMutableDictionary(data, -1, false); } - return GrainFactory.GetGrain(nextGrain) + return this.GrainFactory.GetGrain(nextGrain) .PingMutableDictionary(data, -1, false); } return Task.CompletedTask; @@ -188,10 +188,10 @@ public Task PingMutableDictionary(Dictionary data, long nextGrain, { if (nextGrainIsRemote) { - return GrainFactory.GetGrain(nextGrain) + return this.GrainFactory.GetGrain(nextGrain) .PingImmutableDictionary(data, -1, false); } - return GrainFactory.GetGrain(nextGrain) + return this.GrainFactory.GetGrain(nextGrain) .PingImmutableDictionary(data, -1, false); } return Task.CompletedTask; @@ -266,9 +266,9 @@ public class ReentrantLocalStressTestGrain : Grain, IReentrantLocalStressTestGra public override Task OnActivateAsync() { - label = this.GetPrimaryKeyLong().ToString(); - logger = this.GetLogger("ReentrantLocalStressTestGrain " + base.Data.Address.ToString()); - logger.Info("OnActivateAsync"); + this.label = this.GetPrimaryKeyLong().ToString(); + this.logger = this.GetLogger("ReentrantLocalStressTestGrain " + base.Data.Address.ToString()); + this.logger.Info("OnActivateAsync"); return Task.CompletedTask; } @@ -279,7 +279,7 @@ public Task Echo(byte[] data) public Task GetRuntimeInstanceId() { - return Task.FromResult(RuntimeIdentity); + return Task.FromResult(this.RuntimeIdentity); } public Task Ping(byte[] data) @@ -298,9 +298,9 @@ public Task PingMutableArray(byte[] data, long nextGrain, bool nextGrainIsRemote { if (nextGrainIsRemote) { - return GrainFactory.GetGrain(nextGrain).PingMutableArray(data, -1, false); + return this.GrainFactory.GetGrain(nextGrain).PingMutableArray(data, -1, false); } - return GrainFactory.GetGrain(nextGrain) + return this.GrainFactory.GetGrain(nextGrain) .PingMutableArray(data, -1, false); } return Task.CompletedTask; @@ -312,10 +312,10 @@ public Task PingImmutableArray(Immutable data, long nextGrain, bool next { if (nextGrainIsRemote) { - return GrainFactory.GetGrain(nextGrain) + return this.GrainFactory.GetGrain(nextGrain) .PingImmutableArray(data, -1, false); } - return GrainFactory.GetGrain(nextGrain) + return this.GrainFactory.GetGrain(nextGrain) .PingImmutableArray(data, -1, false); } return Task.CompletedTask; @@ -327,10 +327,10 @@ public Task PingMutableDictionary(Dictionary data, long nextGrain, { if (nextGrainIsRemote) { - return GrainFactory.GetGrain(nextGrain) + return this.GrainFactory.GetGrain(nextGrain) .PingMutableDictionary(data, -1, false); } - return GrainFactory.GetGrain(nextGrain) + return this.GrainFactory.GetGrain(nextGrain) .PingMutableDictionary(data, -1, false); } return Task.CompletedTask; @@ -343,10 +343,10 @@ public Task PingMutableDictionary(Dictionary data, long nextGrain, { if (nextGrainIsRemote) { - return GrainFactory.GetGrain(nextGrain) + return this.GrainFactory.GetGrain(nextGrain) .PingImmutableDictionary(data, -1, false); } - return GrainFactory.GetGrain(nextGrain) + return this.GrainFactory.GetGrain(nextGrain) .PingImmutableDictionary(data, -1, false); } return Task.CompletedTask; diff --git a/test/TestInternalGrains/TestInternalGrains.csproj b/test/TestInternalGrains/TestInternalGrains.csproj index 720559f89a..2ba4fa0794 100644 --- a/test/TestInternalGrains/TestInternalGrains.csproj +++ b/test/TestInternalGrains/TestInternalGrains.csproj @@ -18,6 +18,7 @@ + diff --git a/test/Tester/GrainServiceTests/CustomGrainService.cs b/test/Tester/GrainServiceTests/CustomGrainService.cs index 684343b601..b45a2c5c37 100644 --- a/test/Tester/GrainServiceTests/CustomGrainService.cs +++ b/test/Tester/GrainServiceTests/CustomGrainService.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Threading.Tasks; using Microsoft.Extensions.Logging; using Orleans; @@ -43,19 +43,24 @@ public Task HasInit() public class CustomGrainService : GrainService, ICustomGrainService { - public CustomGrainService(IGrainIdentity id, Silo silo, IGrainServiceConfiguration config, ILoggerFactory loggerFactory) : base(id, silo, config, loggerFactory) + private readonly IGrainIdentity id; + private IGrainServiceConfiguration config; + + public CustomGrainService(IGrainIdentity id, Silo silo, ILoggerFactory loggerFactory) : base(id, silo, loggerFactory) { - + this.id = id; } private bool started = false; private bool startedInBackground = false; private bool init = false; - public override Task Init(IServiceProvider serviceProvider) + public async override Task Init(IServiceProvider serviceProvider) { + await base.Init(serviceProvider); + long configKey = this.id.GetPrimaryKeyLong(out string ignore); + this.config = serviceProvider.GetRequiredServiceByKey(configKey); init = true; - return base.Init(serviceProvider); } public override Task Start() @@ -71,7 +76,7 @@ public Task GetHelloWorldUsingCustomService(GrainReference reference) public Task GetServiceConfigProperty(string propertyName) { - return Task.FromResult(base.Config.Properties[propertyName]); + return Task.FromResult(this.config.Properties[propertyName]); } protected override Task StartInBackground() diff --git a/test/Tester/Placement/CustomPlacementTests.cs b/test/Tester/Placement/CustomPlacementTests.cs index a401f9bac7..c55f1652ee 100644 --- a/test/Tester/Placement/CustomPlacementTests.cs +++ b/test/Tester/Placement/CustomPlacementTests.cs @@ -40,10 +40,15 @@ private class TestSiloBuilderConfigurator : ISiloBuilderConfigurator { public void Configure(ISiloHostBuilder hostBuilder) { - hostBuilder.ConfigureServices(services => - services.AddSingleton, TestPlacementStrategyFixedSiloDirector>()); + hostBuilder.ConfigureServices(ConfigureServices); } } + + private static void ConfigureServices(IServiceCollection services) + { + services.AddSingletonNamedService(nameof(TestCustomPlacementStrategy)); + services.AddSingletonKeyedService(typeof(TestCustomPlacementStrategy)); + } } public CustomPlacementTests(Fixture fixture) diff --git a/test/Tester/SiloInitializationTests.cs b/test/Tester/SiloInitializationTests.cs index 6c00f42ac2..a08f8c98c0 100644 --- a/test/Tester/SiloInitializationTests.cs +++ b/test/Tester/SiloInitializationTests.cs @@ -77,7 +77,7 @@ private static SiloHost CreateSiloHost(AppDomain appDomain, ClusterConfiguration var args = new object[] { nameof(SiloInitializationIsRetryableTest), clusterConfig}; return (SiloHost)appDomain.CreateInstanceFromAndUnwrap( - "Orleans.Runtime.dll", + "Orleans.Runtime.Legacy.dll", typeof(SiloHost).FullName, false, BindingFlags.Default, diff --git a/test/Tester/Tester.csproj b/test/Tester/Tester.csproj index e362fc3f8d..95728d8deb 100644 --- a/test/Tester/Tester.csproj +++ b/test/Tester/Tester.csproj @@ -1,4 +1,4 @@ - + Tester Tester @@ -19,6 +19,7 @@ + diff --git a/test/TesterAzureUtils/AzureGossipTableTests.cs b/test/TesterAzureUtils/AzureGossipTableTests.cs index ef64bdb3ba..c78df86fad 100644 --- a/test/TesterAzureUtils/AzureGossipTableTests.cs +++ b/test/TesterAzureUtils/AzureGossipTableTests.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Linq; using System.Net; using System.Threading.Tasks; @@ -20,28 +20,28 @@ public class AzureGossipTableTests : AzureStorageBasicTests , IDisposable private Guid globalServiceId; //this should be the same for all clusters. Use this as partition key. private SiloAddress siloAddress1; private SiloAddress siloAddress2; - private static readonly TimeSpan timeout = TimeSpan.FromMinutes(1); + private static readonly TimeSpan Timeout = TimeSpan.FromMinutes(1); private AzureTableBasedGossipChannel gossipTable; // This type is internal private readonly ILoggerFactory loggerFactory; public AzureGossipTableTests() { - loggerFactory = TestingUtils.CreateDefaultLoggerFactory($"{this.GetType().Name}.log"); - logger = loggerFactory.CreateLogger(); - - globalServiceId = Guid.NewGuid(); + this.loggerFactory = TestingUtils.CreateDefaultLoggerFactory($"{this.GetType().Name}.log"); + this.logger = this.loggerFactory.CreateLogger(); + + this.globalServiceId = Guid.NewGuid(); IPAddress ip; if (!IPAddress.TryParse("127.0.0.1", out ip)) { - logger.Error(-1, "Could not parse ip address"); + this.logger.Error(-1, "Could not parse ip address"); return; } IPEndPoint ep1 = new IPEndPoint(ip, 21111); - siloAddress1 = SiloAddress.New(ep1, 0); + this.siloAddress1 = SiloAddress.New(ep1, 0); IPEndPoint ep2 = new IPEndPoint(ip, 21112); - siloAddress2 = SiloAddress.New(ep2, 0); + this.siloAddress2 = SiloAddress.New(ep2, 0); - logger.Info("Global ServiceId={0}", globalServiceId); + this.logger.Info("Global ServiceId={0}", this.globalServiceId); GlobalConfiguration config = new GlobalConfiguration { @@ -50,9 +50,9 @@ public AzureGossipTableTests() DataConnectionString = TestDefaultConfiguration.DataConnectionString }; - gossipTable = new AzureTableBasedGossipChannel(loggerFactory); - var done = gossipTable.Initialize(config.ServiceId, config.DataConnectionString); - if (!done.Wait(timeout)) + this.gossipTable = new AzureTableBasedGossipChannel(this.loggerFactory); + var done = this.gossipTable.Initialize(config.ServiceId, config.DataConnectionString); + if (!done.Wait(Timeout)) { throw new TimeoutException("Could not create/read table."); } @@ -67,13 +67,13 @@ public void Dispose() public async Task AzureGossip_ConfigGossip() { // start clean - await gossipTable.DeleteAllEntries(); + await this.gossipTable.DeleteAllEntries(); // push empty data - await gossipTable.Publish(new MultiClusterData()); + await this.gossipTable.Publish(new MultiClusterData()); // push and pull empty data - var answer = await gossipTable.Synchronize(new MultiClusterData()); + var answer = await this.gossipTable.Synchronize(new MultiClusterData()); Assert.True(answer.IsEmpty); var ts1 = new DateTime(year: 2011, month: 1, day: 1); @@ -85,34 +85,34 @@ public async Task AzureGossip_ConfigGossip() var conf3 = new MultiClusterConfiguration(ts3, new string[] { }.ToList()); // push configuration 1 - await gossipTable.Publish(new MultiClusterData(conf1)); + await this.gossipTable.Publish(new MultiClusterData(conf1)); // retrieve (by push/pull empty) - answer = await gossipTable.Synchronize(new MultiClusterData()); + answer = await this.gossipTable.Synchronize(new MultiClusterData()); Assert.Equal(conf1, answer.Configuration); // gossip stable - answer = await gossipTable.Synchronize(new MultiClusterData(conf1)); + answer = await this.gossipTable.Synchronize(new MultiClusterData(conf1)); Assert.True(answer.IsEmpty); // push configuration 2 - answer = await gossipTable.Synchronize(new MultiClusterData(conf2)); + answer = await this.gossipTable.Synchronize(new MultiClusterData(conf2)); Assert.True(answer.IsEmpty); // gossip returns latest - answer = await gossipTable.Synchronize(new MultiClusterData(conf1)); + answer = await this.gossipTable.Synchronize(new MultiClusterData(conf1)); Assert.Equal(conf2, answer.Configuration); - await gossipTable.Publish(new MultiClusterData(conf1)); - answer = await gossipTable.Synchronize(new MultiClusterData()); + await this.gossipTable.Publish(new MultiClusterData(conf1)); + answer = await this.gossipTable.Synchronize(new MultiClusterData()); Assert.Equal(conf2, answer.Configuration); - answer = await gossipTable.Synchronize(new MultiClusterData(conf2)); + answer = await this.gossipTable.Synchronize(new MultiClusterData(conf2)); Assert.True(answer.IsEmpty); // push final configuration - answer = await gossipTable.Synchronize(new MultiClusterData(conf3)); + answer = await this.gossipTable.Synchronize(new MultiClusterData(conf3)); Assert.True(answer.IsEmpty); - answer = await gossipTable.Synchronize(new MultiClusterData(conf1)); + answer = await this.gossipTable.Synchronize(new MultiClusterData(conf1)); Assert.Equal(conf3, answer.Configuration); } @@ -120,7 +120,7 @@ public async Task AzureGossip_ConfigGossip() public async Task AzureGossip_GatewayGossip() { // start clean - await gossipTable.DeleteAllEntries(); + await this.gossipTable.DeleteAllEntries(); var ts1 = DateTime.UtcNow; var ts2 = ts1 + new TimeSpan(hours: 0, minutes: 0, seconds: 1); @@ -156,40 +156,40 @@ public async Task AzureGossip_GatewayGossip() }; // push G1 - await gossipTable.Publish(new MultiClusterData(G1)); + await this.gossipTable.Publish(new MultiClusterData(G1)); // push H1, retrieve G1 - var answer = await gossipTable.Synchronize(new MultiClusterData(H1)); + var answer = await this.gossipTable.Synchronize(new MultiClusterData(H1)); Assert.Equal(1, answer.Gateways.Count); - Assert.True(answer.Gateways.ContainsKey(siloAddress1)); - Assert.Equal(G1, answer.Gateways[siloAddress1]); + Assert.True(answer.Gateways.ContainsKey(this.siloAddress1)); + Assert.Equal(G1, answer.Gateways[this.siloAddress1]); // push G2, retrieve H1 - answer = await gossipTable.Synchronize(new MultiClusterData(G2)); + answer = await this.gossipTable.Synchronize(new MultiClusterData(G2)); Assert.Equal(1, answer.Gateways.Count); - Assert.True(answer.Gateways.ContainsKey(siloAddress2)); - Assert.Equal(H1, answer.Gateways[siloAddress2]); + Assert.True(answer.Gateways.ContainsKey(this.siloAddress2)); + Assert.Equal(H1, answer.Gateways[this.siloAddress2]); // gossip stable - await gossipTable.Publish(new MultiClusterData(H1)); - await gossipTable.Publish(new MultiClusterData(G1)); - answer = await gossipTable.Synchronize(new MultiClusterData(new GatewayEntry[] { H1, G2 })); + await this.gossipTable.Publish(new MultiClusterData(H1)); + await this.gossipTable.Publish(new MultiClusterData(G1)); + answer = await this.gossipTable.Synchronize(new MultiClusterData(new GatewayEntry[] { H1, G2 })); Assert.True(answer.IsEmpty); // retrieve - answer = await gossipTable.Synchronize(new MultiClusterData(new GatewayEntry[] { H1, G2 })); + answer = await this.gossipTable.Synchronize(new MultiClusterData(new GatewayEntry[] { H1, G2 })); Assert.True(answer.IsEmpty); // push H2 - await gossipTable.Publish(new MultiClusterData(H2)); + await this.gossipTable.Publish(new MultiClusterData(H2)); // retrieve all - answer = await gossipTable.Synchronize(new MultiClusterData(new GatewayEntry[] { G1, H1 })); + answer = await this.gossipTable.Synchronize(new MultiClusterData(new GatewayEntry[] { G1, H1 })); Assert.Equal(2, answer.Gateways.Count); - Assert.True(answer.Gateways.ContainsKey(siloAddress1)); - Assert.True(answer.Gateways.ContainsKey(siloAddress2)); - Assert.Equal(G2, answer.Gateways[siloAddress1]); - Assert.Equal(H2, answer.Gateways[siloAddress2]); + Assert.True(answer.Gateways.ContainsKey(this.siloAddress1)); + Assert.True(answer.Gateways.ContainsKey(this.siloAddress2)); + Assert.Equal(G2, answer.Gateways[this.siloAddress1]); + Assert.Equal(H2, answer.Gateways[this.siloAddress2]); } } diff --git a/test/TesterAzureUtils/AzureRemindersTableTests.cs b/test/TesterAzureUtils/AzureRemindersTableTests.cs index e2f552465c..89cdd9367f 100644 --- a/test/TesterAzureUtils/AzureRemindersTableTests.cs +++ b/test/TesterAzureUtils/AzureRemindersTableTests.cs @@ -1,4 +1,4 @@ -using System.Threading.Tasks; +using System.Threading.Tasks; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using Orleans; @@ -41,7 +41,7 @@ public override void Dispose() protected override IReminderTable CreateRemindersTable() { TestUtils.CheckForAzureStorage(); - return new AzureBasedReminderTable(this.ClusterFixture.Services.GetRequiredService(), loggerFactory, this.siloOptions); + return new AzureBasedReminderTable(this.ClusterFixture.Services.GetRequiredService(), loggerFactory, this.siloOptions, this.storageOptions); } protected override Task GetConnectionString() diff --git a/test/TesterAzureUtils/Deployment/AzureSiloTests.cs b/test/TesterAzureUtils/Deployment/AzureSiloTests.cs index aa960fc7e5..594c798147 100644 --- a/test/TesterAzureUtils/Deployment/AzureSiloTests.cs +++ b/test/TesterAzureUtils/Deployment/AzureSiloTests.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Net; using System.Threading.Tasks; @@ -42,8 +42,10 @@ public async Task ValidateConfiguration_Startup_Emulator() private async Task ValidateConfigurationAtStartup(string connectionString) { - var serviceRuntime = new TestServiceRuntimeWrapper(); - serviceRuntime.DeploymentId = "foo"; + var serviceRuntime = new TestServiceRuntimeWrapper + { + DeploymentId = "foo" + }; serviceRuntime.Settings["DataConnectionString"] = connectionString; serviceRuntime.InstanceName = "name"; @@ -59,8 +61,10 @@ private async Task ValidateConfigurationAtStartup(string connectionString) [Fact, TestCategory("BVT"), TestCategory("Functional")] public async Task ValidateConfiguration_InvalidConnectionString() { - var serviceRuntime = new TestServiceRuntimeWrapper(); - serviceRuntime.DeploymentId = "bar"; + var serviceRuntime = new TestServiceRuntimeWrapper + { + DeploymentId = "bar" + }; serviceRuntime.Settings["DataConnectionString"] = "InvalidConnectionString"; serviceRuntime.InstanceName = "name"; @@ -76,8 +80,10 @@ public async Task ValidateConfiguration_InvalidConnectionString() [Fact, TestCategory("BVT"), TestCategory("Functional")] public async Task ValidateConfiguration_IncorrectKey() { - var serviceRuntime = new TestServiceRuntimeWrapper(); - serviceRuntime.DeploymentId = "bar"; + var serviceRuntime = new TestServiceRuntimeWrapper + { + DeploymentId = "bar" + }; serviceRuntime.Settings["DataConnectionString"] = "DefaultEndpointsProtocol=https;AccountName=orleanstest;AccountKey=IncorrectKey"; serviceRuntime.InstanceName = "name"; @@ -104,7 +110,7 @@ public class TestServiceRuntimeWrapper : IServiceRuntimeWrapper public string GetConfigurationSettingValue(string configurationSettingName) { - return Settings[configurationSettingName]; + return this.Settings[configurationSettingName]; } public IPEndPoint GetIPEndpoint(string endpointName) diff --git a/test/TesterAzureUtils/Reminder/ReminderTests_Azure_Standalone.cs b/test/TesterAzureUtils/Reminder/ReminderTests_Azure_Standalone.cs index f7e85194da..9a2b20a03c 100644 --- a/test/TesterAzureUtils/Reminder/ReminderTests_Azure_Standalone.cs +++ b/test/TesterAzureUtils/Reminder/ReminderTests_Azure_Standalone.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; @@ -13,6 +13,7 @@ using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using Orleans.TestingHost.Utils; +using Orleans.Hosting; // ReSharper disable InconsistentNaming // ReSharper disable UnusedVariable @@ -26,7 +27,7 @@ public class ReminderTests_Azure_Standalone : AzureStorageBasicTests private readonly ITestOutputHelper output; private readonly TestEnvironmentFixture fixture; - private Guid ServiceId; + private Guid serviceId; private ILogger log; private ILoggerFactory loggerFactory; @@ -35,9 +36,9 @@ public ReminderTests_Azure_Standalone(ITestOutputHelper output, TestEnvironmentF this.output = output; this.fixture = fixture; this.loggerFactory = TestingUtils.CreateDefaultLoggerFactory($"{GetType().Name}.log"); - log = loggerFactory.CreateLogger(); + this.log = this.loggerFactory.CreateLogger(); - ServiceId = Guid.NewGuid(); + this.serviceId = Guid.NewGuid(); TestUtils.ConfigureClientThreadPoolSettingsForStorageTests(1000); } @@ -47,13 +48,11 @@ public ReminderTests_Azure_Standalone(ITestOutputHelper output, TestEnvironmentF [SkippableFact, TestCategory("ReminderService"), TestCategory("Performance")] public async Task Reminders_AzureTable_InsertRate() { - var siloOptions = Options.Create(new SiloOptions { ClusterId = "TMSLocalTesting", ServiceId = this.ServiceId }); - IReminderTable table = new AzureBasedReminderTable(this.fixture.Services.GetRequiredService(), this.loggerFactory, siloOptions); - var config = new GlobalConfiguration() - { - DataConnectionString = TestDefaultConfiguration.DataConnectionString - }; - await table.Init(config); + var siloOptions = Options.Create(new SiloOptions { ClusterId = "TMSLocalTesting", ServiceId = this.serviceId }); + var storageOptions = Options.Create(new StorageOptions { DataConnectionString = TestDefaultConfiguration.DataConnectionString }); + + IReminderTable table = new AzureBasedReminderTable(this.fixture.Services.GetRequiredService(), this.loggerFactory, siloOptions, storageOptions); + await table.Init(); await TestTableInsertRate(table, 10); await TestTableInsertRate(table, 500); @@ -63,15 +62,10 @@ public async Task Reminders_AzureTable_InsertRate() public async Task Reminders_AzureTable_InsertNewRowAndReadBack() { string clusterId = NewClusterId(); - var siloOptions = Options.Create(new SiloOptions { ClusterId = clusterId, ServiceId = this.ServiceId }); - IReminderTable table = new AzureBasedReminderTable(this.fixture.Services.GetRequiredService(), this.loggerFactory, siloOptions); - var config = new GlobalConfiguration() - { - ServiceId = ServiceId, - ClusterId = clusterId, - DataConnectionString = TestDefaultConfiguration.DataConnectionString - }; - await table.Init(config); + var siloOptions = Options.Create(new SiloOptions { ClusterId = clusterId, ServiceId = this.serviceId }); + var storageOptions = Options.Create(new StorageOptions { DataConnectionString = TestDefaultConfiguration.DataConnectionString }); + IReminderTable table = new AzureBasedReminderTable(this.fixture.Services.GetRequiredService(), this.loggerFactory, siloOptions, storageOptions); + await table.Init(); ReminderEntry[] rows = (await GetAllRows(table)).ToArray(); Assert.Empty(rows); // "The reminder table (sid={0}, did={1}) was not empty.", ServiceId, clusterId); @@ -87,7 +81,7 @@ public async Task Reminders_AzureTable_InsertNewRowAndReadBack() Assert.Equal(expected.Period, actual.Period); // "The newly inserted reminder table (sid={0}, did={1}) row did not have the expected period.", ServiceId, clusterId); // the following assertion fails but i don't know why yet-- the timestamps appear identical in the error message. it's not really a priority to hunt down the reason, however, because i have high confidence it is working well enough for the moment. /*Assert.Equal(expected.StartAt, actual.StartAt); // "The newly inserted reminder table (sid={0}, did={1}) row did not contain the correct start time.", ServiceId, clusterId);*/ - Assert.False(string.IsNullOrWhiteSpace(actual.ETag), $"The newly inserted reminder table (sid={ServiceId}, did={clusterId}) row contains an invalid etag."); + Assert.False(string.IsNullOrWhiteSpace(actual.ETag), $"The newly inserted reminder table (sid={this.serviceId}, did={clusterId}) row contains an invalid etag."); } private async Task TestTableInsertRate(IReminderTable reminderTable, double numOfInserts) @@ -115,21 +109,21 @@ private async Task TestTableInsertRate(IReminderTable reminderTable, double numO Task promise = Task.Run(async () => { await reminderTable.UpsertRow(e); - output.WriteLine("Done " + capture); + this.output.WriteLine("Done " + capture); return true; }); promises.Add(promise); - log.Info("Started " + capture); + this.log.Info("Started " + capture); } - log.Info("Started all, now waiting..."); + this.log.Info("Started all, now waiting..."); await Task.WhenAll(promises).WithTimeout(TimeSpan.FromSeconds(500)); } catch (Exception exc) { - log.Info("Exception caught {0}", exc); + this.log.Info("Exception caught {0}", exc); } TimeSpan dur = DateTime.UtcNow - startedAt; - log.Info("Inserted {0} rows in {1}, i.e., {2:f2} upserts/sec", numOfInserts, dur, (numOfInserts / dur.TotalSeconds)); + this.log.Info("Inserted {0} rows in {1}, i.e., {2:f2} upserts/sec", numOfInserts, dur, (numOfInserts / dur.TotalSeconds)); } #endregion diff --git a/test/TesterAzureUtils/Streaming/AzureQueueAdapterTests.cs b/test/TesterAzureUtils/Streaming/AzureQueueAdapterTests.cs index 7a104543c2..22efd6305d 100644 --- a/test/TesterAzureUtils/Streaming/AzureQueueAdapterTests.cs +++ b/test/TesterAzureUtils/Streaming/AzureQueueAdapterTests.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Globalization; @@ -41,7 +41,7 @@ public AzureQueueAdapterTests(ITestOutputHelper output, TestEnvironmentFixture f this.fixture = fixture; this.clusterId = MakeClusterId(); this.loggerFactory = this.fixture.Services.GetService(); - BufferPool.InitGlobalBufferPool(Options.Create(new SiloMessagingOptions())); + BufferPool.InitGlobalBufferPool(new SiloMessagingOptions()); } public void Dispose() @@ -109,7 +109,7 @@ private async Task SendAndReceiveFromQueueAdapter(IQueueAdapterFactory adapterFa set.Add(new StreamIdentity(message.StreamGuid, message.StreamGuid.ToString())); return set; }); - output.WriteLine("Queue {0} received message on stream {1}", queueId, + this.output.WriteLine("Queue {0} received message on stream {1}", queueId, message.StreamGuid); Assert.Equal(NumMessagesPerBatch / 2, message.GetEvents().Count()); // "Half the events were ints" Assert.Equal(NumMessagesPerBatch / 2, message.GetEvents().Count()); // "Half the events were strings" @@ -153,7 +153,7 @@ private async Task SendAndReceiveFromQueueAdapter(IQueueAdapterFactory adapterFa Exception ex; messageCount++; IBatchContainer batch = cursor.GetCurrent(out ex); - output.WriteLine("Token: {0}", batch.SequenceToken); + this.output.WriteLine("Token: {0}", batch.SequenceToken); Assert.True(batch.SequenceToken.CompareTo(lastToken) >= 0, $"order check for event {messageCount}"); lastToken = batch.SequenceToken; if (messageCount == 10) @@ -161,7 +161,7 @@ private async Task SendAndReceiveFromQueueAdapter(IQueueAdapterFactory adapterFa tenthInCache = batch.SequenceToken; } } - output.WriteLine("On Queue {0} we received a total of {1} message on stream {2}", kvp.Key, messageCount, streamGuid); + this.output.WriteLine("On Queue {0} we received a total of {1} message on stream {2}", kvp.Key, messageCount, streamGuid); Assert.Equal(NumBatches / 2, messageCount); Assert.NotNull(tenthInCache); @@ -172,7 +172,7 @@ private async Task SendAndReceiveFromQueueAdapter(IQueueAdapterFactory adapterFa { messageCount++; } - output.WriteLine("On Queue {0} we received a total of {1} message on stream {2}", kvp.Key, messageCount, streamGuid); + this.output.WriteLine("On Queue {0} we received a total of {1} message on stream {2}", kvp.Key, messageCount, streamGuid); const int expected = NumBatches / 2 - 10 + 1; // all except the first 10, including the 10th (10 + 1) Assert.Equal(expected, messageCount); } @@ -195,7 +195,7 @@ internal static string MakeClusterId() { const string DeploymentIdFormat = "cluster-{0}"; string now = DateTime.UtcNow.ToString("yyyy-MM-dd-hh-mm-ss-ffff"); - return String.Format(DeploymentIdFormat, now); + return string.Format(DeploymentIdFormat, now); } } } \ No newline at end of file diff --git a/test/TesterInternal/General/RequestContextTest.cs b/test/TesterInternal/General/RequestContextTest.cs index 1ecdea4f00..8a8240fe44 100644 --- a/test/TesterInternal/General/RequestContextTest.cs +++ b/test/TesterInternal/General/RequestContextTest.cs @@ -335,50 +335,6 @@ public async Task RequestContext_ActivityId_CM_DynamicChange_Client() RequestContext.Clear(); } - [Fact(Skip = "Silo setting update of PropagateActivityId is not correctly implemented")] - [TestCategory("Functional"), TestCategory("RequestContext")] - public async Task RequestContext_ActivityId_CM_DynamicChange_Server() - { - Guid activityId = Guid.NewGuid(); - Guid activityId2 = Guid.NewGuid(); - - const string PropagateActivityIdConfigKey = @"/OrleansConfiguration/Defaults/Tracing/@PropagateActivityId"; - var changeConfig = new Dictionary(); - - IManagementGrain mgmtGrain = this.fixture.GrainFactory.GetGrain(0); - - IRequestContextTestGrain grain = this.fixture.GrainFactory.GetGrain(GetRandomGrainId()); - - RequestContextTestUtils.SetActivityId(activityId); - Guid result = await grain.E2EActivityId(); - Assert.Equal(activityId, result); // "E2E ActivityId #1 not propagated correctly" - RequestContext.Clear(); - - changeConfig[PropagateActivityIdConfigKey] = Boolean.FalseString; - output.WriteLine("Set {0}={1}", PropagateActivityIdConfigKey, changeConfig[PropagateActivityIdConfigKey]); - await mgmtGrain.UpdateConfiguration(null, changeConfig, null); - - RequestContextTestUtils.SetActivityId(activityId2); - result = await grain.E2EActivityId(); - Assert.NotEqual(activityId2, result); // "E2E ActivityId #2 should not have been propagated" - Assert.Equal(Guid.Empty, result); // "E2E ActivityId #2 should not have been propagated" - RequestContext.Clear(); - - changeConfig[PropagateActivityIdConfigKey] = Boolean.TrueString; - output.WriteLine("Set {0}={1}", PropagateActivityIdConfigKey, changeConfig[PropagateActivityIdConfigKey]); - await mgmtGrain.UpdateConfiguration(null, changeConfig, null); - - RequestContextTestUtils.SetActivityId(activityId2); - result = await grain.E2EActivityId(); - Assert.Equal(activityId2, result); // "E2E ActivityId #2 should have been propagated" - RequestContext.Clear(); - - RequestContextTestUtils.SetActivityId(activityId); - result = await grain.E2EActivityId(); - Assert.Equal(activityId, result); // "E2E ActivityId #1 not propagated correctly after #2" - RequestContext.Clear(); - } - [Fact, TestCategory("Functional"), TestCategory("RequestContext")] public async Task ClientInvokeCallback_CountCallbacks() { diff --git a/test/TesterInternal/LivenessTests/ConsistentRingProviderTests.cs b/test/TesterInternal/LivenessTests/ConsistentRingProviderTests.cs index 4e0aceec7b..1ec401bfe2 100644 --- a/test/TesterInternal/LivenessTests/ConsistentRingProviderTests.cs +++ b/test/TesterInternal/LivenessTests/ConsistentRingProviderTests.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using Microsoft.Extensions.Logging.Abstractions; @@ -7,7 +7,6 @@ using Orleans.Streams; using Xunit; using Xunit.Abstractions; -using Microsoft.Extensions.Options; using Orleans.Hosting; using TestExtensions; @@ -21,7 +20,7 @@ public class Fixture { public Fixture() { - BufferPool.InitGlobalBufferPool(Options.Create(new SiloMessagingOptions())); + BufferPool.InitGlobalBufferPool(new SiloMessagingOptions()); } } diff --git a/test/TesterInternal/RemindersTest/ReminderTableTestsBase.cs b/test/TesterInternal/RemindersTest/ReminderTableTestsBase.cs index fbbe0f25d3..6e6a806ba1 100644 --- a/test/TesterInternal/RemindersTest/ReminderTableTestsBase.cs +++ b/test/TesterInternal/RemindersTest/ReminderTableTestsBase.cs @@ -13,6 +13,7 @@ using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using Orleans.TestingHost.Utils; +using Orleans.Hosting; namespace UnitTests.RemindersTest { @@ -25,10 +26,13 @@ public abstract class ReminderTableTestsBase : IDisposable, IClassFixture siloOptions; + protected IOptions storageOptions; + protected IOptions adoNetOptions; protected const string testDatabaseName = "OrleansReminderTest";//for relational storage protected ReminderTableTestsBase(ConnectionStringFixture fixture, TestEnvironmentFixture clusterFixture, LoggerFilterOptions filters) { + fixture.InitializeConnectionStringAccessor(GetConnectionString); loggerFactory = TestingUtils.CreateDefaultLoggerFactory($"{this.GetType()}.log", filters); this.ClusterFixture = clusterFixture; logger = loggerFactory.CreateLogger(); @@ -36,8 +40,9 @@ protected ReminderTableTestsBase(ConnectionStringFixture fixture, TestEnvironmen var clusterId = "test-" + serviceId; logger.Info("ClusterId={0}", clusterId); - siloOptions = Options.Create(new SiloOptions { ClusterId = clusterId, ServiceId = serviceId }); - fixture.InitializeConnectionStringAccessor(GetConnectionString); + this.siloOptions = Options.Create(new SiloOptions { ClusterId = clusterId, ServiceId = serviceId }); + this.storageOptions = Options.Create(new StorageOptions { DataConnectionStringForReminders = fixture.ConnectionString }); + this.adoNetOptions = Options.Create(new AdoNetOptions() { InvariantForReminders = GetAdoInvariant() }); var globalConfiguration = new GlobalConfiguration { @@ -48,7 +53,7 @@ protected ReminderTableTestsBase(ConnectionStringFixture fixture, TestEnvironmen }; var rmndr = CreateRemindersTable(); - rmndr.Init(globalConfiguration).WithTimeout(TimeSpan.FromMinutes(1)).Wait(); + rmndr.Init().WithTimeout(TimeSpan.FromMinutes(1)).Wait(); remindersTable = rmndr; } diff --git a/test/TesterInternal/StorageTests/HierarchicalKeyStoreTests.cs b/test/TesterInternal/StorageTests/HierarchicalKeyStoreTests.cs index 5ea8877b03..4ec6cd4e74 100644 --- a/test/TesterInternal/StorageTests/HierarchicalKeyStoreTests.cs +++ b/test/TesterInternal/StorageTests/HierarchicalKeyStoreTests.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Globalization; using System.Linq; @@ -6,7 +6,6 @@ using Orleans.Runtime.Configuration; using Orleans.Storage; using Xunit; -using Microsoft.Extensions.Options; using Orleans.Hosting; namespace UnitTests.StorageTests @@ -17,7 +16,7 @@ public class Fixture { public Fixture() { - BufferPool.InitGlobalBufferPool(Options.Create(new SiloMessagingOptions())); + BufferPool.InitGlobalBufferPool(new SiloMessagingOptions()); ClientConfiguration cfg = ClientConfiguration.LoadFromFile("ClientConfigurationForTesting.xml"); } } diff --git a/test/TesterSQLUtils/MySqlRemindersTableTests.cs b/test/TesterSQLUtils/MySqlRemindersTableTests.cs index 6e96e49ec1..392ff4a181 100644 --- a/test/TesterSQLUtils/MySqlRemindersTableTests.cs +++ b/test/TesterSQLUtils/MySqlRemindersTableTests.cs @@ -30,7 +30,7 @@ private static LoggerFilterOptions CreateFilters() protected override IReminderTable CreateRemindersTable() { - return new SqlReminderTable(this.ClusterFixture.Services.GetRequiredService(), this.siloOptions); + return new SqlReminderTable(this.ClusterFixture.Services.GetRequiredService(), this.siloOptions, this.adoNetOptions, this.storageOptions); } protected override string GetAdoInvariant() diff --git a/test/TesterSQLUtils/PostgreSqlRemindersTableTests.cs b/test/TesterSQLUtils/PostgreSqlRemindersTableTests.cs index 43c5ed20b4..48e09c6578 100644 --- a/test/TesterSQLUtils/PostgreSqlRemindersTableTests.cs +++ b/test/TesterSQLUtils/PostgreSqlRemindersTableTests.cs @@ -1,4 +1,4 @@ -using System.Threading.Tasks; +using System.Threading.Tasks; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using Orleans; @@ -28,7 +28,7 @@ private static LoggerFilterOptions CreateFilters() protected override IReminderTable CreateRemindersTable() { - return new SqlReminderTable(this.ClusterFixture.Services.GetRequiredService(), this.siloOptions); + return new SqlReminderTable(this.ClusterFixture.Services.GetRequiredService(), this.siloOptions, this.adoNetOptions, this.storageOptions); } protected override string GetAdoInvariant() diff --git a/test/TesterSQLUtils/SqlServerRemindersTableTests.cs b/test/TesterSQLUtils/SqlServerRemindersTableTests.cs index b77def6eb8..8a8fcfa7b3 100644 --- a/test/TesterSQLUtils/SqlServerRemindersTableTests.cs +++ b/test/TesterSQLUtils/SqlServerRemindersTableTests.cs @@ -30,7 +30,7 @@ private static LoggerFilterOptions CreateFilters() protected override IReminderTable CreateRemindersTable() { - return new SqlReminderTable(this.ClusterFixture.Services.GetRequiredService(), this.siloOptions); + return new SqlReminderTable(this.ClusterFixture.Services.GetRequiredService(), this.siloOptions, this.adoNetOptions, this.storageOptions); } protected override string GetAdoInvariant() diff --git a/test/Versions/TestVersionGrains/VersionGrainsSiloBuilderfactory.cs b/test/Versions/TestVersionGrains/VersionGrainsSiloBuilderfactory.cs index f9ba68dce4..49a3a43225 100644 --- a/test/Versions/TestVersionGrains/VersionGrainsSiloBuilderfactory.cs +++ b/test/Versions/TestVersionGrains/VersionGrainsSiloBuilderfactory.cs @@ -1,5 +1,7 @@ -using Microsoft.Extensions.DependencyInjection; +using System; +using Microsoft.Extensions.DependencyInjection; using Orleans; +using Orleans.Runtime; using Orleans.Runtime.Placement; using UnitTests.GrainInterfaces; using Orleans.Hosting; @@ -12,9 +14,15 @@ public class VersionGrainsSiloBuilderConfigurator : ISiloBuilderConfigurator { public void Configure(ISiloHostBuilder hostBuilder) { - hostBuilder.ConfigureServices(services => - services.AddSingleton, VersionAwarePlacementDirector>()) + hostBuilder + .ConfigureServices(this.ConfigureServices) .ConfigureApplicationParts(parts => parts.AddFromAppDomain().AddFromApplicationBaseDirectory()); } + + private void ConfigureServices(IServiceCollection services) + { + services.AddSingletonNamedService(nameof(VersionAwarePlacementStrategy)); + services.AddSingletonKeyedService(typeof(VersionAwarePlacementStrategy)); + } } }