Skip to content

Commit

Permalink
Add example deserializing a more complex type
Browse files Browse the repository at this point in the history
The dictionary still requires a private setter, as the deserializer will not just invoke Add for each entry, unfortunately.
  • Loading branch information
kzu committed Aug 8, 2023
1 parent 66bd704 commit 6ecb693
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 13 deletions.
5 changes: 4 additions & 1 deletion src/CloudActors.CodeAnaysis/Diagnostics.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,10 @@ public static class Diagnostics
DiagnosticSeverity.Error,
isEnabledByDefault: true);

public static SymbolDisplayFormat FullName { get; } = new(SymbolDisplayGlobalNamespaceStyle.Omitted, SymbolDisplayTypeQualificationStyle.NameAndContainingTypesAndNamespaces);
public static SymbolDisplayFormat FullName { get; } = new(
typeQualificationStyle: SymbolDisplayTypeQualificationStyle.NameAndContainingTypesAndNamespaces,
genericsOptions: SymbolDisplayGenericsOptions.IncludeTypeParameters,
miscellaneousOptions: SymbolDisplayMiscellaneousOptions.ExpandNullable);

public static string ToFileName(this ITypeSymbol type) => type.ToDisplayString(FullName).Replace('+', '.');

Expand Down
8 changes: 4 additions & 4 deletions src/CloudActors.Streamstone/StreamstoneStorage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -54,13 +54,13 @@ public StreamstoneStorage(CloudStorageAccount storage, StreamstoneOptions? optio

public async Task ClearStateAsync<T>(string stateName, GrainId grainId, IGrainState<T> grainState)
{
var table = await GetTable<T>(storage, stateName);
var table = await GetTable(storage, stateName);
await table.ExecuteAsync(TableOperation.Delete(new TableEntity(table.Name, grainId.Key.ToString()!)));
}

public async Task ReadStateAsync<T>(string stateName, GrainId grainId, IGrainState<T> grainState)
{
var table = await GetTable<T>(storage, stateName);
var table = await GetTable(storage, stateName);
var rowId = grainId.Key.ToString();

if (grainState.State is IEventSourced state)
Expand Down Expand Up @@ -122,7 +122,7 @@ entity.Data is not string data ||

public async Task WriteStateAsync<T>(string stateName, GrainId grainId, IGrainState<T> grainState)
{
var table = await GetTable<T>(storage, stateName);
var table = await GetTable(storage, stateName);
var rowId = grainId.Key.ToString();
var type = typeof(T);
var asm = typeof(T).Assembly.GetName();
Expand Down Expand Up @@ -186,7 +186,7 @@ await Stream.WriteAsync(partition,
}
}

async Task<CloudTable> GetTable<T>(CloudStorageAccount storage, string name)
async Task<CloudTable> GetTable(CloudStorageAccount storage, string name)
{
var getTable = tables.GetOrAdd(name, async key =>
{
Expand Down
50 changes: 42 additions & 8 deletions src/Tests/StreamstoneTests.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Text.Json;
using System.Collections.Generic;
using System.Text.Json;
using System.Threading.Tasks;
using Devlooped.CloudActors;
using Microsoft.Azure.Cosmos.Table;
Expand All @@ -25,13 +26,7 @@ await CloudStorageAccount.DevelopmentStorageAccount
account.Withdraw(new Withdraw(50));
account.Close(new Close(CloseReason.Customer));

var storage = new StreamstoneStorage(CloudStorageAccount.DevelopmentStorageAccount, new StreamstoneOptions
{
JsonOptions = new JsonSerializerOptions(StreamstoneOptions.Default.JsonOptions)
{
//TypeInfoResolver =
}
});
var storage = new StreamstoneStorage(CloudStorageAccount.DevelopmentStorageAccount);
await storage.WriteStateAsync(nameof(Account), GrainId.Parse("account/1"), GrainState.Create(account));

var state = GrainState.Create<Account>(new Account("1"));
Expand All @@ -41,6 +36,45 @@ await CloudStorageAccount.DevelopmentStorageAccount
Assert.Equal(account.IsClosed, state.State.IsClosed);
Assert.Equal(account.Reason, state.State.Reason);
}

[Fact]
public async Task ReadWriteComplexObject()
{
await CloudStorageAccount.DevelopmentStorageAccount
.CreateCloudTableClient()
.GetTableReference("CloudActorWallet")
.DeleteIfExistsAsync();

var wallet = new Wallet("1");
wallet.AddFunds("USD", 100);
wallet.AddFunds("EUR", 50);
wallet.AddFunds("EUR", 25);

var storage = new StreamstoneStorage(CloudStorageAccount.DevelopmentStorageAccount);
await storage.WriteStateAsync("CloudActorWallet", GrainId.Parse("wallet/1"), GrainState.Create(wallet));

var state = GrainState.Create<Wallet>(new Wallet("1"));
await storage.ReadStateAsync("CloudActorWallet", GrainId.Parse("wallet/1"), state);

Assert.Equal(wallet.Funds, state.State.Funds);
}
}


[Actor("CloudActorWallet")]
public partial class Wallet(string id)
{
public string Id => id;

public Dictionary<string, decimal> Funds { get; private set; } = new();

public void AddFunds(string currency, decimal amount)
{
if (Funds.TryGetValue(currency, out var balance))
Funds[currency] = balance + amount;
else
Funds.Add(currency, amount);
}
}

static class GrainState
Expand Down

0 comments on commit 6ecb693

Please sign in to comment.