Skip to content

Conversation

@JerrettDavis
Copy link
Owner

@JerrettDavis JerrettDavis commented Dec 23, 2025

Add timeout enforcement, circuit breaker, metrics collection, and kill switch with individual focused documentation guides.

Add timeout enforcement, circuit breaker, metrics collection, and kill switch
with individual focused documentation guides. Fix test stability issues and
add complete XML documentation.

New Packages:
- ExperimentFramework.Resilience (Polly v8 circuit breaker)
- ExperimentFramework.Metrics.Exporters (Prometheus, OpenTelemetry)

Features:
- Timeout enforcement with FallbackToDefault action
- Circuit breaker integration using Polly v8 resilience pipelines
- Metrics collection with Prometheus and OpenTelemetry exporters
- Kill switch for manual experiment/trial shutdown
- In-memory and noop implementations for all providers

Core Implementation (15 new files):
- src/ExperimentFramework/Decorators/TimeoutDecoratorFactory.cs
- src/ExperimentFramework/KillSwitch/IKillSwitchProvider.cs
- src/ExperimentFramework/KillSwitch/KillSwitchDecoratorFactory.cs
- src/ExperimentFramework/Metrics/IExperimentMetrics.cs
- src/ExperimentFramework/Metrics/MetricsDecoratorFactory.cs
- src/ExperimentFramework/Models/TimeoutPolicy.cs
- src/ExperimentFramework/ExperimentBuilderExtensions.cs
- src/ExperimentFramework.Resilience/CircuitBreakerDecoratorFactory.cs
- src/ExperimentFramework.Resilience/CircuitBreakerOptions.cs
- src/ExperimentFramework.Resilience/ResilienceBuilderExtensions.cs
- src/ExperimentFramework.Resilience/ExperimentFramework.Resilience.csproj
- src/ExperimentFramework.Metrics.Exporters/PrometheusExperimentMetrics.cs
- src/ExperimentFramework.Metrics.Exporters/OpenTelemetryExperimentMetrics.cs
- src/ExperimentFramework.Metrics.Exporters/ExperimentFramework.Metrics.Exporters.csproj

Documentation (4 new guides):
- docs/user-guide/timeout-enforcement.md - Prevent slow trials with fallback
- docs/user-guide/circuit-breaker.md - Polly integration and configuration
- docs/user-guide/metrics.md - Prometheus/OpenTelemetry with Grafana queries
- docs/user-guide/kill-switch.md - Manual shutdown with admin API examples
- docs/user-guide/toc.yml - Updated table of contents

README Updates:
- Split monolithic enterprise section into 4 focused sections
- Add concise examples with links to detailed guides
- Update feature list with enterprise capabilities

Test Implementation (2 new files):
- tests/ExperimentFramework.Tests/EnterpriseFeatureTests.cs (17 tests)
- tests/ExperimentFramework.Tests/EnterpriseFeatureDebugTests.cs

Test Fixes:
- Fix flaky telemetry tests with [Collection("TelemetryTests")] attribute
- Add defensive null handling for timing-dependent activity capture
- Fix RuntimeExperimentProxy.cs async Task.FromResult method resolution
- Fix CircuitBreakerDecoratorFactory to use singleton decorator pattern
- Update TelemetryTests.cs and VariantAndTelemetryTests.cs

XML Documentation:
- Add missing docs to TimeoutDecoratorFactory (2 members)
- Add missing docs to IKillSwitchProvider implementations (15 members)
- Add missing docs to KillSwitchDecoratorFactory (4 members)
- Add missing docs to IExperimentMetrics (5 members)
- Add missing docs to MetricsDecoratorFactory (2 members)
- Resolve all 25 CS1591 warnings

Dependencies:
- Add Polly v9.0.0 to ExperimentFramework.Resilience
- Add System.Diagnostics.DiagnosticSource to Metrics.Exporters
- Remove unnecessary package reference (fix NU1510 warning)

Project Files:
- ExperimentFramework.slnx - Add new projects to solution
- tests/ExperimentFramework.Tests/ExperimentFramework.Tests.csproj
- tests/ExperimentFramework.Tests/packages.lock.json

Build Status:
- 0 warnings, 0 errors
- 174 tests passing (100% pass rate)
- All packages restore successfully
@codecov-commenter
Copy link

codecov-commenter commented Dec 23, 2025

Codecov Report

❌ Patch coverage is 85.06329% with 59 lines in your changes missing coverage. Please review.
⚠️ Please upload report for BASE (main@010cc22). Learn more about missing BASE report.

Files with missing lines Patch % Lines
...k.Metrics.Exporters/PrometheusExperimentMetrics.cs 73.37% 41 Missing ⚠️
src/ExperimentFramework/RuntimeExperimentProxy.cs 52.94% 8 Missing ⚠️
...etrics.Exporters/OpenTelemetryExperimentMetrics.cs 86.66% 2 Missing ⚠️
...ework.Resilience/CircuitBreakerDecoratorFactory.cs 96.22% 2 Missing ⚠️
...ramework.Resilience/ResilienceBuilderExtensions.cs 66.66% 2 Missing ⚠️
...erimentFramework/KillSwitch/IKillSwitchProvider.cs 95.12% 2 Missing ⚠️
...k.ComprehensiveSample/Demos/3_OpenTelemetryDemo.cs 0.00% 1 Missing ⚠️
...imentFramework.Resilience/CircuitBreakerOptions.cs 85.71% 1 Missing ⚠️
Additional details and impacted files
@@           Coverage Diff           @@
##             main       #2   +/-   ##
=======================================
  Coverage        ?   69.87%           
=======================================
  Files           ?       65           
  Lines           ?     1736           
  Branches        ?      145           
=======================================
  Hits            ?     1213           
  Misses          ?      523           
  Partials        ?        0           
Flag Coverage Δ
unittests 69.87% <85.06%> (?)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR adds comprehensive enterprise resilience features to the ExperimentFramework, including timeout enforcement, circuit breaker integration with Polly v8, metrics collection (Prometheus/OpenTelemetry), and kill switch functionality. The changes span 29 new files with focused documentation guides for each feature.

Key additions:

  • Four new resilience decorators with independent configuration
  • Two new packages: ExperimentFramework.Resilience and ExperimentFramework.Metrics.Exporters
  • Comprehensive user documentation with real-world examples

Reviewed changes

Copilot reviewed 28 out of 28 changed files in this pull request and generated 22 comments.

Show a summary per file
File Description
tests/ExperimentFramework.Tests/packages.lock.json Adds Polly 8.5.0 and new project dependencies
tests/ExperimentFramework.Tests/VariantAndTelemetryTests.cs Adds Collection attribute and defensive null checks for parallel test stability
tests/ExperimentFramework.Tests/TelemetryTests.cs Adds Collection attribute for test isolation
tests/ExperimentFramework.Tests/ExperimentFramework.Tests.csproj References new Resilience and Metrics.Exporters projects
tests/ExperimentFramework.Tests/EnterpriseFeatureTests.cs 17 new tests covering timeout, metrics, kill switch, and circuit breaker
tests/ExperimentFramework.Tests/EnterpriseFeatureDebugTests.cs Debug tests for isolating enterprise feature issues
src/ExperimentFramework/RuntimeExperimentProxy.cs Fixes Task.FromResult method resolution for async returns
src/ExperimentFramework/Models/TimeoutPolicy.cs New model defining timeout behavior and actions
src/ExperimentFramework/Metrics/MetricsDecoratorFactory.cs Decorator for collecting experiment performance metrics
src/ExperimentFramework/Metrics/IExperimentMetrics.cs Interface and noop implementation for metrics providers
src/ExperimentFramework/KillSwitch/KillSwitchDecoratorFactory.cs Decorator for emergency experiment/trial shutdown
src/ExperimentFramework/KillSwitch/IKillSwitchProvider.cs Interface and in-memory/noop implementations for kill switch
src/ExperimentFramework/ExperimentBuilderExtensions.cs Fluent API extensions for timeout, metrics, and kill switch
src/ExperimentFramework/Decorators/TimeoutDecoratorFactory.cs Decorator enforcing trial execution timeouts
src/ExperimentFramework.Resilience/ResilienceBuilderExtensions.cs Fluent API extensions for circuit breaker configuration
src/ExperimentFramework.Resilience/ExperimentFramework.Resilience.csproj New package project with Polly 8.5.0 dependency
src/ExperimentFramework.Resilience/CircuitBreakerOptions.cs Configuration options for circuit breaker behavior
src/ExperimentFramework.Resilience/CircuitBreakerDecoratorFactory.cs Polly-based circuit breaker decorator implementation
src/ExperimentFramework.Metrics.Exporters/PrometheusExperimentMetrics.cs In-memory Prometheus text format exporter
src/ExperimentFramework.Metrics.Exporters/OpenTelemetryExperimentMetrics.cs OpenTelemetry metrics integration using System.Diagnostics.Metrics
src/ExperimentFramework.Metrics.Exporters/ExperimentFramework.Metrics.Exporters.csproj New metrics exporters package project
docs/user-guide/toc.yml Adds four new documentation sections to table of contents
docs/user-guide/timeout-enforcement.md Comprehensive guide for timeout configuration with examples
docs/user-guide/metrics.md Guide for Prometheus/OpenTelemetry integration with Grafana queries
docs/user-guide/kill-switch.md Guide for manual experiment control including distributed Redis example
docs/user-guide/circuit-breaker.md Guide for Polly circuit breaker configuration and best practices
README.md Updates feature list and adds four new feature sections with examples
ExperimentFramework.slnx Registers new Resilience and Metrics.Exporters projects in solution

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

- Improved error handling in CircuitBreakerDecoratorFactory for better clarity.
- Updated experiment management endpoints to use a registry for allowed experiment types.
- Adjusted metrics to reflect changes in tagging for better tracking.
- Added smoke tests and unit tests for the new generator functionality.
Repository owner deleted a comment from Copilot AI Dec 24, 2025
@github-actions
Copy link

Code Coverage

Summary
  Generated on: 12/24/2025 - 05:27:16
  Coverage date: 12/24/2025 - 05:27:13
  Parser: Cobertura
  Assemblies: 6
  Classes: 120
  Files: 83
  Line coverage: 59.4%
  Covered lines: 1850
  Uncovered lines: 1262
  Coverable lines: 3112
  Total lines: 8162
  Branch coverage: 40.2% (377 of 936)
  Covered branches: 377
  Total branches: 936
  Method coverage: 81.2% (338 of 416)
  Full method coverage: 63.2% (263 of 416)
  Covered methods: 338
  Fully covered methods: 263
  Total methods: 416

ExperimentFramework                                                                          86.2%
  ExperimentFramework.Decorators.BenchmarkDecoratorFactory                                    100%
  ExperimentFramework.Decorators.DecoratorPipeline                                            100%
  ExperimentFramework.Decorators.ErrorLoggingDecoratorFactory                                 100%
  ExperimentFramework.Decorators.InvocationContext                                            100%
  ExperimentFramework.Decorators.TimeoutDecoratorFactory                                      100%
  ExperimentFramework.ExperimentBuilderExtensions                                             100%
  ExperimentFramework.ExperimentFrameworkBuilder                                              100%
  ExperimentFramework.ExperimentLoggingBuilder                                                100%
  ExperimentFramework.ExperimentRegistry                                                      100%
  ExperimentFramework.KillSwitch.ExperimentDisabledException                                  100%
  ExperimentFramework.KillSwitch.InMemoryKillSwitchProvider                                   100%
  ExperimentFramework.KillSwitch.KillSwitchDecoratorFactory                                   100%
  ExperimentFramework.KillSwitch.NoopKillSwitchProvider                                        75%
  ExperimentFramework.KillSwitch.TrialDisabledException                                       100%
  ExperimentFramework.Metrics.MetricsDecoratorFactory                                         100%
  ExperimentFramework.Metrics.NoopExperimentMetrics                                           100%
  ExperimentFramework.Models.ExperimentFrameworkConfiguration                                 100%
  ExperimentFramework.Models.ExperimentRegistration                                          88.8%
  ExperimentFramework.Models.ServiceExperimentDefinition<T>                                   100%
  ExperimentFramework.Models.TimeoutPolicy                                                    100%
  ExperimentFramework.Naming.DefaultExperimentNamingConvention                                100%
  ExperimentFramework.Naming.ExperimentSelectorName                                            50%
  ExperimentFramework.Routing.StickyTrialRouter                                               100%
  ExperimentFramework.RuntimeExperimentProxy<T>                                              64.4%
  ExperimentFramework.ServiceCollectionExtensions                                              96%
  ExperimentFramework.ServiceExperimentBuilder<T>                                            90.9%
  ExperimentFramework.Telemetry.NoopExperimentTelemetry                                       100%
  ExperimentFramework.Telemetry.OpenTelemetryExperimentTelemetry                              100%
  ExperimentFramework.Variants.VariantFeatureManagerAdapter                                  59.2%

ExperimentFramework.ComprehensiveSample                                                      58.9%
  ExperimentFramework.ComprehensiveSample.Decorators.CachingDecorator                        93.3%
  ExperimentFramework.ComprehensiveSample.Decorators.CachingDecoratorFactory                  100%
  ExperimentFramework.ComprehensiveSample.Decorators.CustomLoggingDecorator                  91.6%
  ExperimentFramework.ComprehensiveSample.Decorators.CustomLoggingDecoratorFactory            100%
  ExperimentFramework.ComprehensiveSample.Decorators.TimingDecorator                         91.6%
  ExperimentFramework.ComprehensiveSample.Decorators.TimingDecoratorFactory                   100%
  ExperimentFramework.ComprehensiveSample.Demos.CustomDecoratorDemo                             0%
  ExperimentFramework.ComprehensiveSample.Demos.ErrorPolicyDemo                                 0%
  ExperimentFramework.ComprehensiveSample.Demos.OpenTelemetryDemo                               0%
  ExperimentFramework.ComprehensiveSample.Demos.ReturnTypesDemo                                 0%
  ExperimentFramework.ComprehensiveSample.Demos.VariantFeatureDemo                              0%
  ExperimentFramework.ComprehensiveSample.ExperimentConfiguration                             100%
  ExperimentFramework.ComprehensiveSample.Services.Decorator.CacheDataService                   0%
  ExperimentFramework.ComprehensiveSample.Services.Decorator.DatabaseDataService              100%
  ExperimentFramework.ComprehensiveSample.Services.ErrorPolicy.CloudDatabaseImplementation    100%
  ExperimentFramework.ComprehensiveSample.Services.ErrorPolicy.DefaultImplementation          100%
  ExperimentFramework.ComprehensiveSample.Services.ErrorPolicy.ExperimentalImplementation       0%
  ExperimentFramework.ComprehensiveSample.Services.ErrorPolicy.InMemoryCacheImplementation    100%
  ExperimentFramework.ComprehensiveSample.Services.ErrorPolicy.LocalCacheImplementation       100%
  ExperimentFramework.ComprehensiveSample.Services.ErrorPolicy.NoopDiagnosticsHandler         100%
  ExperimentFramework.ComprehensiveSample.Services.ErrorPolicy.PrimaryImplementation          100%
  ExperimentFramework.ComprehensiveSample.Services.ErrorPolicy.PrimaryProvider                  0%
  ExperimentFramework.ComprehensiveSample.Services.ErrorPolicy.SecondaryImplementation          0%
  ExperimentFramework.ComprehensiveSample.Services.ErrorPolicy.SecondaryProvider                0%
  ExperimentFramework.ComprehensiveSample.Services.ErrorPolicy.StableImplementation           100%
  ExperimentFramework.ComprehensiveSample.Services.ErrorPolicy.StaticDataImplementation         0%
  ExperimentFramework.ComprehensiveSample.Services.ErrorPolicy.TertiaryProvider               100%
  ExperimentFramework.ComprehensiveSample.Services.ErrorPolicy.UnstableImplementation           0%
  ExperimentFramework.ComprehensiveSample.Services.ReturnTypes.TaskImplementationA              0%
  ExperimentFramework.ComprehensiveSample.Services.ReturnTypes.TaskImplementationB            100%
  ExperimentFramework.ComprehensiveSample.Services.ReturnTypes.TaskTImplementationA             0%
  ExperimentFramework.ComprehensiveSample.Services.ReturnTypes.TaskTImplementationB           100%
  ExperimentFramework.ComprehensiveSample.Services.ReturnTypes.ValueTaskImplementationA         0%
  ExperimentFramework.ComprehensiveSample.Services.ReturnTypes.ValueTaskImplementationB       100%
  ExperimentFramework.ComprehensiveSample.Services.ReturnTypes.ValueTaskTImplementationA      100%
  ExperimentFramework.ComprehensiveSample.Services.ReturnTypes.ValueTaskTImplementationB        0%
  ExperimentFramework.ComprehensiveSample.Services.ReturnTypes.VoidImplementationA              0%
  ExperimentFramework.ComprehensiveSample.Services.ReturnTypes.VoidImplementationB            100%
  ExperimentFramework.ComprehensiveSample.Services.Telemetry.EmailNotificationService         100%
  ExperimentFramework.ComprehensiveSample.Services.Telemetry.SmsNotificationService             0%
  ExperimentFramework.ComprehensiveSample.Services.Variant.PayPalPaymentProcessor               0%
  ExperimentFramework.ComprehensiveSample.Services.Variant.SquarePaymentProcessor               0%
  ExperimentFramework.ComprehensiveSample.Services.Variant.StripePaymentProcessor             100%
  ExperimentFramework.Generated.DataServiceExperimentProxy                                   71.1%
  ExperimentFramework.Generated.NotificationServiceExperimentProxy                           71.1%
  ExperimentFramework.Generated.PaymentProcessorExperimentProxy                              67.7%
  ExperimentFramework.Generated.RedirectAnyServiceExperimentProxy                            82.6%
  ExperimentFramework.Generated.RedirectDefaultServiceExperimentProxy                        71.1%
  ExperimentFramework.Generated.RedirectOrderedServiceExperimentProxy                        82.4%
  ExperimentFramework.Generated.RedirectSpecificServiceExperimentProxy                       78.8%
  ExperimentFramework.Generated.TaskServiceExperimentProxy                                     80%
  ExperimentFramework.Generated.TaskTServiceExperimentProxy                                    80%
  ExperimentFramework.Generated.ThrowPolicyServiceExperimentProxy                              72%
  ExperimentFramework.Generated.ValueTaskServiceExperimentProxy                                80%
  ExperimentFramework.Generated.ValueTaskTServiceExperimentProxy                               80%
  ExperimentFramework.Generated.VoidServiceExperimentProxy                                   78.5%
  Program                                                                                       0%

ExperimentFramework.Metrics.Exporters                                                        73.3%
  ExperimentFramework.Metrics.Exporters.OpenTelemetryExperimentMetrics                       86.6%
  ExperimentFramework.Metrics.Exporters.PrometheusExperimentMetrics                            72%

ExperimentFramework.Resilience                                                               89.3%
  ExperimentFramework.Resilience.CircuitBreakerDecoratorFactory                              92.3%
  ExperimentFramework.Resilience.CircuitBreakerOpenException                                  100%
  ExperimentFramework.Resilience.CircuitBreakerOptions                                       85.7%
  ExperimentFramework.Resilience.ResilienceBuilderExtensions                                 66.6%

ExperimentFramework.SampleConsole                                                            57.6%
  ExperimentFramework.Generated.MyDatabaseExperimentProxy                                      73%
  ExperimentFramework.Generated.MyTaxProviderExperimentProxy                                 83.6%
  ExperimentFramework.SampleConsole.Contexts.MyCloudDbContext                                 100%
  ExperimentFramework.SampleConsole.Contexts.MyDbContext                                      100%
  ExperimentFramework.SampleConsole.DemoWorker                                                  0%
  ExperimentFramework.SampleConsole.ExperimentConfiguration                                   100%
  ExperimentFramework.SampleConsole.Providers.DefaultTaxProvider                              100%
  ExperimentFramework.SampleConsole.Providers.OkTaxProvider                                   100%
  ExperimentFramework.SampleConsole.Providers.TxTaxProvider                                   100%
  Program                                                                                       0%

ExperimentFramework.SampleWebApp                                                               33%
  ExperimentFramework.Generated.CheckoutFlowExperimentProxy                                  71.4%
  ExperimentFramework.Generated.RecommendationEngineExperimentProxy                            76%
  ExperimentFramework.SampleWebApp.Controllers.CheckoutController                             100%
  ExperimentFramework.SampleWebApp.Controllers.CheckoutRequest                                100%
  ExperimentFramework.SampleWebApp.Controllers.RecommendationsController                     89.2%
  ExperimentFramework.SampleWebApp.ExperimentConfiguration                                    100%
  ExperimentFramework.SampleWebApp.Services.CheckoutInfo                                      100%
  ExperimentFramework.SampleWebApp.Services.CollaborativeRecommendationEngine                 100%
  ExperimentFramework.SampleWebApp.Services.ExpressCheckoutFlow                               100%
  ExperimentFramework.SampleWebApp.Services.MLRecommendationEngine                           11.1%
  ExperimentFramework.SampleWebApp.Services.OneClickCheckoutFlow                                0%
  ExperimentFramework.SampleWebApp.Services.PopularityRecommendationEngine                    100%
  ExperimentFramework.SampleWebApp.Services.ProductRecommendation                             100%
  ExperimentFramework.SampleWebApp.Services.SessionIdentityProvider                          62.5%
  ExperimentFramework.SampleWebApp.Services.StandardCheckoutFlow                              100%
  Microsoft.AspNetCore.OpenApi.Generated                                                      0.5%
  Program                                                                                     100%
  System.Runtime.CompilerServices                                                               0%

@JerrettDavis JerrettDavis merged commit 7721e95 into main Dec 24, 2025
5 of 6 checks passed
@JerrettDavis JerrettDavis deleted the feature/add-enterprise-features branch December 24, 2025 05:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants