dotnet / dotnet/orleans

Orleans Dashboard shows `IPersistentState<T>`-backed grain state as `{}`

Open
#10,237 2 comments 0 reactions 0 assignees View on GitHub
Dominant language
C#
Stars
10.9k
Forks
2.1k
Avg merge
13h 56m
Merged PRs (30d)
351

Description

## Summary

In a small Orleans sample app, Orleans Dashboard shows a grain’s state as `{}` even after the grain has been initialized and `WriteStateAsync()` has completed successfully.

## Expected behavior

After the grain is initialized, the dashboard should display the persisted state values.

## Actual behavior

The grain appears in Orleans Dashboard, but the displayed state remains `{}`.

## Repro setup

The app has:

- an Orleans silo with Orleans Dashboard enabled
- Redis-backed clustering
- Redis-backed grain storage
- a grain using `IPersistentState`
- an API endpoint that calls the grain’s `Initialize()` method

The grain looks like this:

```csharp
public class PlayerGrain : Grain, IPlayer
{
private readonly IPersistentState _playerState;

public PlayerGrain([PersistentState("player", "PlayerStore")] IPersistentState playerState)
{
_playerState = playerState;
}

public async Task Initialize(string name)
{
_playerState.State.Name = name;
await _playerState.WriteStateAsync();
}
}
```
`PlayerState` is a simple serializable type:

```csharp
[Serializable]
public class PlayerState
{
public string? Name { get; set; }
}
```

Dashboard is enabled in the silo host:

```csharp
builder.UseOrleans(orleans =>
{
orleans.AddDashboard();
});

app.MapOrleansDashboard("/");
```

## Steps to reproduce

1. Start the app.
2. Call the API endpoint that initializes `PlayerGrain`, for example with id `1` and a non-empty `Name`.
3. Open Orleans Dashboard.
4. Inspect the grain instance.

## Observed result

The grain is visible, but the state shown in the dashboard is:

```json
{}
```

## Additional notes

- The grain state is written via `WriteStateAsync()`.
- Exposing the state through a public `State` property did not change the dashboard output.
- This suggests either:
- Orleans Dashboard does not currently inspect `IPersistentState`-backed grain state as expected, or
- some additional configuration is required for dashboard state visualization.

## Question

Is this expected behavior for Orleans Dashboard with `IPersistentState`, or does this indicate a bug / missing configuration?

Contributor guide

Open the contributing guide

Research direction

Start by reproducing the sample flow through Initialize, WriteStateAsync(), AddDashboard(), and MapOrleansDashboard("/") with the Redis-backed setup. Trace how Orleans Dashboard inspects the grain instance and its IPersistentState; done means identifying the cause and making the persisted Name visible, or documenting the required configuration or limitation with a regression test if the repository provides one.

Written by the indexing model from the issue text.

Assessment

Tech stack
csharp, redis
Domain
distributed-systems, observability
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.