Releases: ANcpLua/SWEN3.Paperless.RabbitMq
Releases · ANcpLua/SWEN3.Paperless.RabbitMq
v2.3.1 - Test Infrastructure Fixes
Test Infrastructure Fixes
SSE Test Hanging Issue Resolved
All SSE tests now use proper stream completion patterns, reducing test suite runtime from 11+ minutes to ~50 seconds.
Changes
- Refactored all SSE tests to use
FakeCompletableSseStreamwith.Complete() - Added
.AsTask().WaitAsync()pattern for read operations with timeouts - Fixed tests that were hanging due to never-ending SSE streams
Files Updated
| File | Pattern Applied |
|---|---|
SseExtensionsTests.cs |
FakeCompletableSseStream + .Complete() + .AsTask().WaitAsync() |
SseExtensionsFallbackTests.cs |
FakeCompletableSseStream + .Complete() |
SseExtensionsNet10Tests.cs |
FakeCompletableSseStream + .Complete() |
GenAIEventStreamIntegrationTests.cs |
FakeCompletableSseStream + .Complete() + .AsTask().WaitAsync() |
OcrEventStreamIntegrationTests.cs |
FakeCompletableSseStream + .Complete() + .AsTask().WaitAsync() |
Test Results
| Framework | Tests | Duration |
|---|---|---|
| net8.0 | 76 ✅ | 30s |
| net9.0 | 101 ✅ | 45s |
| net10.0 | 103 ✅ | 49s |
Breaking Changes
None - test infrastructure only.
v2.3.0 - SSE Infrastructure Improvements
SSE Infrastructure Improvements
1. Graceful Shutdown Support
ISseStream<T>now extendsIAsyncDisposableSseStream<T>completes all client channels on dispose- Prevents clients from hanging when host shuts down
2. Simplified Endpoint Registration
- New
MapSse<T>(pattern, eventTypeSelector)overload - Serializes entire event object as payload (no projection lambda needed)
- Uses camelCase JSON by default
3. Test Infrastructure
FakeCompletableSseStream<T>implementsIAsyncDisposableSseStreamTestsproperly disposes stream (fixes CA1001)
Summary Table
| Component | Change |
|---|---|
ISseStream<T> |
Added : IAsyncDisposable |
SseStream<T> |
Added _disposed flag, DisposeAsync(), ObjectDisposedException check |
SseExtensions |
Added MapSse<T>(pattern, eventTypeSelector) overload |
FakeCompletableSseStream<T> |
Implements IAsyncDisposable |
SseStreamTests |
Implements IAsyncDisposable |
Example Usage
// Before (v2.2.0) - always needed both lambdas
app.MapSse<NotificationEvent>("/api/notifications",
evt => new { evt.Id, evt.Message }, // payload projection
evt => evt.Type); // event type
// After (v2.3.0) - simplified when no projection needed
app.MapSse<NotificationEvent>("/api/notifications", evt => evt.Type);Breaking Changes
None - IAsyncDisposable is additive. Existing code works unchanged.
v2.2.0
What's New
OcrCommand Enhancement
- Added optional
CreatedAtparameter for document timestamp tracking - Fully backward compatible - existing code continues to work without changes
- New tests verify serialization and backward compatibility
Gemini Model Update
- Updated default model from
gemini-2.0-flash→gemini-2.5-flash - Updated documentation and examples
Backward Compatibility
| Scenario | Result |
|---|---|
Old code: new OcrCommand(id, name, path) |
✅ Works, CreatedAt = null |
Old JSON without createdAt |
✅ Deserializes, CreatedAt = null |
| New code with timestamp | ✅ Works |
New JSON with createdAt |
✅ Deserializes correctly |
Full Changelog
v2.0.0 - .NET 10 GA + Microsoft Resilience Integration
Breaking Changes
- Configuration section renamed:
GenAI:Gemini→Gemini - Removed
MaxRetriesproperty fromGeminiOptions(retry handling now managed byAddStandardResilienceHandler()) - Replaced Polly with Microsoft.Extensions.Http.Resilience
Changes
- Migrated to .NET 10 GA
- Added
AddPaperlessGenAI()extension method for one-line GenAI setup - Automatic retry with exponential backoff, circuit breaker, and timeout handling via
AddStandardResilienceHandler()
Migration
// Before (v1.0.4)
services.AddOptionsWithValidateOnStart<GeminiOptions>()
.BindConfiguration("GenAI:Gemini")
.ValidateDataAnnotations();
services.AddHttpClient<ITextSummarizer, GeminiService>();
services.AddHostedService<GenAIWorker>();
// After (v2.0.0)
services.AddPaperlessGenAI(configuration);See README for full migration guide.
v1.0.4 - GenAI Integration & Quality Improvements
What's New in v1.0.4
Features
-
GenAI integration: document summarization via Google Gemini API
GenAIWorkerbackground service for summarization commandsGeminiServicewith configurable retries and timeout handling- GenAI event streaming via Server-Sent Events (SSE)
- New message types:
GenAICommand,GenAIEvent
Dependencies
- NEW:
Polly8.6.3(retry policies) RabbitMQ.Client7.1.2.NET10.0 Preview 7
Configuration
Configure the Gemini API by either method.
Option 1: Environment variables (.env)
GENAI__GEMINI__APIKEY=API key from https://aistudio.google.com/app/apikey
GENAI__GEMINI__MODEL=gemini-2.0-flash
GENAI__GEMINI__MAXRETRIES=3
GENAI__GEMINI__TIMEOUTSECONDS=30Option 2: appsettings.json
{
"Gemini": {
"ApiKey": "your-api-key",
"Model": "gemini-2.0-flash",
"MaxRetries": 3,
"TimeoutSeconds": 30
}
}Note
Environment variables use double underscores (__) as hierarchy separators in .NET configuration.
Usage
// Event streaming
services.AddPaperlessRabbitMq(config, includeOcrResultStream: true, includeGenAiResultStream: true);
// Gemini Worker
services.AddPaperlessRabbitMq(configuration);
services.AddHttpClient<ITextSummarizer, GeminiService>();
services.AddHostedService<GenAIWorker>();Breaking Changes
None.
Contributors
v1.0.1 release
Released
Full Changelog: https://github.com/ANcpLua/SWEN3.Paperless.RabbitMq/commits/v1.0.1