-
-
Notifications
You must be signed in to change notification settings - Fork 362
doc(OnlineSheet): improve performance #6605
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
Reviewer's GuideThis PR enhances the OnlineSheet sample by deferring mock data initialization after initial render, tightening dispatch matching, refactoring hosted service registrations, and consolidating contributor models and mock logic into the tutorial sample. Sequence diagram for deferred mock contributor dispatch after initial rendersequenceDiagram
participant OnlineSheet as OnlineSheet.razor.cs
participant MockOnlineContributor
participant DispatchService
OnlineSheet->>OnlineSheet: OnAfterRenderAsync(firstRender)
OnlineSheet->>OnlineSheet: await Task.Delay(5000)
OnlineSheet->>MockOnlineContributor: Trigger(DispatchService)
MockOnlineContributor->>DispatchService: Dispatch(DispatchEntry<Contributor>)
Class diagram for new Contributor and MockOnlineContributor classesclassDiagram
class Contributor {
string? Name
string? Avatar
string? Description
UniverSheetData? Data
}
class MockOnlineContributor {
+static void Trigger(IDispatchService<Contributor> dispatchService)
}
Contributor <|-- MockOnlineContributor: uses
File-Level Changes
Assessment against linked issues
Possibly linked issues
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
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.
Hey @ArgoZhang - I've reviewed your changes - here's some feedback:
- Avoid using a fixed Task.Delay in OnAfterRenderAsync—consider using an event-driven trigger or making the delay configurable so updates aren’t tied to an arbitrary timeout.
- The new pattern-matching check in Dispatch is concise but could be hard to follow; adding a named helper or comment might improve clarity and maintainability.
- You removed the hosted‐service registration for MockOnlineContributor but then rely on its static Trigger method—verify that your service configuration matches the new mock implementation across build configurations.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- Avoid using a fixed Task.Delay in OnAfterRenderAsync—consider using an event-driven trigger or making the delay configurable so updates aren’t tied to an arbitrary timeout.
- The new pattern-matching check in Dispatch is concise but could be hard to follow; adding a named helper or comment might improve clarity and maintainability.
- You removed the hosted‐service registration for MockOnlineContributor but then rely on its static Trigger method—verify that your service configuration matches the new mock implementation across build configurations.
## Individual Comments
### Comment 1
<location> `src/BootstrapBlazor.Server/Extensions/ServiceCollectionExtensions.cs:39` </location>
<code_context>
-#if !DEBUG
// 增加后台任务服务
services.AddTaskServices();
services.AddHostedService<ClearTempFilesService>();
- services.AddHostedService<MockOnlineContributor>();
</code_context>
<issue_to_address>
Consider replacing the open-generic AddTaskServices registration with explicit service registrations or a small factory to improve clarity and maintainability.
```suggestion
The call to `services.AddTaskServices()` is hiding an open‐generic/reflection‐based scan that can make it hard to see exactly which `IDispatchService<T>` implementations are wired up. You can simplify by registering each dispatch service explicitly (or with a tiny factory) while preserving all existing behavior. For example:
```csharp
// instead of: services.AddTaskServices();
services.AddScoped<IDispatchService<Order>, OrderDispatchService>();
services.AddScoped<IDispatchService<Invoice>, InvoiceDispatchService>();
services.AddScoped<IDispatchService<Customer>, CustomerDispatchService>();
// …repeat for each T…
```
Or, if you still want a single registration point, use a small factory delegate:
```csharp
services.AddSingleton<Func<Type, object>>(sp => serviceType =>
{
if (serviceType == typeof(IDispatchService<Order>))
return sp.GetRequiredService<OrderDispatchService>();
if (serviceType == typeof(IDispatchService<Invoice>))
return sp.GetRequiredService<InvoiceDispatchService>();
if (serviceType == typeof(IDispatchService<Customer>))
return sp.GetRequiredService<CustomerDispatchService>();
throw new KeyNotFoundException($"No dispatch service for {serviceType}");
});
```
This keeps the registrations explicit—no hidden assembly scans—and makes it obvious which dispatch services are available.
</issue_to_address>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
|
|
||
| #if !DEBUG | ||
| // 增加后台任务服务 | ||
| services.AddTaskServices(); |
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.
issue (complexity): Consider replacing the open-generic AddTaskServices registration with explicit service registrations or a small factory to improve clarity and maintainability.
| services.AddTaskServices(); | |
| The call to `services.AddTaskServices()` is hiding an open‐generic/reflection‐based scan that can make it hard to see exactly which `IDispatchService<T>` implementations are wired up. You can simplify by registering each dispatch service explicitly (or with a tiny factory) while preserving all existing behavior. For example: | |
| ```csharp | |
| // instead of: services.AddTaskServices(); | |
| services.AddScoped<IDispatchService<Order>, OrderDispatchService>(); | |
| services.AddScoped<IDispatchService<Invoice>, InvoiceDispatchService>(); | |
| services.AddScoped<IDispatchService<Customer>, CustomerDispatchService>(); | |
| // …repeat for each T… |
Or, if you still want a single registration point, use a small factory delegate:
services.AddSingleton<Func<Type, object>>(sp => serviceType =>
{
if (serviceType == typeof(IDispatchService<Order>))
return sp.GetRequiredService<OrderDispatchService>();
if (serviceType == typeof(IDispatchService<Invoice>))
return sp.GetRequiredService<InvoiceDispatchService>();
if (serviceType == typeof(IDispatchService<Customer>))
return sp.GetRequiredService<CustomerDispatchService>();
throw new KeyNotFoundException($"No dispatch service for {serviceType}");
});This keeps the registrations explicit—no hidden assembly scans—and makes it obvious which dispatch services are available.
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #6605 +/- ##
=========================================
Coverage 100.00% 100.00%
=========================================
Files 739 739
Lines 31669 31669
Branches 4458 4458
=========================================
Hits 31669 31669
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
Link issues
fixes #6604
Summary By Copilot
Regression?
Risk
Verification
Packaging changes reviewed?
☑️ Self Check before Merge
Summary by Sourcery
Improve OnlineSheet sample performance by deferring and scoping mock updates and removing unnecessary hosted service
Enhancements: