Skip to content
Merged
Show file tree
Hide file tree
Changes from 9 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: 2 additions & 2 deletions .docfx/Dockerfile.docfx
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
ARG NGINX_VERSION=1.29.3-alpine
ARG NGINX_VERSION=1.29.4-alpine

FROM --platform=$BUILDPLATFORM nginx:${NGINX_VERSION} AS base
RUN rm -rf /usr/share/nginx/html/*

FROM --platform=$BUILDPLATFORM codebeltnet/docfx:2.78.3 AS build
FROM --platform=$BUILDPLATFORM codebeltnet/docfx:2.78.4 AS build

ADD [".", "docfx"]

Expand Down
8 changes: 4 additions & 4 deletions .docfx/docfx.json
Original file line number Diff line number Diff line change
Expand Up @@ -65,10 +65,10 @@
],
"build": {
"xref": [
"https://docs.cuemon.net/xrefmap.yml"
"https://docs.cuemon.net/xrefmap.yml",
"https://newtonsoft.codebelt.net/xrefmap.yml",
"https://github.com/dotnet/docfx/raw/main/.xrefmap.json"
],
"xrefService": [
"https://xref.docs.microsoft.com/query?uid={uid}" ],
"content": [
{
"files": [
Expand All @@ -92,7 +92,7 @@
],
"globalMetadata": {
"_appTitle": "Savvy I/O for .NET",
"_appFooter": "<span>Generated by <strong>DocFX</strong>. Copyright 2021-2025 Geekle. All rights reserved. Code with passion; love your work; deploy with confidence 👨‍💻️🔥❤️🚀😎</span>",
"_appFooter": "<span>Generated by <strong>DocFX</strong>. Copyright 2021-2026 Geekle. All rights reserved. Code with passion; love your work; deploy with confidence 👨‍💻️🔥❤️🚀😎</span>",
"_appLogoPath": "images/50x50.png",
"_appFaviconPath": "images/favicon.ico",
"_googleAnalyticsTagId": "G-KDPCBM5XNC",
Expand Down
585 changes: 477 additions & 108 deletions .github/copilot-instructions.md

Large diffs are not rendered by default.

164 changes: 164 additions & 0 deletions .github/prompts/benchmark.prompt.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
---
mode: agent
description: 'Writing Performance Benchmarks'
---

# Benchmark Fixture Prompt (Tuning Benchmarks)

This prompt defines how to generate performance tests (“benchmarks”) for a project/solution using BenchmarkDotNet.
Benchmarks are *not* unit tests — they are micro- or component-level performance measurements that belong under the `tuning/` directory and follow strict conventions.

Copilot must follow these guidelines when generating benchmark fixtures.

---

## 1. Naming and Placement

- All benchmark projects live under the `tuning/` folder.
Examples:
- `tuning/<ProjectName>.Benchmarks/`
- `tuning/<ProjectName>.Console.Benchmarks/`

- **Namespaces must NOT end with `.Benchmarks`.**
They must mirror the production assembly’s namespace.

Example:
If benchmarking a type inside `YourProject.Console`, then:

```csharp
namespace YourProject.Console
{
public class Sha512256Benchmark { … }
}
```

* **Benchmark class names must end with `Benchmark`.**
Example: `DateSpanBenchmark`, `FowlerNollVoBenchmark`.

* Benchmark files should be located in the matching benchmark project
(e.g., benchmarks for `YourProject.Console` go in `YourProject.Console.Benchmarks.csproj`).

* In the `.csproj` for each benchmark project, set the root namespace to the production namespace, for example:

```xml
<RootNamespace>YourProject.Console</RootNamespace>
```

---

## 2. Attributes and Configuration

Each benchmark class should use:

```csharp
[MemoryDiagnoser]
[GroupBenchmarksBy(BenchmarkLogicalGroupRule.ByCategory)]
```

Optional but strongly recommended where meaningful:

* `[Params(...)]` — define small, medium, large input sizes.
* `[GlobalSetup]` — deterministic initialization of benchmark data.
* `[Benchmark(Description = "...")]` — always add descriptions.
* `[Benchmark(Baseline = true)]` — when comparing two implementations.

Avoid complex global configs; prefer explicit attributes inside the class.

---

## 3. Structure and Best Practices

A benchmark fixture must:

* Measure a **single logical operation** per benchmark method.
* Avoid I/O, networking, disk access, logging, or side effects.
* Avoid expensive setup inside `[Benchmark]` methods.
* Use deterministic data (e.g., seeded RNG or predefined constants).
* Use `[GlobalSetup]` to allocate buffers, random payloads, or reusable test data only once.
* Avoid shared mutable state unless reset per iteration.

Use representative input sizes such as:

```csharp
[Params(8, 256, 4096)]
public int Count { get; set; }
```

BenchmarkDotNet will run each benchmark for each parameter value.

---

## 4. Method Naming Conventions

Use descriptive names that communicate intent:

* `Parse_Short`
* `Parse_Long`
* `ComputeHash_Small`
* `ComputeHash_Large`
* `Serialize_Optimized`
* `Serialize_Baseline`

When comparing approaches, always list them clearly and tag one as the baseline.

---

## 5. Example Benchmark Fixture

```csharp
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Configs;

namespace YourProject
{
[MemoryDiagnoser]
[GroupBenchmarksBy(BenchmarkLogicalGroupRule.ByCategory)]
public class SampleOperationBenchmark
{
[Params(8, 256, 4096)]
public int Count { get; set; }

private byte[] _payload;

[GlobalSetup]
public void Setup()
{
_payload = new byte[Count];
// deterministic initialization
}

[Benchmark(Baseline = true, Description = "Operation - baseline")]
public int Operation_Baseline() => SampleOperation.Process(_payload);

[Benchmark(Description = "Operation - optimized")]
public int Operation_Optimized() => SampleOperation.ProcessOptimized(_payload);
}
}
```

---

## 6. Reporting and CI

* Benchmark projects live exclusively under `tuning/`. They must not affect production builds.
* Heavy BenchmarkDotNet runs should *not* run in CI unless explicitly configured.
* Reports are produced by the benchmark runner and stored under the configured artifacts directory.

---

## 7. Additional Guidelines

* Keep benchmark fixtures focused and readable.
* Document non-obvious reasoning in short comments.
* Prefer realistic but deterministic data sets.
* When benchmarks reveal regressions or improvements, reference the associated PR or issue in a comment.
* Shared benchmark helpers belong in `tuning/` projects, not in production code.

---

## Final Notes

* Benchmarks are performance tests, not unit tests.
* Use `[Benchmark]` only for pure performance measurement.
* Avoid `MethodImplOptions.NoInlining` unless absolutely necessary.
* Use small sets of meaningful benchmark scenarios — avoid combinatorial explosion.
36 changes: 36 additions & 0 deletions .github/prompts/nuget.prompt.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
---
mode: agent
description: 'Prompt for populating PackageReleaseNotes.txt files under .nuget/**'
params:
version: '10.0.0'
---

Purpose: deterministic, low-analysis instructions so automated runs prepend a single, consistent release block.

Behavior (exact):
- For every file matching `.nuget/**/PackageReleaseNotes.txt`:
1. Read the file and find the first line that starts with `Availability:` (case-sensitive).
2. If found, capture the remainder of that line as `previous-tfm` and prepend the exact template shown below (substituting `{{version}}` and `{{previous-tfm}}`).
3. If not found within the first 3 lines, do nothing for that file.
4. Apply the template exactly as shown, preserving all whitespace and blank lines (including NBSP U+00A0 characters).
5. Save the file in-place - do not open PRs or create branches.
6. Continue to the next file until all matching files have been processed.
7. Do not assume that each file are the same - process each file independently.

Exact template to prepend (preserve whitespace and trailing NBSP U+00A0 on the blank lines):
```
Version {{version}}
Availability: {{previous-tfm}}

# ALM
- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs)

```
Notes:
- Do not attempt to infer versions or parse changelogs — use the provided `params.version` value.
- Keep edits minimal: only prepend the template block; preserve the rest of the file unchanged for human interference.
- DO NOT REMOVE THE ASCII 0xA0 NBSP CHARACTERS OR RUN ANY SORT OF TRIM on the blank lines in the template!
- DO NOT RUN ANY SORT OF GIT COMMANDS - once the files are saved, you are done.

Example run command (agent):
`run: /nuget version={{version}}`
Original file line number Diff line number Diff line change
@@ -1,12 +1,7 @@
name: Savvy I/O Pipeline
name: Savvy I/O CI Pipeline
on:
pull_request:
branches: [main]
paths-ignore:
- .codecov/**
- .docfx/**
- .nuget/**
- '**/*.md'
workflow_dispatch:
inputs:
configuration:
Expand Down Expand Up @@ -74,7 +69,7 @@ jobs:
strategy:
fail-fast: false
matrix:
os: [ubuntu-24.04, windows-2022]
os: [ubuntu-24.04, windows-2025, ubuntu-24.04-arm, windows-11-arm]
configuration: [Debug, Release]
project: ${{ fromJson(needs.prepare_test.outputs.json) }}
uses: codebeltnet/jobs-dotnet-test/.github/workflows/default.yml@v3
Expand All @@ -92,7 +87,7 @@ jobs:
strategy:
fail-fast: false
matrix:
os: [ubuntu-24.04, windows-2022]
os: [ubuntu-24.04, windows-2025]
configuration: [Release]
project: [ test/**/Savvyio.FunctionalTests.csproj, test/**/Savvyio.Extensions.SimpleQueueService.FunctionalTests.csproj, test/**/Savvyio.Extensions.QueueStorage.FunctionalTests.csproj ]
runs-on: ${{ matrix.os }}
Expand Down
36 changes: 35 additions & 1 deletion .nuget/Savvyio.App/PackageReleaseNotes.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,37 @@
Version 5.0.1
Availability: .NET 10 and .NET 9

# References
- Savvyio
- Savvyio.Commands
- Savvyio.Commands.Messaging
- Savvyio.Domain
- Savvyio.Domain.EventSourcing
- Savvyio.EventDriven
- Savvyio.EventDriven.Messaging
- Savvyio.Extensions.Dapper
- Savvyio.Extensions.DependencyInjection
- Savvyio.Extensions.DependencyInjection.Dapper
- Savvyio.Extensions.DependencyInjection.Domain
- Savvyio.Extensions.DependencyInjection.EFCore
- Savvyio.Extensions.DependencyInjection.EFCore.Domain
- Savvyio.Extensions.DependencyInjection.EFCore.Domain.EventSourcing
- Savvyio.Extensions.DependencyInjection.NATS
- Savvyio.Extensions.DependencyInjection.QueueStorage
- Savvyio.Extensions.DependencyInjection.RabbitMQ
- Savvyio.Extensions.DependencyInjection.SimpleQueueService
- Savvyio.Extensions.Dispatchers
- Savvyio.Extensions.EFCore
- Savvyio.Extensions.EFCore.Domain
- Savvyio.Extensions.EFCore.Domain.EventSourcing
- Savvyio.Extensions.NATS
- Savvyio.Extensions.QueueStorage
- Savvyio.Extensions.RabbitMQ
- Savvyio.Extensions.SimpleQueueService
- Savvyio.Extensions.Text.Json
- Savvyio.Messaging
- Savvyio.Queries

Version: 5.0.0
Availability: .NET 10 and .NET 9

Expand Down Expand Up @@ -385,4 +419,4 @@ Availability: .NET 9 and .NET 8
- Savvyio.Extensions.Text.Json
- Savvyio.Messaging
- Savvyio.Queries


8 changes: 7 additions & 1 deletion .nuget/Savvyio.Commands.Messaging/PackageReleaseNotes.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
Version 5.0.1
Availability: .NET 10 and .NET 9

# ALM
- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs)

Version: 5.0.0
Availability: .NET 10 and .NET 9

Expand Down Expand Up @@ -79,4 +85,4 @@ Availability: .NET 8 and .NET 6
# New Features
- ADDED CommandExtensions class in the Savvyio.Commands.Messaging namespace that consist of extension methods for the ICommand interface: ToMessage{T}
- ADDED InMemoryCommandQueue class in the Savvyio.Commands.Messaging namespace that provides an in-memory implementation of the IPointToPointChannel{TRequest} interface useful for unit testing and the likes thereof


8 changes: 7 additions & 1 deletion .nuget/Savvyio.Commands/PackageReleaseNotes.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
Version 5.0.1
Availability: .NET 10 and .NET 9

# ALM
- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs)

Version: 5.0.0
Availability: .NET 10 and .NET 9

Expand Down Expand Up @@ -131,4 +137,4 @@ Availability: .NET 7.0, .NET 6.0
- ADDED ICommandDispatcher interface in the Savvyio.Commands namespace that defines a Command dispatcher that uses Fire-and-Forget/In-Only MEP
- ADDED ICommandHandler interface in the Savvyio.Commands namespace that defines a handler responsible for objects that implements the ICommand interface
- ADDED SavvyioOptionsExtensions class in the Savvyio.Commands namespace that consist of extension methods for the SavvyioOptions class: AddCommandHandler, AddCommandDispatcher


8 changes: 7 additions & 1 deletion .nuget/Savvyio.Core/PackageReleaseNotes.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
Version 5.0.1
Availability: .NET 10 and .NET 9
Copy link

Copilot AI Jan 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is an extra space after the colon in "Availability: .NET 10" (two spaces instead of one). This appears consistently across all updated PackageReleaseNotes.txt files. For consistency with the existing format used in line 7 ("Availability: .NET 10"), line 2 should have only one space after the colon:

Availability: .NET 10 and .NET 9

This formatting inconsistency exists in all the updated release notes files.

Suggested change
Availability: .NET 10 and .NET 9
Availability: .NET 10 and .NET 9

Copilot uses AI. Check for mistakes.

# ALM
- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs)

Version: 5.0.0
Availability: .NET 10 and .NET 9

Expand Down Expand Up @@ -227,4 +233,4 @@ Availability: .NET 7.0, .NET 6.0
- ADDED IRequestReplyRegistry interface in the Savvyio.Handlers namespace that specifies a Request-Reply/In-Out MEP registry that store delegates responsible of handling type TRequest
- ADDED OrphanedHandlerException class in the Savvyio.Dispatchers namespace that provides the exception that is thrown when an IHandler{TRequest} implementation cannot be resolved
- ADDED RequestReplyRegistryExtensions class in the Savvyio.Handlers namespace that consist of extension methods for the IRequestReplyRegistry{TRequest} interface: RegisterAsync


8 changes: 7 additions & 1 deletion .nuget/Savvyio.Domain.EventSourcing/PackageReleaseNotes.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
Version 5.0.1
Availability: .NET 10 and .NET 9

# ALM
- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs)

Version: 5.0.0
Availability: .NET 10 and .NET 9

Expand Down Expand Up @@ -104,4 +110,4 @@ Availability: .NET 7.0, .NET 6.0
- ADDED TracedAggregateRoot class in the Savvyio.Domain.EventSourcing namespace that provides a way to cover the pattern of an Aggregate as specified in Domain Driven Design that is optimized for Event Sourcing
- ADDED TracedDomainEvent record in the Savvyio.Domain.EventSourcing namespace that provides a default implementation of something that happened in the domain that you want other parts of the same domain (in-process/inner-application) to be aware of
- ADDED TracedDomainEventExtensions class in the Savvyio.Domain.EventSourcing namespace that consist of extension methods for the ITracedDomainEvent interface: SetAggregateVersion, GetAggregateVersion, GetMemberType


8 changes: 7 additions & 1 deletion .nuget/Savvyio.Domain/PackageReleaseNotes.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
Version 5.0.1
Availability: .NET 10 and .NET 9

# ALM
- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs)

Version: 5.0.0
Availability: .NET 10 and .NET 9

Expand Down Expand Up @@ -130,4 +136,4 @@ Availability: .NET 7.0, .NET 6.0
- ADDED ITracedAggregateRepository interface in the Savvyio.Domain.EventSourcing namespace that defines a generic way of abstracting traced read- and writable repositories (CRud) that is optimized for Domain Driven Design
- ADDED ITracedAggregateRoot interface in the Savvyio.Domain.EventSourcing namespace that defines an Event Sourcing capable contract of an Aggregate as specified in Domain Driven Design
- ADDED ITracedDomainEvent interface in the Savvyio.Domain.EventSourcing namespace that specifies something that happened in the domain that you want other parts of the same domain (in-process/inner-application) to be aware of


Loading
Loading