-
Notifications
You must be signed in to change notification settings - Fork 10.3k
[Blazor] Apply persistence api review feedback #31147
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
Conversation
javiercn
commented
Mar 23, 2021
- Renames
- Lifetime -> Infrastructure
- ComponentApplicationLifetime -> ComponentStatePersistenceManager
- ComponentApplicationState -> PersistentComponentState
- OnPersisting -> Subscription RegisterOnPersisting(Func callback)
- PersistState -> Persist
- IComponentApplicationStateStore -> IComponentPersistedStateStore
- Lifetime -> Infrastructure
- "Spanify" APIs
- Persist(string key, byte [] data) -> Persist(string key, Action<IBufferWriter> writer);
- TryTake(string key out byte[] data) -> TryTake(string key, out ReadOnlySequence data)
src/Components/Components/src/Lifetime/PersistentComponentState.cs
Outdated
Show resolved
Hide resolved
src/Components/Components/src/Lifetime/PersistingComponentStateSubscription.cs
Outdated
Show resolved
Hide resolved
src/Components/Components/src/Microsoft.AspNetCore.Components.csproj
Outdated
Show resolved
Hide resolved
src/Components/WebAssembly/Samples/HostedBlazorWebassemblyApp/Client/Pages/FetchData.razor
Show resolved
Hide resolved
src/Components/test/testassets/BasicTestApp/PreserveStateComponent.razor
Show resolved
Hide resolved
src/Components/Components/src/Lifetime/PersistentComponentState.cs
Outdated
Show resolved
Hide resolved
return JsonSerializer.SerializeToUtf8Bytes(state); | ||
// System.Text.Json doesn't support serializing ReadonlySequence<byte> so we need to buffer | ||
// the data with a memory pool here. We will change our serialization strategy in the future here | ||
// so that we can avoid this step. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We serialize the dictionary directly manually since System.Text.Json doesn't support serializing ReadOnlySequence.
We do the serialization using the lower level APIs so that we can avoid having to create an extra dictionary and hold on to pooled memory. The way it works is, if the data is already in a single segment (most of the cases) we write it. If it "fits" within the stack, we copy it to a continuous buffer and write it. Otherwise, we rent a buffer from the memorypool, copy it there, write the property and return the buffer to the pool.
cc @ReubenBond it occurs to me this is very similar to orleans state persistence. |
It's very likely we can provide a backend for circuits using Orleans. I have a conversation pending with @ReubenBond once I deep a bit more into the design for pausing and resuming circuits. |
src/Components/Components/src/Lifetime/ComponentStatePersistenceManager.cs
Outdated
Show resolved
Hide resolved
d5bb40d
to
350fc7f
Compare
I ended up "spanifying/pooling" things all the way to the top. Here is how the current implementation behaves for about 250K for payloads with about 250K of data.
Here are some other entries and entry sizes that I've tried out to test where things break:
Other improvements we could do here if we needed to are:
|
src/Mvc/perf/Microbenchmarks/Microsoft.AspNetCore.Mvc/PreserveComponentStateBenchmark.cs
Show resolved
Hide resolved
src/Mvc/perf/Microbenchmarks/Microsoft.AspNetCore.Mvc/PreserveComponentStateBenchmark.cs
Show resolved
Hide resolved
src/Components/Components/src/Infrastructure/ComponentStatePersistenceManager.cs
Outdated
Show resolved
Hide resolved
src/Components/Components/src/Infrastructure/ComponentStatePersistenceManager.cs
Outdated
Show resolved
Hide resolved
src/Components/Components/src/Infrastructure/ComponentStatePersistenceManager.cs
Outdated
Show resolved
Hide resolved
src/Components/Components/src/Infrastructure/ComponentStatePersistenceManager.cs
Outdated
Show resolved
Hide resolved
src/Components/Components/src/Infrastructure/ComponentStatePersistenceManager.cs
Show resolved
Hide resolved
src/Components/WebAssembly/Samples/HostedBlazorWebassemblyApp/Client/Pages/FetchData.razor
Outdated
Show resolved
Hide resolved
@javiercn The use of the pooled writers comes at some long-term cost because there's now a lot of action-at-a-distance to reason about, and substantial risk of problems if we have any bugs that might leak instances in certain error cases. I don't have a clear sense of what makes it necessarily the right way to organize it. Naively - and I know I'm probably wrong here - I would have guessed we'd just hold all the user-supplied objects in a dictionary, and then |
f171c56
to
945a4b5
Compare
945a4b5
to
a9f4f9c
Compare
src/Components/Components/test/Lifetime/ComponentApplicationLifetimeTest.cs
Show resolved
Hide resolved
05f26da
to
69cebf7
Compare
We don't want to force things to be json serializable (they can serialize/deserialize things however they see fit, we just provide convenient json overloads) and we don't want to encourage people allocating byte arrays when they are serializing things out. |
69cebf7
to
40da9e2
Compare
62453cf
to
37b85f4
Compare
/backport to release/6.0-rc1 |
Started backporting to release/6.0-rc1: https://github.com/dotnet/aspnetcore/actions/runs/1168142700 |
@javiercn backporting to release/6.0-rc1 failed, the patch most likely resulted in conflicts: $ git am --3way --ignore-whitespace --keep-non-patch changes.patch
Applying: Apply API review feedback
warning: Cannot merge binary files: src/Components/Web.JS/dist/Release/blazor.webview.js (HEAD vs. Apply API review feedback)
warning: Cannot merge binary files: src/Components/Web.JS/dist/Release/blazor.server.js (HEAD vs. Apply API review feedback)
Using index info to reconstruct a base tree...
M src/Components/Web.JS/dist/Release/blazor.server.js
M src/Components/Web.JS/dist/Release/blazor.webview.js
M src/Components/WebAssembly/WebAssembly/src/Hosting/WebAssemblyHostBuilder.cs
Falling back to patching base and 3-way merge...
Auto-merging src/Components/WebAssembly/WebAssembly/src/Hosting/WebAssemblyHostBuilder.cs
Auto-merging src/Components/Web.JS/dist/Release/blazor.webview.js
CONFLICT (content): Merge conflict in src/Components/Web.JS/dist/Release/blazor.webview.js
Auto-merging src/Components/Web.JS/dist/Release/blazor.server.js
CONFLICT (content): Merge conflict in src/Components/Web.JS/dist/Release/blazor.server.js
error: Failed to merge in the changes.
hint: Use 'git am --show-current-patch=diff' to see the failed patch
Patch failed at 0001 Apply API review feedback
When you have resolved this problem, run "git am --continue".
If you prefer to skip this patch, run "git am --skip" instead.
To restore the original branch and stop patching, run "git am --abort".
Error: The process '/usr/bin/git' failed with exit code 128 Please backport manually! |
using System.Threading.Tasks; | ||
using Microsoft.AspNetCore.Components.RenderTree; | ||
using Microsoft.Extensions.Logging; | ||
|
||
namespace Microsoft.AspNetCore.Components.Lifetime | ||
namespace Microsoft.AspNetCore.Components.Infrastructure |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this an existing namespace? Seems strange for something with public types in it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit
@@ -15,6 +15,7 @@ | |||
<Compile Include="$(ComponentsSharedSourceRoot)src\JsonSerializerOptionsProvider.cs" /> | |||
<Compile Include="$(SharedSourceRoot)LinkerFlags.cs" LinkBase="Shared" /> | |||
<Compile Include="$(SharedSourceRoot)QueryStringEnumerable.cs" LinkBase="Shared" /> | |||
<Compile Include="$(RepoRoot)src\Shared\Components\PooledByteBufferWritter.cs" LinkBase="Infrastructure" /> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why does this single file appear in three different pseudo-folders❔ Suggest using LinkBase="Shared"
everywhere
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The inconsistency here leads me to suggest we should fix before this is merged or back-ported
37b85f4
to
3a03893
Compare
We took a different path |