Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 3 additions & 1 deletion .github/workflows/build-master.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@ jobs:
- uses: Cysharp/Actions/.github/actions/checkout@main
- uses: Cysharp/Actions/.github/actions/setup-dotnet@main
- run: dotnet build -c Debug -p:DefineConstants=RUNNING_IN_CI
- run: dotnet pack ./src/LogicLooper/LogicLooper.csproj -c Debug --no-build -p:IncludeSymbols=true -p:SymbolPackageFormat=snupkg
- run: |
dotnet pack ./src/LogicLooper/LogicLooper.csproj -c Debug --no-build -p:IncludeSymbols=true -p:SymbolPackageFormat=snupkg
dotnet pack ./src/LogicLooper.Diagnostics/LogicLooper.Diagnostics.csproj -c Debug --no-build -p:IncludeSymbols=true -p:SymbolPackageFormat=snupkg
- run: dotnet test -c Debug --no-build
- uses: Cysharp/Actions/.github/actions/upload-artifact@main
with:
Expand Down
8 changes: 7 additions & 1 deletion LogicLooper.sln
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
.editorconfig = .editorconfig
.gitignore = .gitignore
.github\workflows\build-master.yaml = .github\workflows\build-master.yaml
.github\workflows\build-release.yml = .github\workflows\build-release.yml
.github\workflows\build-release.yaml = .github\workflows\build-release.yaml
Directory.Build.props = Directory.Build.props
README.ja.md = README.ja.md
README.md = README.md
Expand All @@ -22,6 +22,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Samples", "Samples", "{159E
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LoopHostingApp", "samples\LoopHostingApp\LoopHostingApp.csproj", "{6AFDB90D-8198-45F1-A963-425ED604E24F}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LogicLooper.Diagnostics", "src\LogicLooper.Diagnostics\LogicLooper.Diagnostics.csproj", "{731F91B3-8764-9802-0605-5886F1F0C090}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand All @@ -40,6 +42,10 @@ Global
{6AFDB90D-8198-45F1-A963-425ED604E24F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6AFDB90D-8198-45F1-A963-425ED604E24F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6AFDB90D-8198-45F1-A963-425ED604E24F}.Release|Any CPU.Build.0 = Release|Any CPU
{731F91B3-8764-9802-0605-5886F1F0C090}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{731F91B3-8764-9802-0605-5886F1F0C090}.Debug|Any CPU.Build.0 = Debug|Any CPU
{731F91B3-8764-9802-0605-5886F1F0C090}.Release|Any CPU.ActiveCfg = Release|Any CPU
{731F91B3-8764-9802-0605-5886F1F0C090}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down
22 changes: 22 additions & 0 deletions README.ja.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ await looper.RegisterActionAsync((in LogicLooperActionContext ctx) =>
- [一つのループ](#%E4%B8%80%E3%81%A4%E3%81%AE%E3%83%AB%E3%83%BC%E3%83%97)
- [LooperPool を使用した複数の Looper](#looperpool-%E3%82%92%E4%BD%BF%E7%94%A8%E3%81%97%E3%81%9F%E8%A4%87%E6%95%B0%E3%81%AE-looper)
- [Microsoft.Extensions.Hosting との統合](#microsoftextensionshosting-%E3%81%A8%E3%81%AE%E7%B5%B1%E5%90%88)
- [メトリクス](#%E3%83%A1%E3%83%88%E3%83%AA%E3%82%AF%E3%82%B9)
- [上級編](#%E4%B8%8A%E7%B4%9A%E7%B7%A8)
- [ユニットテスト / フレーム単位実行](#%E3%83%A6%E3%83%8B%E3%83%83%E3%83%88%E3%83%86%E3%82%B9%E3%83%88--%E3%83%95%E3%83%AC%E3%83%BC%E3%83%A0%E5%8D%98%E4%BD%8D%E5%AE%9F%E8%A1%8C)
- [Coroutine](#coroutine)
Expand Down Expand Up @@ -112,6 +113,27 @@ await looperPool.RegisterActionAsync((in LogicLooperActionContext ctx) =>
### Microsoft.Extensions.Hosting との統合
[samples/LoopHostingApp](samples/LoopHostingApp) をご覧ください。`IHostedService` と組み合わせることでサーバーのライフサイクルなどを考慮した実装を行えます。

### メトリクス

LogicLooper は Metric API を使用してメトリクスを提供します。これにより LogicLooper や登録されているアクションの数、ループ当たりの実行時間といったものを取得できます。

メトリクスの取得を有効化するには LogicLooper.Diagnostics パッケージをインストールして `AddLogicLooperMetrics` を呼び出します。

```csharp
services.AddLogicLooperMetrics();
```

|Instrumentation|Unit|Description|
|---|---|---|
|LogicLooper.shared_pool.loopers|`{looper}`|LogicLooperPool.Shared で稼働している LogicLooper インスタンスの数|
|LogicLooper.shared_pool.running_actions|`{action}`|LogicLooperPool.Shared で稼働している LogicLooper に登録されているアクションの数|
|LogicLooper.running_loopers|`{looper}`|プロセスで稼働している LogicLooper インスタンスの数|
|LogicLooper.running_actions|`{action}`|プロセスで稼働している LogicLooper に登録されているアクションの数|
|LogicLooper.processing_duration_min|`ms`|プロセスで稼働しているループの1ループの実行時間 (最小)|
|LogicLooper.processing_duration_max|`ms`|プロセスで稼働しているループの1ループの実行時間 (最大)|
|LogicLooper.processing_duration_avg|`ms`|プロセスで稼働しているループの1ループの実行時間 (平均)|


## 上級編
### ユニットテスト / フレーム単位実行
LogicLooper と共にユニットテストを記述する場合やフレームを手動で更新したいような場合には `ManualLogicLooper` / `ManualLogicLooperPool` を利用できます。
Expand Down
22 changes: 22 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ await looper.RegisterActionAsync((in LogicLooperActionContext ctx) =>
- [Single-loop application](#single-loop-application)
- [Multiple-loop application using LooperPool](#multiple-loop-application-using-looperpool)
- [Integrate with Microsoft.Extensions.Hosting](#integrate-with-microsoftextensionshosting)
- [Metrics](#metrics)
- [Advanced](#advanced)
- [Unit tests / Frame-by-Frame execution](#unit-tests--frame-by-frame-execution)
- [Coroutine](#coroutine)
Expand Down Expand Up @@ -116,6 +117,27 @@ await looperPool.RegisterActionAsync((in LogicLooperActionContext ctx) =>
### Integrate with Microsoft.Extensions.Hosting
See [samples/LoopHostingApp](samples/LoopHostingApp).

### Metrics

LogicLooper provides metrics using the Metric API. This allows you to obtain the number of LogicLoopers and registered actions, as well as the execution time per loop.

To enable metrics collection, install the `LogicLooper.Diagnostics` package and call `AddLogicLooperMetrics`.

```csharp
services.AddLogicLooperMetrics();
```

|Instrumentation|Unit|Description|
|---|---|---|
|LogicLooper.shared_pool.loopers|`{looper}`|Number of LogicLooper instances running in LogicLooperPool.Shared|
|LogicLooper.shared_pool.running_actions|`{action}`|Number of actions registered in LogicLooperPool.Shared that are running in LogicLooper|
|LogicLooper.running_loopers|`{looper}`|Number of LogicLooper instances running in the process|
|LogicLooper.running_actions|`{action}`|Number of actions registered in LogicLooper that are running in the process|
|LogicLooper.processing_duration_min|`ms`|Minimum execution time of one loop in the process for LogicLooper|
|LogicLooper.processing_duration_max|`ms`|Maximum execution time of one loop in the process for LogicLooper|
|LogicLooper.processing_duration_avg|`ms`|Average execution time of one loop in the process for LogicLooper|


## Advanced
### Unit tests / Frame-by-Frame execution
If you want to write unit tests with LogicLooper or update frames manually, you can use `ManualLogicLooper` / `ManualLogicLooperPool`.
Expand Down
34 changes: 34 additions & 0 deletions src/LogicLooper.Diagnostics/LogicLooper.Diagnostics.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<RootNamespace>Cysharp.Threading</RootNamespace>
<AssemblyName>Cysharp.Threading.LogicLooper.Diagnostics</AssemblyName>
<SignAssembly>true</SignAssembly>
<AssemblyOriginatorKeyFile>..\LogicLooper\opensource.snk</AssemblyOriginatorKeyFile>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<NoWarn>$(NoWarn);1591</NoWarn>

<!-- NuGet Package information -->
<PackageId>LogicLooper.Diagnostics</PackageId>
<Description>Provides diagnostic and monitoring support for LogicLooper.</Description>
<IsPackable>true</IsPackable>
</PropertyGroup>

<ItemGroup>
<None Include="..\LogicLooper\Icon.png" Pack="true" PackagePath="/" />
<None Include="..\..\README.md" Pack="true" PackagePath="/" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Diagnostics" Version="9.0.8" />
<PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="9.0.8" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\LogicLooper\LogicLooper.csproj" />
</ItemGroup>

</Project>
20 changes: 20 additions & 0 deletions src/LogicLooper.Diagnostics/LogicLooperDiagnosticsExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
using System.Diagnostics.Metrics;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Cysharp.Threading.Diagnostics;

// ReSharper disable once CheckNamespace
namespace Microsoft.Extensions.DependencyInjection;

public static class LogicLooperDiagnosticsExtensions
{
/// <summary>
/// Adds services required for LogicLooper metrics to the specified service collection.
/// </summary>
public static IServiceCollection AddLogicLooperMetrics(this IServiceCollection services)
{
services.AddMetrics();
services.TryAddSingleton<LogicLooperMetrics>(x => new LogicLooperMetrics(x.GetRequiredService<IMeterFactory>()));
services.AddHostedService<LogicLooperMetricsInitializationHostedService>();
return services;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
using Microsoft.Extensions.Hosting;

// ReSharper disable once CheckNamespace
namespace Cysharp.Threading.Diagnostics;

#pragma warning disable CS9113 // Parameter is unread.
public class LogicLooperMetricsInitializationHostedService(LogicLooperMetrics metrics) : IHostedService
#pragma warning restore CS9113 // Parameter is unread.
{
public Task StartAsync(CancellationToken cancellationToken)
{
return Task.CompletedTask;
}

public Task StopAsync(CancellationToken cancellationToken)
{
return Task.CompletedTask;
}
}
Loading
Loading