293 lines
13 KiB
C#
293 lines
13 KiB
C#
using System.Reflection;
|
|
using Discord.Commands;
|
|
using Discord.WebSocket;
|
|
using FluentValidation;
|
|
using Managing.Application;
|
|
using Managing.Application.Abstractions;
|
|
using Managing.Application.Abstractions.Repositories;
|
|
using Managing.Application.Abstractions.Services;
|
|
using Managing.Application.Accounts;
|
|
using Managing.Application.Agents;
|
|
using Managing.Application.Backtests;
|
|
using Managing.Application.ManageBot;
|
|
using Managing.Application.ManageBot.Commands;
|
|
using Managing.Application.MoneyManagements;
|
|
using Managing.Application.Scenarios;
|
|
using Managing.Application.Shared;
|
|
using Managing.Application.Shared.Behaviours;
|
|
using Managing.Application.Synth;
|
|
using Managing.Application.Trading;
|
|
using Managing.Application.Trading.Commands;
|
|
using Managing.Application.Trading.Handlers;
|
|
using Managing.Application.Users;
|
|
using Managing.Application.Workers;
|
|
using Managing.Domain.Trades;
|
|
using Managing.Infrastructure.Database.PostgreSql;
|
|
using Managing.Infrastructure.Databases;
|
|
using Managing.Infrastructure.Databases.InfluxDb;
|
|
using Managing.Infrastructure.Databases.InfluxDb.Abstractions;
|
|
using Managing.Infrastructure.Databases.InfluxDb.Models;
|
|
using Managing.Infrastructure.Databases.PostgreSql;
|
|
using Managing.Infrastructure.Databases.PostgreSql.Configurations;
|
|
using Managing.Infrastructure.Evm;
|
|
using Managing.Infrastructure.Evm.Abstractions;
|
|
using Managing.Infrastructure.Evm.Models.Privy;
|
|
using Managing.Infrastructure.Evm.Services;
|
|
using Managing.Infrastructure.Evm.Subgraphs;
|
|
using Managing.Infrastructure.Exchanges;
|
|
using Managing.Infrastructure.Exchanges.Abstractions;
|
|
using Managing.Infrastructure.Exchanges.Exchanges;
|
|
using Managing.Infrastructure.Messengers.Discord;
|
|
using Managing.Infrastructure.Storage;
|
|
using MediatR;
|
|
using Microsoft.AspNetCore.Hosting;
|
|
using Microsoft.Extensions.Configuration;
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
using Microsoft.Extensions.Hosting;
|
|
using Microsoft.Extensions.Logging;
|
|
using Microsoft.Extensions.Options;
|
|
using Orleans.Configuration;
|
|
|
|
namespace Managing.Bootstrap;
|
|
|
|
public static class ApiBootstrap
|
|
{
|
|
private static readonly Assembly ApplicationAssembly = typeof(StartBotCommand).GetTypeInfo().Assembly;
|
|
|
|
public static IServiceCollection RegisterApiDependencies(this IServiceCollection services,
|
|
IConfiguration configuration)
|
|
{
|
|
services.Configure<Web3ProxySettings>(configuration.GetSection("Web3Proxy"));
|
|
|
|
return services
|
|
.AddApplication()
|
|
.AddInfrastructure(configuration)
|
|
.AddWorkers(configuration)
|
|
.AddFluentValidation()
|
|
.AddMediatR()
|
|
;
|
|
}
|
|
|
|
// Note: IClusterClient is automatically available in co-hosting scenarios
|
|
// through IGrainFactory. Services should inject IGrainFactory instead of IClusterClient
|
|
// to avoid circular dependency issues during DI container construction.
|
|
|
|
public static IHostBuilder ConfigureOrleans(this IHostBuilder hostBuilder, IConfiguration configuration,
|
|
bool isProduction)
|
|
{
|
|
var postgreSqlConnectionString = configuration.GetSection("PostgreSql")["Orleans"];
|
|
|
|
return hostBuilder.UseOrleans(siloBuilder =>
|
|
{
|
|
// Configure clustering with improved networking
|
|
siloBuilder
|
|
.UseAdoNetClustering(options =>
|
|
{
|
|
options.ConnectionString = postgreSqlConnectionString;
|
|
options.Invariant = "Npgsql";
|
|
})
|
|
.UseAdoNetReminderService(options =>
|
|
{
|
|
options.ConnectionString = postgreSqlConnectionString;
|
|
options.Invariant = "Npgsql";
|
|
});
|
|
|
|
// Configure networking for better silo communication
|
|
siloBuilder
|
|
.ConfigureEndpoints(siloPort: 11111, gatewayPort: 30000)
|
|
.Configure<ClusterOptions>(options =>
|
|
{
|
|
// Configure cluster options with unique identifiers
|
|
options.ServiceId = "ManagingApp";
|
|
options.ClusterId = configuration["ASPNETCORE_ENVIRONMENT"] ?? "Development";
|
|
})
|
|
.Configure<GrainCollectionOptions>(options =>
|
|
{
|
|
// Configure grain collection to prevent memory issues
|
|
options.CollectionAge = TimeSpan.FromMinutes(10);
|
|
options.CollectionQuantum = TimeSpan.FromMinutes(1);
|
|
})
|
|
.Configure<MessagingOptions>(options =>
|
|
{
|
|
// Configure messaging for better reliability
|
|
options.ResponseTimeout = TimeSpan.FromSeconds(30);
|
|
});
|
|
|
|
siloBuilder
|
|
.ConfigureLogging(logging => logging.SetMinimumLevel(LogLevel.Information));
|
|
|
|
// Only enable dashboard in development to avoid shutdown issues
|
|
if (!isProduction)
|
|
{
|
|
siloBuilder.UseDashboard(options =>
|
|
{
|
|
// Configure dashboard with proper shutdown handling
|
|
options.Port = 9999;
|
|
options.HostSelf = true;
|
|
options.CounterUpdateIntervalMs = 10000; // 10 seconds
|
|
options.HideTrace = true; // Hide trace to reduce dashboard overhead
|
|
options.Host = "0.0.0.0"; // Allow external connections
|
|
options.Username = "admin";
|
|
options.Password = "admin";
|
|
});
|
|
}
|
|
|
|
siloBuilder
|
|
.AddAdoNetGrainStorage("bot-store", options =>
|
|
{
|
|
options.ConnectionString = postgreSqlConnectionString;
|
|
options.Invariant = "Npgsql";
|
|
})
|
|
.AddAdoNetGrainStorage("registry-store", options =>
|
|
{
|
|
options.ConnectionString = postgreSqlConnectionString;
|
|
options.Invariant = "Npgsql";
|
|
})
|
|
.AddAdoNetGrainStorage("agent-store", options =>
|
|
{
|
|
options.ConnectionString = postgreSqlConnectionString;
|
|
options.Invariant = "Npgsql";
|
|
})
|
|
.ConfigureServices(services =>
|
|
{
|
|
// Register existing services for Orleans DI
|
|
// These will be available to grains through dependency injection
|
|
services.AddTransient<IExchangeService, ExchangeService>();
|
|
services.AddTransient<IAccountService, AccountService>();
|
|
services.AddTransient<ITradingService, TradingService>();
|
|
services.AddTransient<IMessengerService, MessengerService>();
|
|
});
|
|
})
|
|
;
|
|
}
|
|
|
|
|
|
private static IServiceCollection AddApplication(this IServiceCollection services)
|
|
{
|
|
services.AddScoped<ITradingService, TradingService>();
|
|
services.AddScoped<IScenarioService, ScenarioService>();
|
|
services.AddScoped<IMoneyManagementService, MoneyManagementService>();
|
|
services.AddScoped<IAccountService, AccountService>();
|
|
services.AddScoped<IStatisticService, StatisticService>();
|
|
services.AddScoped<IAgentService, AgentService>();
|
|
services.AddScoped<ISettingsService, SettingsService>();
|
|
services.AddScoped<IUserService, UserService>();
|
|
services.AddScoped<IGeneticService, GeneticService>();
|
|
services.AddSingleton<IBotService, BotService>();
|
|
services.AddScoped<IWorkerService, WorkerService>();
|
|
services.AddScoped<ISynthPredictionService, SynthPredictionService>();
|
|
services.AddScoped<ISynthApiClient, SynthApiClient>();
|
|
services.AddTransient<ICommandHandler<OpenPositionRequest, Position>, OpenPositionCommandHandler>();
|
|
services.AddTransient<ICommandHandler<ClosePositionCommand, Position>, ClosePositionCommandHandler>();
|
|
|
|
// Processors
|
|
services.AddTransient<IBacktester, Backtester>();
|
|
services.AddTransient<IExchangeProcessor, EvmProcessor>();
|
|
|
|
services.AddTransient<ITradaoService, TradaoService>();
|
|
services.AddTransient<IExchangeService, ExchangeService>();
|
|
services.AddTransient<IExchangeStream, ExchangeStream>();
|
|
|
|
|
|
services.AddTransient<IPrivyService, PrivyService>();
|
|
services.AddTransient<IWeb3ProxyService, Web3ProxyService>();
|
|
services.AddTransient<IWebhookService, WebhookService>();
|
|
services.AddTransient<IKaigenService, KaigenService>();
|
|
|
|
services.AddSingleton<IMessengerService, MessengerService>();
|
|
services.AddSingleton<IDiscordService, DiscordService>();
|
|
|
|
return services;
|
|
}
|
|
|
|
private static IServiceCollection AddInfrastructure(this IServiceCollection services, IConfiguration configuration)
|
|
{
|
|
// Database
|
|
services.AddSingleton<IPostgreSqlSettings>(sp =>
|
|
sp.GetRequiredService<IOptions<PostgreSqlSettings>>().Value);
|
|
|
|
services.AddSingleton<IInfluxDbSettings>(sp =>
|
|
sp.GetRequiredService<IOptions<InfluxDbSettings>>().Value);
|
|
|
|
services.AddSingleton<IPrivySettings>(sp =>
|
|
sp.GetRequiredService<IOptions<PrivySettings>>().Value);
|
|
|
|
services.Configure<KaigenSettings>(configuration.GetSection("Kaigen"));
|
|
|
|
// Evm
|
|
services.AddGbcFeed();
|
|
services.AddUniswapV2();
|
|
services.AddChainlink();
|
|
services.AddChainlinkGmx();
|
|
services.AddSingleton<IEvmManager, EvmManager>();
|
|
|
|
// PostgreSql Repositories
|
|
|
|
services.AddTransient<IAccountRepository, PostgreSqlAccountRepository>();
|
|
services.AddTransient<IBacktestRepository, PostgreSqlBacktestRepository>();
|
|
services.AddTransient<IGeneticRepository, PostgreSqlGeneticRepository>();
|
|
services.AddTransient<ITradingRepository, PostgreSqlTradingRepository>();
|
|
services.AddTransient<ISettingsRepository, PostgreSqlSettingsRepository>();
|
|
services.AddTransient<IUserRepository, PostgreSqlUserRepository>();
|
|
services.AddTransient<IAgentSummaryRepository, AgentSummaryRepository>();
|
|
services.AddTransient<IStatisticRepository, PostgreSqlStatisticRepository>();
|
|
services.AddTransient<IBotRepository, PostgreSqlBotRepository>();
|
|
services.AddTransient<IWorkerRepository, PostgreSqlWorkerRepository>();
|
|
services.AddTransient<ISynthRepository, PostgreSqlSynthRepository>();
|
|
|
|
// InfluxDb Repositories
|
|
services.AddTransient<IInfluxDbRepository, InfluxDbRepository>();
|
|
services.AddTransient<ICandleRepository, CandleRepository>();
|
|
services.AddTransient<IAgentBalanceRepository, AgentBalanceRepository>();
|
|
|
|
// Cache
|
|
services.AddDistributedMemoryCache();
|
|
services.AddTransient<ICacheService, CacheService>();
|
|
services.AddSingleton<ITaskCache, TaskCache>();
|
|
|
|
// Services
|
|
services.AddTransient<ICacheService, CacheService>();
|
|
services.AddSingleton<ITaskCache, TaskCache>();
|
|
|
|
return services;
|
|
}
|
|
|
|
private static IServiceCollection AddWorkers(this IServiceCollection services, IConfiguration configuration)
|
|
{
|
|
if (configuration.GetValue<bool>("WorkerBalancesTracking", false))
|
|
{
|
|
services.AddHostedService<BalanceTrackingWorker>();
|
|
}
|
|
|
|
if (configuration.GetValue<bool>("WorkerNotifyBundleBacktest", false))
|
|
{
|
|
services.AddHostedService<NotifyBundleBacktestWorker>();
|
|
}
|
|
|
|
return services;
|
|
}
|
|
|
|
private static IServiceCollection AddMediatR(this IServiceCollection services)
|
|
{
|
|
return services.AddMediatR(cfg => cfg.RegisterServicesFromAssemblies(AppDomain.CurrentDomain.GetAssemblies()))
|
|
.AddTransient(typeof(IPipelineBehavior<,>), typeof(ValidationBehaviour<,>))
|
|
.AddTransient(typeof(IUnhandledExceptionBehaviour<,>), typeof(UnhandledExceptionBehaviour<,>));
|
|
}
|
|
|
|
private static IServiceCollection AddFluentValidation(this IServiceCollection services)
|
|
{
|
|
return services.AddValidatorsFromAssembly(ApplicationAssembly);
|
|
}
|
|
|
|
public static IWebHostBuilder SetupDiscordBot(this IWebHostBuilder builder)
|
|
{
|
|
return builder.ConfigureServices(services =>
|
|
{
|
|
services
|
|
.AddSingleton<DiscordSettings>()
|
|
.AddSingleton<DiscordSocketClient>()
|
|
.AddSingleton<CommandService>()
|
|
.AddHostedService<DiscordService>();
|
|
});
|
|
}
|
|
} |