Skip to content

Commit cd52a7e

Browse files
committed
big refactoring
1 parent c6b0d74 commit cd52a7e

File tree

49 files changed

+7162
-922
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+7162
-922
lines changed

AGENTS.md

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# Conversations
2+
any resulting updates to agents.md should go under the section "## Rules to follow"
3+
When you see a convincing argument from me on how to solve or do something. add a summary for this in agents.md. so you learn what I want over time.
4+
If I say any of the following point, you do this: add the context to agents.md, and associate this with a specific type of task.
5+
if I say "never do x" in some way.
6+
if I say "always do x" in some way.
7+
if I say "the process is x" in some way.
8+
If I tell you to remember something, you do the same, update
9+
10+
11+
## Rules to follow
12+
always check all test are passed.
13+
14+
# Repository Guidelines
15+
16+
## Project Structure & Module Organization
17+
The solution `ManagedCode.Communication.slnx` ties together the core library (`ManagedCode.Communication`), ASP.NET Core adapters, Orleans integrations, performance benchmarks, and the consolidated test suite (`ManagedCode.Communication.Tests`). Tests mirror the runtime namespaces—look for feature-specific folders such as `Results`, `Commands`, and `AspNetCore`—so keep new specs alongside the code they exercise. Shared assets live at the repository root (`README.md`, `logo.png`) and are packaged automatically through `Directory.Build.props`.
18+
19+
## Build, Test, and Development Commands
20+
- `dotnet restore ManagedCode.Communication.slnx` – restore all project dependencies.
21+
- `dotnet build -c Release ManagedCode.Communication.slnx` – compile every project with warnings treated as errors.
22+
- `dotnet test ManagedCode.Communication.Tests/ManagedCode.Communication.Tests.csproj` – run the xUnit suite; produces `*.trx` logs under `ManagedCode.Communication.Tests`.
23+
- `dotnet test ManagedCode.Communication.Tests/ManagedCode.Communication.Tests.csproj /p:CollectCoverage=true /p:CoverletOutputFormat=lcov` – refresh `coverage.info` via coverlet.
24+
- `dotnet run -c Release --project ManagedCode.Communication.Benchmark` – execute benchmark scenarios before performance-sensitive changes.
25+
26+
## Coding Style & Naming Conventions
27+
Formatting is driven by the root `.editorconfig`: spaces only, 4-space indent for C#, CRLF endings for code, braces on new lines, and explicit types except when the type is obvious. The repo builds with C# 13, nullable reference types enabled, and analyzers elevated to errors—leave no compiler warnings behind. Stick to domain-centric names (e.g., `ResultExtensionsTests`) and prefer PascalCase for members and const fields per the configured naming rules.
28+
29+
## Testing Guidelines
30+
All automated tests use xUnit with FluentAssertions and Microsoft test hosts; follow the existing spec style (`MethodUnderTest_WithScenario_ShouldOutcome`). New fixtures belong in the matching feature folder and should assert both success and failure branches for Result types. Maintain the default coverage settings supplied by `coverlet.collector`; update snapshots or helper builders under `TestHelpers` when shared setup changes.
31+
32+
## Commit & Pull Request Guidelines
33+
Commits in this repository stay short, imperative, and often reference the related issue or PR number (e.g., `Add FailBadRequest methods (#30)`). Mirror that tone, limit each commit to a coherent change, and include updates to docs or benchmarks when behavior shifts. Pull requests should summarize intent, list breaking changes, attach relevant `dotnet test` outputs or coverage deltas, and link tracked issues. Screenshots or sample payloads are welcome for HTTP-facing work.

CLAUDE_CODE_AGENTS.md

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
# Claude Code Agents for ManagedCode.Communication
2+
3+
This project includes specialized Claude Code agents for comprehensive code review and quality assurance.
4+
5+
## Available Agents
6+
7+
### 1. 🔍 Result Classes Reviewer (`result-classes-reviewer`)
8+
9+
**Specialization**: Expert analysis of Result pattern implementation
10+
**Focus Areas**:
11+
- Interface consistency between Result, Result<T>, CollectionResult<T>
12+
- JSON serialization attributes and patterns
13+
- Performance optimization opportunities
14+
- API design consistency
15+
16+
**Usage**: Invoke when making changes to core Result classes or interfaces
17+
18+
### 2. 🏗️ Architecture Reviewer (`architecture-reviewer`)
19+
20+
**Specialization**: High-level project structure and design patterns
21+
**Focus Areas**:
22+
- Project organization and dependency management
23+
- Design pattern implementation quality
24+
- Framework integration architecture
25+
- Scalability and maintainability assessment
26+
27+
**Usage**: Use for architectural decisions and major structural changes
28+
29+
### 3. 🛡️ Security & Performance Auditor (`security-performance-auditor`)
30+
31+
**Specialization**: Security vulnerabilities and performance bottlenecks
32+
**Focus Areas**:
33+
- Input validation and information disclosure risks
34+
- Memory allocation patterns and async best practices
35+
- Resource management and potential performance issues
36+
- Security antipatterns and vulnerabilities
37+
38+
**Usage**: Run before production releases and during security reviews
39+
40+
### 4. 🧪 Test Quality Analyst (`test-quality-analyst`)
41+
42+
**Specialization**: Test coverage and quality assessment
43+
**Focus Areas**:
44+
- Test coverage gaps and edge cases
45+
- Test design quality and maintainability
46+
- Integration test completeness
47+
- Testing strategy recommendations
48+
49+
**Usage**: Invoke when updating test suites or evaluating test quality
50+
51+
### 5. 🎯 API Design Reviewer (`api-design-reviewer`)
52+
53+
**Specialization**: Public API usability and developer experience
54+
**Focus Areas**:
55+
- API consistency and naming conventions
56+
- Developer experience and discoverability
57+
- Documentation quality and examples
58+
- Framework integration patterns
59+
60+
**Usage**: Use when designing new APIs or refactoring public interfaces
61+
62+
## How to Use the Agents
63+
64+
### Option 1: Via Task Tool (Recommended)
65+
```
66+
Task tool with subagent_type parameter - currently requires general-purpose agent as proxy
67+
```
68+
69+
### Option 2: Direct Invocation (Future)
70+
```
71+
Once Claude Code recognizes the agents, they can be invoked directly
72+
```
73+
74+
## Agent File Locations
75+
76+
All agents are stored in:
77+
```
78+
.claude/agents/
79+
├── result-classes-reviewer.md
80+
├── architecture-reviewer.md
81+
├── security-performance-auditor.md
82+
├── test-quality-analyst.md
83+
└── api-design-reviewer.md
84+
```
85+
86+
## Comprehensive Review Process
87+
88+
For a complete project audit, run agents in this order:
89+
90+
1. **Architecture Reviewer** - Get overall structural assessment
91+
2. **Result Classes Reviewer** - Focus on core library consistency
92+
3. **Security & Performance Auditor** - Identify security and performance issues
93+
4. **Test Quality Analyst** - Evaluate test coverage and quality
94+
5. **API Design Reviewer** - Review public API design and usability
95+
96+
## Recent Audit Findings Summary
97+
98+
### ✅ Major Strengths Identified
99+
- Excellent Result pattern implementation with proper type safety
100+
- Outstanding framework integration (ASP.NET Core, Orleans)
101+
- Strong performance characteristics using structs
102+
- RFC 7807 compliance and proper JSON serialization
103+
- Comprehensive railway-oriented programming support
104+
105+
### ⚠️ Areas for Improvement
106+
- Minor JSON property ordering inconsistencies
107+
- Some LINQ allocation hotspots in extension methods
108+
- Missing ConfigureAwait(false) in async operations
109+
- Information disclosure risks in exception handling
110+
- Test coverage gaps in edge cases
111+
112+
### 🚨 Critical Issues Addressed
113+
- Standardized interface hierarchy and removed redundant interfaces
114+
- Fixed missing JsonIgnore attributes
115+
- Improved logging infrastructure to avoid performance issues
116+
- Added proper IsValid properties across all Result types
117+
118+
## Contributing to Agent Development
119+
120+
When creating new agents:
121+
122+
1. Follow the established YAML frontmatter format
123+
2. Include specific tools requirements
124+
3. Provide clear focus areas and review processes
125+
4. Include specific examples and code patterns to look for
126+
5. Define clear deliverable formats
127+
128+
## Continuous Improvement
129+
130+
These agents should be updated as the project evolves:
131+
- Add new review criteria as patterns emerge
132+
- Update security checklist based on new threats
133+
- Enhance performance patterns as bottlenecks are identified
134+
- Expand API design guidelines based on user feedback
135+
136+
The agents represent institutional knowledge and should be maintained alongside the codebase.
Lines changed: 223 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,223 @@
1+
# Command Idempotency Store Improvements
2+
3+
## Overview
4+
5+
The `ICommandIdempotencyStore` interface and its implementations have been significantly improved to address concurrency issues, performance bottlenecks, and memory management concerns.
6+
7+
## Problems Solved
8+
9+
### ✅ 1. Race Conditions Fixed
10+
11+
**Problem**: Race conditions between checking status and setting status
12+
**Solution**: Added atomic operations
13+
14+
```csharp
15+
// NEW: Atomic compare-and-swap operations
16+
Task<bool> TrySetCommandStatusAsync(string commandId, CommandExecutionStatus expectedStatus, CommandExecutionStatus newStatus);
17+
Task<(CommandExecutionStatus currentStatus, bool wasSet)> GetAndSetStatusAsync(string commandId, CommandExecutionStatus newStatus);
18+
```
19+
20+
**Usage in Extensions**:
21+
```csharp
22+
// OLD: Race condition prone
23+
var status = await store.GetCommandStatusAsync(commandId);
24+
await store.SetCommandStatusAsync(commandId, CommandExecutionStatus.InProgress);
25+
26+
// NEW: Atomic operation
27+
var (currentStatus, wasSet) = await store.GetAndSetStatusAsync(commandId, CommandExecutionStatus.InProgress);
28+
```
29+
30+
### ✅ 2. Batch Operations Added
31+
32+
**Problem**: No batching support - each command processed separately
33+
**Solution**: Batch operations for better performance
34+
35+
```csharp
36+
// NEW: Batch operations
37+
Task<Dictionary<string, CommandExecutionStatus>> GetMultipleStatusAsync(IEnumerable<string> commandIds);
38+
Task<Dictionary<string, T?>> GetMultipleResultsAsync<T>(IEnumerable<string> commandIds);
39+
40+
// NEW: Batch execution extension
41+
Task<Dictionary<string, T>> ExecuteBatchIdempotentAsync<T>(
42+
IEnumerable<(string commandId, Func<Task<T>> operation)> operations);
43+
```
44+
45+
**Usage Example**:
46+
```csharp
47+
var operations = new[]
48+
{
49+
("cmd1", () => ProcessOrder1()),
50+
("cmd2", () => ProcessOrder2()),
51+
("cmd3", () => ProcessOrder3())
52+
};
53+
54+
var results = await store.ExecuteBatchIdempotentAsync(operations);
55+
```
56+
57+
### ✅ 3. Memory Leak Prevention
58+
59+
**Problem**: No automatic cleanup of old commands
60+
**Solution**: Comprehensive cleanup system
61+
62+
```csharp
63+
// NEW: Cleanup operations
64+
Task<int> CleanupExpiredCommandsAsync(TimeSpan maxAge);
65+
Task<int> CleanupCommandsByStatusAsync(CommandExecutionStatus status, TimeSpan maxAge);
66+
Task<Dictionary<CommandExecutionStatus, int>> GetCommandCountByStatusAsync();
67+
```
68+
69+
**Automatic Cleanup Service**:
70+
```csharp
71+
// NEW: Background cleanup service
72+
services.AddCommandIdempotency<InMemoryCommandIdempotencyStore>(options =>
73+
{
74+
options.CleanupInterval = TimeSpan.FromMinutes(10);
75+
options.CompletedCommandMaxAge = TimeSpan.FromHours(24);
76+
options.FailedCommandMaxAge = TimeSpan.FromHours(1);
77+
options.InProgressCommandMaxAge = TimeSpan.FromMinutes(30);
78+
});
79+
```
80+
81+
### ✅ 4. Simplified Implementation
82+
83+
**Problem**: Complex retry logic and polling
84+
**Solution**: Simplified with better defaults
85+
86+
```csharp
87+
// NEW: Improved retry with jitter
88+
public static async Task<T> ExecuteIdempotentWithRetryAsync<T>(
89+
this ICommandIdempotencyStore store,
90+
string commandId,
91+
Func<Task<T>> operation,
92+
int maxRetries = 3,
93+
TimeSpan? baseDelay = null)
94+
{
95+
// Exponential backoff with jitter to prevent thundering herd
96+
var delay = TimeSpan.FromMilliseconds(
97+
baseDelay.Value.TotalMilliseconds * Math.Pow(2, retryCount - 1) *
98+
(0.8 + Random.Shared.NextDouble() * 0.4)); // Jitter: 80%-120%
99+
}
100+
```
101+
102+
**Adaptive Polling**:
103+
```csharp
104+
// NEW: Adaptive polling - starts fast, slows down
105+
private static async Task<T> WaitForCompletionAsync<T>(...)
106+
{
107+
var pollInterval = TimeSpan.FromMilliseconds(10); // Start fast
108+
const int maxInterval = 1000; // Max 1 second
109+
110+
// Exponential backoff for polling
111+
pollInterval = TimeSpan.FromMilliseconds(
112+
Math.Min(pollInterval.TotalMilliseconds * 1.5, maxInterval));
113+
}
114+
```
115+
116+
## New Features
117+
118+
### 🎯 Health Monitoring
119+
120+
```csharp
121+
var metrics = await store.GetHealthMetricsAsync();
122+
Console.WriteLine($"Total: {metrics.TotalCommands}, Failed: {metrics.FailureRate:F1}%");
123+
```
124+
125+
### 🎯 Easy Service Registration
126+
127+
```csharp
128+
// Simple registration with automatic cleanup
129+
services.AddCommandIdempotency<InMemoryCommandIdempotencyStore>();
130+
131+
// Custom cleanup configuration
132+
services.AddCommandIdempotency<RedisCommandIdempotencyStore>(options =>
133+
{
134+
options.CompletedCommandMaxAge = TimeSpan.FromHours(48);
135+
options.LogHealthMetrics = true;
136+
});
137+
```
138+
139+
### 🎯 Orleans Integration Enhancements
140+
141+
The Orleans implementation now supports all new operations:
142+
- Atomic operations leveraging Orleans grain concurrency model
143+
- Batch operations using Task.WhenAll for parallel grain calls
144+
- Automatic cleanup (no-op since Orleans handles grain lifecycle)
145+
146+
## Performance Improvements
147+
148+
### Before:
149+
- Race conditions causing duplicate executions
150+
- Individual calls for each command check
151+
- No cleanup - memory grows indefinitely
152+
- 5-minute polling timeout (too long)
153+
- Fixed retry intervals causing thundering herd
154+
155+
### After:
156+
- ✅ Atomic operations prevent race conditions
157+
- ✅ Batch operations reduce round trips
158+
- ✅ Automatic cleanup prevents memory leaks
159+
- ✅ 30-second polling timeout (more reasonable)
160+
- ✅ Exponential backoff with jitter prevents thundering herd
161+
- ✅ Adaptive polling (starts fast, slows down)
162+
163+
## Breaking Changes
164+
165+
### ❌ None - Fully Backward Compatible
166+
167+
All existing code continues to work without changes. New features are additive.
168+
169+
## Usage Examples
170+
171+
### Basic Usage (Unchanged)
172+
```csharp
173+
var result = await store.ExecuteIdempotentAsync("cmd-123", async () =>
174+
{
175+
return await ProcessPayment();
176+
});
177+
```
178+
179+
### New Batch Processing
180+
```csharp
181+
var batchOperations = orders.Select(order =>
182+
(order.Id, () => ProcessOrder(order)));
183+
184+
var results = await store.ExecuteBatchIdempotentAsync(batchOperations);
185+
```
186+
187+
### Health Monitoring
188+
```csharp
189+
var metrics = await store.GetHealthMetricsAsync();
190+
if (metrics.StuckCommandsPercentage > 10)
191+
{
192+
logger.LogWarning("High percentage of stuck commands: {Percentage}%",
193+
metrics.StuckCommandsPercentage);
194+
}
195+
```
196+
197+
### Manual Cleanup
198+
```csharp
199+
// Clean up commands older than 1 hour
200+
var cleanedCount = await store.AutoCleanupAsync(
201+
completedCommandMaxAge: TimeSpan.FromHours(1),
202+
failedCommandMaxAge: TimeSpan.FromMinutes(30));
203+
```
204+
205+
## Recommendations
206+
207+
1. **Use automatic cleanup** for production deployments
208+
2. **Monitor health metrics** to detect issues early
209+
3. **Use batch operations** when processing multiple commands
210+
4. **Configure appropriate timeout values** based on your operations
211+
5. **Consider Orleans implementation** for distributed scenarios
212+
213+
## Migration Path
214+
215+
1.**No immediate action required** - everything works as before
216+
2.**Add cleanup service** when convenient:
217+
```csharp
218+
services.AddCommandIdempotency<YourStore>();
219+
```
220+
3.**Use batch operations** for new high-volume scenarios
221+
4.**Monitor health metrics** for operational insights
222+
223+
The improvements provide a production-ready, scalable command idempotency solution while maintaining full backward compatibility.

0 commit comments

Comments
 (0)