sqrtspace-dotnet/src/SqrtSpace.SpaceTime.AspNetCore/ServiceCollectionExtensions.cs
2025-07-20 03:41:39 -04:00

203 lines
6.5 KiB
C#

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Routing;
using Microsoft.Extensions.DependencyInjection;
using SqrtSpace.SpaceTime.Core;
using SqrtSpace.SpaceTime.Diagnostics;
namespace SqrtSpace.SpaceTime.AspNetCore;
/// <summary>
/// Extension methods for configuring SpaceTime services
/// </summary>
public static class ServiceCollectionExtensions
{
/// <summary>
/// Adds SpaceTime services to the service collection
/// </summary>
public static IServiceCollection AddSpaceTime(
this IServiceCollection services,
Action<SpaceTimeServiceOptions>? configureOptions = null)
{
var options = new SpaceTimeServiceOptions();
configureOptions?.Invoke(options);
// Register options
services.AddSingleton(options);
// Add checkpoint services if enabled
if (options.EnableCheckpointing)
{
services.AddSingleton(options.CheckpointOptions);
}
// Add streaming services if enabled
if (options.EnableStreaming)
{
services.AddSingleton(options.StreamingOptions);
}
return services;
}
/// <summary>
/// Adds SpaceTime middleware to the pipeline
/// </summary>
public static IApplicationBuilder UseSpaceTime(this IApplicationBuilder app)
{
var options = app.ApplicationServices.GetService<SpaceTimeServiceOptions>();
if (options == null)
{
throw new InvalidOperationException("SpaceTime services not registered. Call AddSpaceTime() in ConfigureServices.");
}
if (options.EnableCheckpointing)
{
var checkpointOptions = app.ApplicationServices.GetRequiredService<CheckpointOptions>();
app.UseMiddleware<CheckpointMiddleware>(checkpointOptions);
}
if (options.EnableStreaming)
{
var streamingOptions = app.ApplicationServices.GetRequiredService<ResponseStreamingOptions>();
app.UseMiddleware<ResponseStreamingMiddleware>(streamingOptions);
}
return app;
}
/// <summary>
/// Maps SpaceTime diagnostic and monitoring endpoints
/// </summary>
public static IApplicationBuilder UseSpaceTimeEndpoints(this IApplicationBuilder app)
{
app.UseEndpoints(endpoints =>
{
// Health check endpoint
endpoints.MapGet("/spacetime/health", async context =>
{
context.Response.StatusCode = 200;
await context.Response.WriteAsync("OK");
});
// Metrics endpoint (for Prometheus scraping)
endpoints.MapGet("/spacetime/metrics", async context =>
{
context.Response.ContentType = "text/plain";
await context.Response.WriteAsync("# SpaceTime metrics endpoint\n");
await context.Response.WriteAsync("# Configure OpenTelemetry with Prometheus exporter for metrics\n");
});
// Diagnostics report endpoint
endpoints.MapGet("/spacetime/diagnostics", async context =>
{
var diagnostics = context.RequestServices.GetService<ISpaceTimeDiagnostics>();
if (diagnostics != null)
{
var report = await diagnostics.GenerateReportAsync(TimeSpan.FromHours(1));
context.Response.ContentType = "application/json";
await context.Response.WriteAsJsonAsync(report);
}
else
{
context.Response.StatusCode = 404;
await context.Response.WriteAsync("Diagnostics not configured");
}
});
// Configuration endpoint
endpoints.MapGet("/spacetime/config", async context =>
{
var options = context.RequestServices.GetService<SpaceTimeServiceOptions>();
if (options != null)
{
context.Response.ContentType = "application/json";
await context.Response.WriteAsJsonAsync(options);
}
else
{
context.Response.StatusCode = 404;
await context.Response.WriteAsync("Configuration not found");
}
});
});
return app;
}
}
/// <summary>
/// Options for SpaceTime services
/// </summary>
public class SpaceTimeServiceOptions
{
/// <summary>
/// Enable checkpointing middleware
/// </summary>
public bool EnableCheckpointing { get; set; } = true;
/// <summary>
/// Enable streaming optimizations
/// </summary>
public bool EnableStreaming { get; set; } = true;
/// <summary>
/// Options for checkpointing
/// </summary>
public CheckpointOptions CheckpointOptions { get; set; } = new();
/// <summary>
/// Options for streaming
/// </summary>
public ResponseStreamingOptions StreamingOptions { get; set; } = new();
/// <summary>
/// Directory for storing checkpoints
/// </summary>
public string CheckpointDirectory { get; set; } = Path.Combine(Path.GetTempPath(), "spacetime-checkpoints");
/// <summary>
/// Checkpointing strategy to use
/// </summary>
public CheckpointStrategy CheckpointStrategy { get; set; } = CheckpointStrategy.SqrtN;
/// <summary>
/// Interval for checkpointing operations
/// </summary>
public TimeSpan CheckpointInterval { get; set; } = TimeSpan.FromSeconds(30);
/// <summary>
/// Directory for external storage operations
/// </summary>
public string ExternalStorageDirectory { get; set; } = Path.Combine(Path.GetTempPath(), "spacetime-storage");
/// <summary>
/// Default strategy for space-time operations
/// </summary>
public SpaceTimeStrategy DefaultStrategy { get; set; } = SpaceTimeStrategy.SqrtN;
/// <summary>
/// Default chunk size for streaming operations
/// </summary>
public int DefaultChunkSize { get; set; } = 1024;
/// <summary>
/// Buffer size for streaming operations
/// </summary>
public int StreamingBufferSize { get; set; } = 8192;
}
/// <summary>
/// Strategies for space-time tradeoffs
/// </summary>
public enum SpaceTimeStrategy
{
/// <summary>Use √n space strategy</summary>
SqrtN,
/// <summary>Use O(1) space strategy</summary>
Constant,
/// <summary>Use O(log n) space strategy</summary>
Logarithmic,
/// <summary>Use O(n) space strategy</summary>
Linear
}