diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index bc9254b..7a07155 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,7 +15,7 @@ jobs: - name: Setup .NET Core uses: actions/setup-dotnet@v1 with: - dotnet-version: 3.1.100 + dotnet-version: 5.0.301 # - name: Azure Cosmos Emulator # uses: galvesribeiro/AzureCosmosAction@v1.0.0 # - name: Start CosmosDB Emulator diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 5fa87b1..2304499 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -15,7 +15,7 @@ jobs: - name: Setup .NET Core uses: actions/setup-dotnet@v1 with: - dotnet-version: 3.1.100 + dotnet-version: 5.0.301 - name: Pack working-directory: src/Orleans.Clustering.CosmosDB run: dotnet pack --configuration Release -p:Version=${GITHUB_REF##*/v} diff --git a/Orleans.CosmosDB.sln b/Orleans.CosmosDB.sln index 245b8f1..846ed17 100644 --- a/Orleans.CosmosDB.sln +++ b/Orleans.CosmosDB.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 15 -VisualStudioVersion = 15.0.27130.2036 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.31320.298 MinimumVisualStudioVersion = 15.0.26124.0 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{12BE367B-569F-4C2E-AC15-876709C119D1}" EndProject @@ -12,7 +12,9 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution .editorconfig = .editorconfig .gitignore = .gitignore src\AssemblyInfo.cs = src\AssemblyInfo.cs - .circleci\config.yml = .circleci\config.yml + .github\workflows\ci.yml = .github\workflows\ci.yml + global.json = global.json + .github\workflows\publish.yml = .github\workflows\publish.yml README.md = README.md README.Nuget.md = README.Nuget.md EndProjectSection @@ -25,7 +27,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Orleans.Persistence.CosmosD EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Orleans.Reminders.CosmosDB", "src\Orleans.Reminders.CosmosDB\Orleans.Reminders.CosmosDB.csproj", "{E82D600B-2C44-4458-AB68-BCC25DE16631}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Orleans.Streaming.CosmosDB", "src\Orleans.Streaming.CosmosDB\Orleans.Streaming.CosmosDB.csproj", "{97AC434A-A072-44E4-B8F3-CCFD87A94F08}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Orleans.Streaming.CosmosDB", "src\Orleans.Streaming.CosmosDB\Orleans.Streaming.CosmosDB.csproj", "{97AC434A-A072-44E4-B8F3-CCFD87A94F08}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution diff --git a/global.json b/global.json index 0f27938..aa100ed 100644 --- a/global.json +++ b/global.json @@ -1,5 +1,5 @@ { "sdk": { - "version": "3.1.100" + "version": "5.0.301" } } \ No newline at end of file diff --git a/src/Orleans.Clustering.CosmosDB/CosmosDBMembershipTable.cs b/src/Orleans.Clustering.CosmosDB/CosmosDBMembershipTable.cs index feb7cbb..1b1b320 100755 --- a/src/Orleans.Clustering.CosmosDB/CosmosDBMembershipTable.cs +++ b/src/Orleans.Clustering.CosmosDB/CosmosDBMembershipTable.cs @@ -26,6 +26,7 @@ internal class CosmosDBMembershipTable : IMembershipTable private CosmosClient _cosmos; private Container _container; + private ItemResponse _selfRow; public CosmosDBMembershipTable(ILoggerFactory loggerFactory, IOptions clusterOptions, IOptions clusteringOptions) { @@ -228,11 +229,41 @@ public async Task ReadRow(SiloAddress key) } - public Task UpdateIAmAlive(MembershipEntry entry) + public async Task UpdateIAmAlive(MembershipEntry entry) { - var siloEntity = ConvertToEntity(entry, this._clusterOptions.ClusterId); + var siloEntityId = ConstructSiloEntityId(entry.SiloAddress); - return this._container.ReplaceItemAsync(siloEntity, siloEntity.Id, new PartitionKey(this._clusterOptions.ClusterId)); + if (this._selfRow is not { } selfRow) + { + var response = await this._container.ReadItemAsync(siloEntityId, new PartitionKey(this._clusterOptions.ClusterId)); + + if (response.StatusCode != HttpStatusCode.OK) + { + var message = $"Unable to query for SiloEntity {entry.ToFullString()}"; + this._logger.LogWarning((int)ErrorCode.MembershipBase, message); + throw new OrleansException(message); + } + + this._selfRow = selfRow = response; + } + + var siloEntity = selfRow.Resource; + siloEntity.IAmAliveTime = entry.IAmAliveTime; + + try + { + var replaceResponse = await this._container.ReplaceItemAsync( + siloEntity, + siloEntityId, + new PartitionKey(this._clusterOptions.ClusterId), + new ItemRequestOptions { IfMatchEtag = selfRow.ETag }); + this._selfRow = replaceResponse; + } + catch + { + this._selfRow = null; + throw; + } } public async Task UpdateRow(MembershipEntry entry, string etag, TableVersion tableVersion) diff --git a/src/Orleans.Persistence.CosmosDB/CosmosDBGrainStorage.cs b/src/Orleans.Persistence.CosmosDB/CosmosDBGrainStorage.cs index 4f24515..d4074a8 100755 --- a/src/Orleans.Persistence.CosmosDB/CosmosDBGrainStorage.cs +++ b/src/Orleans.Persistence.CosmosDB/CosmosDBGrainStorage.cs @@ -153,10 +153,12 @@ public async Task ReadStateAsync(string grainType, GrainReference grainReference if (doc.Resource.State != null) { grainState.State = JsonConvert.DeserializeObject(doc.Resource.State.ToString(), grainState.State.GetType(), this._options.JsonSerializerSettings); + grainState.RecordExists = true; } else { grainState.State = Activator.CreateInstance(grainState.State.GetType()); + grainState.RecordExists = true; } grainState.ETag = doc.Resource.ETag; @@ -224,6 +226,7 @@ public async Task WriteStateAsync(string grainType, GrainReference grainReferenc grainState.ETag = response.Resource.ETag; } + grainState.RecordExists = true; } catch (CosmosException dce) when (dce.StatusCode == HttpStatusCode.PreconditionFailed) { @@ -259,6 +262,7 @@ await ExecuteWithRetries(() => this._container.DeleteItemAsync id, pk, requestOptions)); grainState.ETag = null; + grainState.RecordExists = false; } else { @@ -278,6 +282,7 @@ await ExecuteWithRetries(() => this._container.DeleteItemAsync .ConfigureAwait(false); grainState.ETag = response.Resource.ETag; + grainState.RecordExists = true; } } catch (Exception exc) diff --git a/src/Orleans.Persistence.CosmosDB/Orleans.Persistence.CosmosDB.csproj b/src/Orleans.Persistence.CosmosDB/Orleans.Persistence.CosmosDB.csproj index 40dee65..ed11a7d 100755 --- a/src/Orleans.Persistence.CosmosDB/Orleans.Persistence.CosmosDB.csproj +++ b/src/Orleans.Persistence.CosmosDB/Orleans.Persistence.CosmosDB.csproj @@ -1,4 +1,4 @@ - + netstandard2.0 @@ -27,9 +27,9 @@ - - - + + + \ No newline at end of file diff --git a/src/Orleans.Reminders.CosmosDB/Orleans.Reminders.CosmosDB.csproj b/src/Orleans.Reminders.CosmosDB/Orleans.Reminders.CosmosDB.csproj index 6b4509b..29e5b9e 100755 --- a/src/Orleans.Reminders.CosmosDB/Orleans.Reminders.CosmosDB.csproj +++ b/src/Orleans.Reminders.CosmosDB/Orleans.Reminders.CosmosDB.csproj @@ -27,8 +27,8 @@ - - + + diff --git a/src/Orleans.Streaming.CosmosDB/Orleans.Streaming.CosmosDB.csproj b/src/Orleans.Streaming.CosmosDB/Orleans.Streaming.CosmosDB.csproj index fb1c1b5..96f5295 100644 --- a/src/Orleans.Streaming.CosmosDB/Orleans.Streaming.CosmosDB.csproj +++ b/src/Orleans.Streaming.CosmosDB/Orleans.Streaming.CosmosDB.csproj @@ -25,9 +25,9 @@ - + - + diff --git a/test/Orleans.CosmosDB.Tests/MBTTests.cs b/test/Orleans.CosmosDB.Tests/MBTTests.cs index e04531b..cae9cfe 100755 --- a/test/Orleans.CosmosDB.Tests/MBTTests.cs +++ b/test/Orleans.CosmosDB.Tests/MBTTests.cs @@ -16,21 +16,8 @@ namespace Orleans.CosmosDB.Tests /// /// Tests for operation of Orleans Membership Table using Azure Cosmos DB /// - public class MBTTests : MembershipTableTestsBase/*, IClassFixture*/ + public class MBTTests : MembershipTableTestsBase { - public MBTTests() : base(CreateFilters()) - { - } - - private static LoggerFilterOptions CreateFilters() - { - var filters = new LoggerFilterOptions(); - //filters.AddFilter(typeof(Orleans.Clustering.CosmosDB.AzureTableDataManager<>).FullName, LogLevel.Trace); - //filters.AddFilter(typeof(OrleansSiloInstanceManager).FullName, LogLevel.Trace); - //filters.AddFilter("Orleans.Storage", LogLevel.Trace); - return filters; - } - protected override IMembershipTable CreateMembershipTable(ILogger logger, string accountEndpoint, string accountKey) { var httpHandler = new HttpClientHandler() @@ -44,7 +31,6 @@ protected override IMembershipTable CreateMembershipTable(ILogger logger, string new CosmosClientOptions { ConnectionMode = ConnectionMode.Gateway } ); - //TestUtils.CheckForAzureStorage(); var options = new CosmosDBClusteringOptions() { Client = dbClient, @@ -80,12 +66,6 @@ protected override IGatewayListProvider CreateGatewayListProvider(ILogger logger Options.Create(new GatewayOptions())); } - protected override Task GetConnectionString() - { - //TestUtils.CheckForAzureStorage(); - return Task.FromResult(""); - } - [Fact] public async Task GetGateways() { diff --git a/test/Orleans.CosmosDB.Tests/MembershipTableTestsBase.cs b/test/Orleans.CosmosDB.Tests/MembershipTableTestsBase.cs index 46dea17..44d0150 100755 --- a/test/Orleans.CosmosDB.Tests/MembershipTableTestsBase.cs +++ b/test/Orleans.CosmosDB.Tests/MembershipTableTestsBase.cs @@ -24,7 +24,7 @@ internal static class SiloInstanceTableTestConstants } [Collection("Default")] - public abstract class MembershipTableTestsBase : IDisposable //, IClassFixture + public abstract class MembershipTableTestsBase : IDisposable { private static readonly string hostName = Dns.GetHostName(); private readonly ILogger logger = null; @@ -32,7 +32,6 @@ public abstract class MembershipTableTestsBase : IDisposable //, IClassFixture b.AddConsole()).BuildServiceProvider(); loggerFactory = sp.GetRequiredService(); logger = loggerFactory.CreateLogger(this.GetType().FullName); @@ -54,10 +51,6 @@ protected MembershipTableTestsBase(/*ConnectionStringFixture fixture, TestEnviro logger?.Info("ClusterId={0}", this.clusterId); - //fixture.InitializeConnectionStringAccessor(GetConnectionString); - //this.connectionString = fixture.ConnectionString; - var adoVariant = GetAdoInvariant(); - membershipTable = CreateMembershipTable(logger, accountEndpoint, accountKey); membershipTable.InitializeMembershipTable(true).WithTimeout(TimeSpan.FromMinutes(3)).Wait(); @@ -65,29 +58,16 @@ protected MembershipTableTestsBase(/*ConnectionStringFixture fixture, TestEnviro gatewayListProvider.InitializeGatewayListProvider().WithTimeout(TimeSpan.FromMinutes(3)).Wait(); } - //public IGrainFactory GrainFactory => this.environment.GrainFactory; - - //public IGrainReferenceConverter GrainReferenceConverter => this.environment.Services.GetRequiredService(); - - //public IServiceProvider Services => this.environment.Services; - public void Dispose() { if (membershipTable != null && SiloInstanceTableTestConstants.DeleteEntriesAfterTest) { membershipTable.DeleteMembershipTableEntries(this.clusterId).Wait(); } - //this.loggerFactory.Dispose(); } protected abstract IGatewayListProvider CreateGatewayListProvider(ILogger logger, string accountEndpoint, string accountKey); protected abstract IMembershipTable CreateMembershipTable(ILogger logger, string accountEndpoint, string accountKey); - protected abstract Task GetConnectionString(); - - protected virtual string GetAdoInvariant() - { - return null; - } protected async Task MembershipTable_GetGateways() { diff --git a/test/Orleans.CosmosDB.Tests/Orleans.CosmosDB.Tests.csproj b/test/Orleans.CosmosDB.Tests/Orleans.CosmosDB.Tests.csproj index 9241606..4cf79e1 100644 --- a/test/Orleans.CosmosDB.Tests/Orleans.CosmosDB.Tests.csproj +++ b/test/Orleans.CosmosDB.Tests/Orleans.CosmosDB.Tests.csproj @@ -1,20 +1,23 @@ - + - netcoreapp3.1 + net5.0 latest false - - - - - + + + + + - + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + diff --git a/test/Orleans.CosmosDB.Tests/PersistenceTests.cs b/test/Orleans.CosmosDB.Tests/PersistenceTests.cs index 2808172..07379fe 100755 --- a/test/Orleans.CosmosDB.Tests/PersistenceTests.cs +++ b/test/Orleans.CosmosDB.Tests/PersistenceTests.cs @@ -188,9 +188,7 @@ public async Task ClearState() var list = await grain.Read(); - Assert.Empty(list); - } [Fact] @@ -220,9 +218,6 @@ public async Task ClearState_BeforeWrite() var grain = this._fixture.Client.GetGrain(guid); await grain.ClearState(); - - } } - }