Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add TGrainState type constraints to document necessary system constraints - Resolves #1906 #1923

Merged
merged 17 commits into from
Oct 1, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
d4e20fe
Add TGrainState constraints to document clearly what is needed by fol…
normanhh3 Jul 8, 2016
874c9f3
Removed class constraint because it was overly broad
normanhh3 Jul 15, 2016
69e272f
Extended type interogation to determine the appropriate grain type fr…
normanhh3 Jul 15, 2016
b52fa3d
Created test case to verify support of struct-based grain state stora…
normanhh3 Jul 15, 2016
86501fe
Add TGrainState constraints to document clearly what is needed by fol…
normanhh3 Jul 8, 2016
117e405
Removed class constraint because it was overly broad
normanhh3 Jul 15, 2016
ba21211
Extended type interogation to determine the appropriate grain type fr…
normanhh3 Jul 15, 2016
0e865d5
Created test case to verify support of struct-based grain state stora…
normanhh3 Jul 15, 2016
a0f1c25
Merge branch '1906-GrainStateConstraint' of https://github.com/norman…
normanhh3 Aug 21, 2016
36974bc
Moved test grain to non-internal location
normanhh3 Aug 21, 2016
39b3d73
Switched to using ValueTypeTestData
normanhh3 Aug 21, 2016
8f878de
Moved test to new location and refactored to use non-internal methods
normanhh3 Aug 21, 2016
961ecdd
Add TGrainState constraints to document clearly what is needed by fol…
normanhh3 Jul 8, 2016
34a9f3f
Created test case to verify support of struct-based grain state stora…
normanhh3 Jul 15, 2016
fd29e2e
Removed unused grain classes that were failing to compile.
sergeybykov Sep 30, 2016
19d672b
Fixed MemoryStore provider name.
sergeybykov Sep 30, 2016
538167f
Pulled from rebase by sergeybykov to correct issues
normanhh3 Oct 1, 2016
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/Orleans/Core/Grain.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using System.Threading.Tasks;
using Orleans.Core;
using Orleans.Runtime;
using Orleans.Storage;
using Orleans.Streams;

namespace Orleans
Expand Down Expand Up @@ -247,7 +248,7 @@ internal string CaptureRuntimeEnvironment()
/// Base class for a Grain with declared persistent state.
/// </summary>
/// <typeparam name="TGrainState">The class of the persistent state object</typeparam>
public class Grain<TGrainState> : Grain, IStatefulGrain
public class Grain<TGrainState> : Grain, IStatefulGrain where TGrainState : new()
{
private readonly GrainState<TGrainState> grainState;

Expand Down
2 changes: 1 addition & 1 deletion src/OrleansEventSourcing/JournaledGrain.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ namespace Orleans.EventSourcing
/// The base class for all grain classes that have event-sourced state.
/// </summary>
public class JournaledGrain<TGrainState> : Grain<TGrainState>
where TGrainState : JournaledGrainState<TGrainState>
where TGrainState : JournaledGrainState<TGrainState>, new()
{
/// <summary>
/// Helper method for raising events, applying them to TGrainState and optionally committing to storage
Expand Down
2 changes: 1 addition & 1 deletion src/OrleansEventSourcing/JournaledGrainState.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ namespace Orleans.EventSourcing
/// Base class for event-sourced grain state classes.
/// </summary>
public abstract class JournaledGrainState<TGrainState>
where TGrainState : JournaledGrainState<TGrainState>
where TGrainState : JournaledGrainState<TGrainState>, new()
{
private List<object> events = new List<object>();
protected TGrainState State;
Expand Down
2 changes: 1 addition & 1 deletion src/OrleansRuntime/GrainTypeManager/SiloAssemblyLoader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ public IDictionary<string, GrainTypeData> GetGrainClassTypes(bool strict)
if (definition == typeof(Grain<>))
{
var stateArg = parentType.GetGenericArguments()[0];
if (stateArg.GetTypeInfo().IsClass)
if (stateArg.GetTypeInfo().IsClass || stateArg.GetTypeInfo().IsValueType)
{
grainStateType = stateArg;
break;
Expand Down
4 changes: 1 addition & 3 deletions test/TestGrainInterfaces/IValueTypeTestGrain.cs
Original file line number Diff line number Diff line change
Expand Up @@ -122,13 +122,11 @@ public void SetT(T t)
}
}

public interface IValueTypeTestGrain : IGrainWithIntegerKey
public interface IValueTypeTestGrain : IGrainWithGuidKey
{
Task<ValueTypeTestData> GetStateData();

Task SetStateData(ValueTypeTestData d);

Task<CampaignEnemyTestType> GetEnemyType();
}

public interface IEnumResultGrain : IGrainWithIntegerKey
Expand Down
29 changes: 6 additions & 23 deletions test/TestGrains/ValueTypeTestGrain.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,40 +4,23 @@

namespace UnitTests.Grains
{
public class ValueTypeTestGrainState
{
public ValueTypeTestData StateData { get; set; }
}

[Orleans.Providers.StorageProvider(ProviderName = "MemoryStore")]
public class ValueTypeTestGrain : Grain<ValueTypeTestGrainState>, IValueTypeTestGrain
public class ValueTypeTestGrain : Grain<ValueTypeTestData>, IValueTypeTestGrain
{
public ValueTypeTestGrain()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This class ValueTypeTestGrainState is no longer needed. This used to inherit from GrainState, but that's no longer needed, and for some reason that inheritance was removed at the same time the file was moved (hmmm), so that's why diffing it was hard and the change was missed.

{
State.StateData = new ValueTypeTestData(7);
}

public Task SetState(ValueTypeTestData d)
{
State.StateData = d;
return TaskDone.Done;
}

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wow, I see that we had dead code there for testing structs. If possible, instead of using an int64 as you are now, I would use ValueTypeTestData (because sometimes there are optimizations being done for primitive types).

Also, you probably don't need to move the implementation to TesterInternal. From what I understand, these tests are not using anything that requires access to the internals (not public exposed) members of Orleans, correct?

public Task<CampaignEnemyTestType> GetEnemyType()
public async Task<ValueTypeTestData> GetStateData()
{
return Task.FromResult(CampaignEnemyTestType.Enemy2);
await ReadStateAsync();
return State;
}

public Task<ValueTypeTestData> GetStateData()
{
return Task.FromResult(State.StateData);
}


public Task SetStateData(ValueTypeTestData d)
{
State.StateData = d;
return TaskDone.Done;
State = d;
return WriteStateAsync();
}
}
}
16 changes: 16 additions & 0 deletions test/Tester/GenericGrainTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -678,6 +678,22 @@ public async Task Generic_GrainWithTypeConstraints()
Assert.Equal(1, result);
}

[Fact, TestCategory("Functional"), TestCategory("Persistence")]
public async Task Generic_GrainWithValueTypeState()
{
Guid id = Guid.NewGuid();
var grain = GrainClient.GrainFactory.GetGrain<IValueTypeTestGrain>(id);

var initial = await grain.GetStateData();
Assert.Equal(new ValueTypeTestData(0), initial);

var expectedValue = new ValueTypeTestData(42);

await grain.SetStateData(expectedValue);

Assert.Equal(expectedValue, await grain.GetStateData());
}

[Fact(Skip = "https://github.com/dotnet/orleans/issues/1655 Casting from non-generic to generic interface fails with an obscure error message"), TestCategory("Functional"), TestCategory("Cast"), TestCategory("Generics")]
public async Task Generic_CastToGenericInterfaceAfterActivation()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,23 +18,16 @@ private interface ITestGrainWithIntegerKey: IGrainWithIntegerKey { }
private interface ITestGrainGenericWithIntegerKey<T>: IGrainWithIntegerKey { }
private class TestGrainWithIntegerKey: Grain, ITestGrainWithIntegerKey { }
private class TestGrainGenericWithIntegerKey<T>: Grain, ITestGrainGenericWithIntegerKey<T> { }
private class TestGrainStateWithIntegerKey<TState>: Grain<TState>, ITestGrainWithIntegerKey { }
private class TestGrainStateGenericWithIntegerKey<T, TState>: Grain<TState>, ITestGrainGenericWithIntegerKey<T> { }

private interface ITestGrainWithGuidKey: IGrainWithGuidKey { }
private interface ITestGrainGenericWithGuidKey<T>: IGrainWithGuidKey { }
private class TestGrainWithGuidKey: Grain, ITestGrainWithGuidKey { }
private class TestGrainGenericWithGuidKey<T>: Grain, ITestGrainGenericWithGuidKey<T> { }
private class TestGrainStateWithGuidKey<TState>: Grain<TState>, ITestGrainWithGuidKey { }
private class TestGrainStateGenericWithGuidKey<T, TState>: Grain<TState>, ITestGrainGenericWithGuidKey<T> { }

private interface ITestGrainWithStringKey: IGrainWithStringKey { }
private interface ITestGrainGenericWithStringKey<T>: IGrainWithStringKey { }
private class TestGrainWithStringKey: Grain, ITestGrainWithStringKey { }
private class TestGrainGenericWithStringKey<T>: Grain, ITestGrainGenericWithStringKey<T> { }
private class TestGrainStateWithStringKey<TState>: Grain<TState>, ITestGrainWithStringKey { }
private class TestGrainStateGenericWithStringKey<T, TState>: Grain<TState>, ITestGrainGenericWithStringKey<T> { }


private static Dictionary<Type, Func<Type, Type, Type>> GrainTypeSwitch { get; } = new Dictionary<Type, Func<Type, Type, Type>>
{
Expand Down