generated from fahricansecer/boilerplate-be
96 lines
3.4 KiB
C#
96 lines
3.4 KiB
C#
using Microsoft.Extensions.DependencyInjection;
|
||
using Microsoft.Extensions.Hosting;
|
||
using Polly;
|
||
using Polly.Extensions.Http;
|
||
using Serilog;
|
||
using SaasMediaWorker.Configuration;
|
||
using SaasMediaWorker.Services;
|
||
|
||
Log.Logger = new LoggerConfiguration()
|
||
.MinimumLevel.Information()
|
||
.WriteTo.Console(outputTemplate:
|
||
"[{Timestamp:HH:mm:ss} {Level:u3}] {Message:lj}{NewLine}{Exception}")
|
||
.CreateLogger();
|
||
|
||
try
|
||
{
|
||
Log.Information("🚀 ContentGen AI Media Worker başlatılıyor...");
|
||
|
||
var builder = Host.CreateApplicationBuilder(args);
|
||
|
||
builder.Services.AddSerilog();
|
||
|
||
// Configuration binding
|
||
builder.Services.Configure<WorkerSettings>(
|
||
builder.Configuration.GetSection("WorkerSettings"));
|
||
builder.Services.Configure<RedisSettings>(
|
||
builder.Configuration.GetSection("Redis"));
|
||
builder.Services.Configure<S3Settings>(
|
||
builder.Configuration.GetSection("S3"));
|
||
builder.Services.Configure<ApiSettings>(
|
||
builder.Configuration.GetSection("ApiSettings"));
|
||
builder.Services.Configure<FFmpegSettings>(
|
||
builder.Configuration.GetSection("FFmpeg"));
|
||
|
||
// Polly Retry Policy — Exponential Backoff + Circuit Breaker
|
||
var retryPolicy = HttpPolicyExtensions
|
||
.HandleTransientHttpError()
|
||
.WaitAndRetryAsync(
|
||
retryCount: 3,
|
||
sleepDurationProvider: attempt =>
|
||
TimeSpan.FromSeconds(Math.Pow(2, attempt)) +
|
||
TimeSpan.FromMilliseconds(Random.Shared.Next(0, 1000)),
|
||
onRetry: (outcome, delay, attempt, _) =>
|
||
{
|
||
Log.Warning(
|
||
"HTTP Retry #{Attempt} — {Delay}s sonra tekrar denenecek. Hata: {Error}",
|
||
attempt, delay.TotalSeconds,
|
||
outcome.Exception?.Message ?? outcome.Result?.StatusCode.ToString());
|
||
});
|
||
|
||
var circuitBreakerPolicy = HttpPolicyExtensions
|
||
.HandleTransientHttpError()
|
||
.CircuitBreakerAsync(
|
||
handledEventsAllowedBeforeBreaking: 5,
|
||
durationOfBreak: TimeSpan.FromSeconds(30),
|
||
onBreak: (_, duration) =>
|
||
Log.Error("⚡ Circuit Breaker AÇILDI — {Duration}s bekleniyor", duration.TotalSeconds),
|
||
onReset: () =>
|
||
Log.Information("✅ Circuit Breaker kapandı — istekler devam ediyor"));
|
||
|
||
var combinedPolicy = Policy.WrapAsync(retryPolicy, circuitBreakerPolicy);
|
||
|
||
// HttpClient registrations with Polly
|
||
builder.Services.AddHttpClient<HiggsFieldService>("HiggsField")
|
||
.AddPolicyHandler(combinedPolicy);
|
||
|
||
builder.Services.AddHttpClient<TtsService>("TTS")
|
||
.AddPolicyHandler(combinedPolicy);
|
||
|
||
builder.Services.AddHttpClient<SunoMusicService>("Suno")
|
||
.AddPolicyHandler(combinedPolicy);
|
||
|
||
builder.Services.AddHttpClient<ApiNotificationService>("CoreAPI")
|
||
.AddPolicyHandler(retryPolicy);
|
||
|
||
// Service registrations
|
||
builder.Services.AddSingleton<S3StorageService>();
|
||
builder.Services.AddSingleton<FFmpegService>();
|
||
builder.Services.AddSingleton<VideoRenderPipeline>();
|
||
builder.Services.AddSingleton<DatabaseService>();
|
||
|
||
// Background Service — Redis Queue Consumer
|
||
builder.Services.AddHostedService<QueueConsumerService>();
|
||
|
||
var host = builder.Build();
|
||
await host.RunAsync();
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Log.Fatal(ex, "💀 Media Worker başlatılamadı!");
|
||
}
|
||
finally
|
||
{
|
||
await Log.CloseAndFlushAsync();
|
||
}
|