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

Commit

Permalink
Fix for UpdateIAmAlive in CosmosDBMembershipTable.cs (#51)
Browse files Browse the repository at this point in the history
* UpdateIAmAlive was throwing an exception as the MembershipEntry being passed in from Orleans only contained SiloAddress and IAmAliveTime. The code now reads the existing state from Cosmos Db, updates IAmAliveTime and writes it back. From what I can see, this is what UpdateIAmAlive.js used to do.

* Fix IAmAlive

Co-authored-by: Nick Barrett <[email protected]>
  • Loading branch information
ReubenBond and NickBarrett authored Jun 16, 2021
1 parent b75c91c commit 948ef97
Show file tree
Hide file tree
Showing 13 changed files with 70 additions and 74 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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/[email protected]
# - name: Start CosmosDB Emulator
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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}
Expand Down
10 changes: 6 additions & 4 deletions Orleans.CosmosDB.sln
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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
Expand All @@ -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
Expand Down
2 changes: 1 addition & 1 deletion global.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"sdk": {
"version": "3.1.100"
"version": "5.0.301"
}
}
37 changes: 34 additions & 3 deletions src/Orleans.Clustering.CosmosDB/CosmosDBMembershipTable.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ internal class CosmosDBMembershipTable : IMembershipTable

private CosmosClient _cosmos;
private Container _container;
private ItemResponse<SiloEntity> _selfRow;

public CosmosDBMembershipTable(ILoggerFactory loggerFactory, IOptions<ClusterOptions> clusterOptions, IOptions<CosmosDBClusteringOptions> clusteringOptions)
{
Expand Down Expand Up @@ -228,11 +229,41 @@ public async Task<MembershipTableData> 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<SiloEntity>(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<bool> UpdateRow(MembershipEntry entry, string etag, TableVersion tableVersion)
Expand Down
5 changes: 5 additions & 0 deletions src/Orleans.Persistence.CosmosDB/CosmosDBGrainStorage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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)
{
Expand Down Expand Up @@ -259,6 +262,7 @@ await ExecuteWithRetries(() => this._container.DeleteItemAsync<GrainStateEntity>
id, pk, requestOptions));

grainState.ETag = null;
grainState.RecordExists = false;
}
else
{
Expand All @@ -278,6 +282,7 @@ await ExecuteWithRetries(() => this._container.DeleteItemAsync<GrainStateEntity>
.ConfigureAwait(false);

grainState.ETag = response.Resource.ETag;
grainState.RecordExists = true;
}
}
catch (Exception exc)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
Expand Down Expand Up @@ -27,9 +27,9 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="Microsoft.Azure.Cosmos" Version="3.6.0" />
<PackageReference Include="Microsoft.Orleans.OrleansRuntime" Version="3.0.2" />
<PackageReference Include="System.Threading.Tasks.Extensions" Version="4.5.3" />
<PackageReference Include="Microsoft.Azure.Cosmos" Version="3.17.1" />
<PackageReference Include="Microsoft.Orleans.OrleansRuntime" Version="3.4.2" />
<PackageReference Include="System.Threading.Tasks.Extensions" Version="4.5.4" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="Microsoft.Azure.Cosmos" Version="3.6.0" />
<PackageReference Include="Microsoft.Orleans.OrleansRuntime" Version="3.0.2" />
<PackageReference Include="Microsoft.Azure.Cosmos" Version="3.17.1" />
<PackageReference Include="Microsoft.Orleans.OrleansRuntime" Version="3.4.2" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@
<ItemGroup>
<PackageReference Include="Microsoft.Azure.DocumentDB.Core" Version="2.9.1" />
<PackageReference Include="Microsoft.Orleans.OrleansProviders" Version="3.0.2" />
<PackageReference Include="System.Threading.Tasks.Extensions" Version="4.5.3" />
<PackageReference Include="System.Threading.Tasks.Extensions" Version="4.5.4" />
<PackageReference Include="Microsoft.Azure.DocumentDB.ChangeFeedProcessor" Version="2.2.8" />
<PackageReference Include="Microsoft.Orleans.OrleansRuntime" Version="3.0.2" />
<PackageReference Include="Microsoft.Orleans.OrleansRuntime" Version="3.4.2" />
<PackageReference Include="Microsoft.Orleans.CodeGenerator.MSBuild" Version="3.0.2" />
</ItemGroup>

Expand Down
22 changes: 1 addition & 21 deletions test/Orleans.CosmosDB.Tests/MBTTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,21 +16,8 @@ namespace Orleans.CosmosDB.Tests
/// <summary>
/// Tests for operation of Orleans Membership Table using Azure Cosmos DB
/// </summary>
public class MBTTests : MembershipTableTestsBase/*, IClassFixture<AzureStorageBasicTests>*/
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()
Expand All @@ -44,7 +31,6 @@ protected override IMembershipTable CreateMembershipTable(ILogger logger, string
new CosmosClientOptions { ConnectionMode = ConnectionMode.Gateway }
);

//TestUtils.CheckForAzureStorage();
var options = new CosmosDBClusteringOptions()
{
Client = dbClient,
Expand Down Expand Up @@ -80,12 +66,6 @@ protected override IGatewayListProvider CreateGatewayListProvider(ILogger logger
Options.Create(new GatewayOptions()));
}

protected override Task<string> GetConnectionString()
{
//TestUtils.CheckForAzureStorage();
return Task.FromResult("");
}

[Fact]
public async Task GetGateways()
{
Expand Down
24 changes: 2 additions & 22 deletions test/Orleans.CosmosDB.Tests/MembershipTableTestsBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,14 @@ internal static class SiloInstanceTableTestConstants
}

[Collection("Default")]
public abstract class MembershipTableTestsBase : IDisposable //, IClassFixture<ConnectionStringFixture>
public abstract class MembershipTableTestsBase : IDisposable
{
private static readonly string hostName = Dns.GetHostName();
private readonly ILogger logger = null;
private readonly IMembershipTable membershipTable;
private readonly IGatewayListProvider gatewayListProvider;
protected readonly string clusterId;
protected ILoggerFactory loggerFactory;
protected const string testDatabaseName = "OrleansMembershipTest";//for relational storage

private static string accountEndpoint;
private static string accountKey;
Expand All @@ -42,10 +41,8 @@ static MembershipTableTestsBase()
OrleansFixture.GetAccountInfo(out accountEndpoint, out accountKey);
}

protected MembershipTableTestsBase(/*ConnectionStringFixture fixture, TestEnvironmentFixture environment, */LoggerFilterOptions filters)
protected MembershipTableTestsBase()
{
//this.environment = environment;
//loggerFactory = TestingUtils.CreateDefaultLoggerFactory($"{this.GetType()}.log", filters);
var sp = new ServiceCollection().AddLogging(b => b.AddConsole()).BuildServiceProvider();
loggerFactory = sp.GetRequiredService<ILoggerFactory>();
logger = loggerFactory.CreateLogger(this.GetType().FullName);
Expand All @@ -54,40 +51,23 @@ 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();

gatewayListProvider = CreateGatewayListProvider(logger, accountEndpoint, accountKey);
gatewayListProvider.InitializeGatewayListProvider().WithTimeout(TimeSpan.FromMinutes(3)).Wait();
}

//public IGrainFactory GrainFactory => this.environment.GrainFactory;

//public IGrainReferenceConverter GrainReferenceConverter => this.environment.Services.GetRequiredService<IGrainReferenceConverter>();

//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<string> GetConnectionString();

protected virtual string GetAdoInvariant()
{
return null;
}

protected async Task MembershipTable_GetGateways()
{
Expand Down
19 changes: 11 additions & 8 deletions test/Orleans.CosmosDB.Tests/Orleans.CosmosDB.Tests.csproj
Original file line number Diff line number Diff line change
@@ -1,20 +1,23 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<TargetFramework>net5.0</TargetFramework>
<LangVersion>latest</LangVersion>
<IsPackable>false</IsPackable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.4.0" />
<PackageReference Include="Microsoft.Orleans.CodeGenerator.MSBuild" Version="3.0.2" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="3.1.1" />
<PackageReference Include="Microsoft.Orleans.Server" Version="3.0.2" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.2" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.10.0" />
<PackageReference Include="Microsoft.Orleans.CodeGenerator.MSBuild" Version="3.4.2" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="5.0.0" />
<PackageReference Include="Microsoft.Orleans.Server" Version="3.4.2" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
<PackageReference Include="System.Threading.Tasks.Extensions" Version="4.5.4" />
<PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.3">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>

<ItemGroup>
Expand Down
5 changes: 0 additions & 5 deletions test/Orleans.CosmosDB.Tests/PersistenceTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -188,9 +188,7 @@ public async Task ClearState()

var list = await grain.Read();


Assert.Empty(list);

}

[Fact]
Expand Down Expand Up @@ -220,9 +218,6 @@ public async Task ClearState_BeforeWrite()

var grain = this._fixture.Client.GetGrain<ITestCustomPartitionGrain>(guid);
await grain.ClearState();


}
}

}

0 comments on commit 948ef97

Please sign in to comment.