Beispiel #1
0
        // todo: make this reliable. The problem:
        // Sometimes an exception is thrown on client.BlockUntilReady.
        // The factory then seems unable to produce a working client
        // until the whole process is restarted. A similar thing is seen
        // if client.Destroy() is called. Do this, then, as per docs, create a new
        // factory and client. This client will _always_ fail on BlockUntilReady
        private static ISplitClient ReliablyCreateSplitClient(string apiKey)
        {
            SplitFactory factory = null;
            ISplitClient client  = null;

            for (var i = 0; i < 5; i++)
            {
                try
                {
                    if (factory == null)
                    {
                        factory = new SplitFactory(apiKey);
                    }
                    client = factory.Client();
                    client.BlockUntilReady(5000);

                    return(client);
                }
                catch (Exception e)
                {
                    Console.WriteLine("Creating client failed:");
                    Console.WriteLine();
                    Console.WriteLine(e);
                    Console.WriteLine();
                    Console.WriteLine("Retrying...");

                    client?.Destroy();
                    factory = null;
                }
            }

            throw new Exception("couldn't initialise client after 5 tries");
        }
Beispiel #2
0
        public FeatureFlagProvider(IHttpContextAccessor httpContextAccessor, ISplitClient client, ILogger <FeatureFlagProvider> logger)
        {
            _httpContextAccessor = httpContextAccessor;
            _client = client;
            _logger = logger;

            _client.BlockUntilReady(10000);
        }
Beispiel #3
0
        public async Task Initialize()
        {
            ConfigurationOptions config  = new ConfigurationOptions();
            SplitFactory         factory = new SplitFactory(ApiKey, config);

            _splitClient = factory.Client();
            _splitClient.BlockUntilReady(100000);
            await Task.FromResult(0);
        }
Beispiel #4
0
        public override async Task ConfigureAsync(ServiceCollection serviceCollection)
        {
            CreateLogger(configuration.LogLevel);

            if (string.IsNullOrWhiteSpace(configuration.ConnectionString))
            {
                throw new InvalidOperationException("Connection string cannot be null");
            }

            serviceCollection.AddDbContext <MikiDbContext>(
                x => x.UseNpgsql(
                    configuration.ConnectionString,
                    b => b.MigrationsAssembly("Miki.Bot.Models"))
                .EnableDetailedErrors());
            serviceCollection.AddDbContext <DbContext, MikiDbContext>(
                x => x.UseNpgsql(
                    configuration.ConnectionString,
                    b => b.MigrationsAssembly("Miki.Bot.Models"))
                .EnableDetailedErrors());

            serviceCollection.AddScoped <IUnitOfWork, UnitOfWork>();
            serviceCollection.AddSingleton(configuration.Configuration);
            serviceCollection.AddSingleton <ISerializer, ProtobufSerializer>();

            serviceCollection.AddScoped <
                IRepositoryFactory <Achievement>, AchievementRepository.Factory>();

            serviceCollection.AddScoped(x => new MikiApiClient(x.GetService <Config>().MikiApiKey));

            // Setup Discord
            serviceCollection.AddSingleton <IApiClient>(
                s => new DiscordApiClient(s.GetService <Config>().Token, s.GetService <ICacheClient>()));

            if (configuration.IsSelfHosted)
            {
                serviceCollection.AddSingleton <IGateway>(
                    new GatewayShard(
                        new GatewayProperties
                {
                    ShardCount             = 1,
                    ShardId                = 0,
                    Token                  = configuration.Configuration.Token,
                    AllowNonDispatchEvents = true,
                    Intents                = GatewayIntents.AllDefault | GatewayIntents.GuildMembers
                }));

                serviceCollection.AddSingleton <ICacheClient, InMemoryCacheClient>();
                serviceCollection.AddSingleton <IExtendedCacheClient, InMemoryCacheClient>();

                var splitConfig = new ConfigurationOptions
                {
                    LocalhostFilePath = "./feature_flags.yaml"
                };
                var factory = new SplitFactory("localhost", splitConfig);
                var client  = factory.Client();
                client.BlockUntilReady(30000);

                serviceCollection.AddSingleton(client);
            }
            else
            {
                var consumer = new RetsuConsumer(
                    new ConsumerConfiguration
                {
                    ConnectionString = new Uri(configuration.Configuration.RabbitUrl),
                    QueueName        = "gateway",
                    ExchangeName     = "consumer",
                    ConsumerAutoAck  = false,
                    PrefetchCount    = 25,
                },
                    new Retsu.Consumer.Models.QueueConfiguration
                {
                    ConnectionString = new Uri(configuration.Configuration.RabbitUrl),
                    QueueName        = "gateway-command",
                    ExchangeName     = "consumer",
                });

                await consumer.SubscribeAsync("MESSAGE_CREATE");

                await consumer.SubscribeAsync("MESSAGE_UPDATE");

                await consumer.SubscribeAsync("MESSAGE_DELETE");

                await consumer.SubscribeAsync("MESSAGE_DELETE_BULK");

                await consumer.SubscribeAsync("MESSAGE_REACTION_ADD");

                await consumer.SubscribeAsync("MESSAGE_REACTION_REMOVE");

                await consumer.SubscribeAsync("MESSAGE_REACTION_REMOVE_ALL");

                await consumer.SubscribeAsync("MESSAGE_REACTION_REMOVE_EMOJI");

                await consumer.SubscribeAsync("CHANNEL_CREATE");

                await consumer.SubscribeAsync("CHANNEL_DELETE");

                await consumer.SubscribeAsync("CHANNEL_PINS_UPDATE");

                await consumer.SubscribeAsync("CHANNEL_UPDATE");

                await consumer.SubscribeAsync("GUILD_CREATE");

                await consumer.SubscribeAsync("GUILD_DELETE");

                await consumer.SubscribeAsync("GUILD_UPDATE");

                await consumer.SubscribeAsync("GUILD_BAN_ADD");

                await consumer.SubscribeAsync("GUILD_BAN_REMOVE");

                await consumer.SubscribeAsync("GUILD_EMOJIS_UPDATE");

                await consumer.SubscribeAsync("GUILD_MEMBER_ADD");

                await consumer.SubscribeAsync("GUILD_MEMBER_REMOVE");

                await consumer.SubscribeAsync("GUILD_MEMBER_UPDATE");

                await consumer.SubscribeAsync("GUILD_ROLE_CREATE");

                await consumer.SubscribeAsync("GUILD_ROLE_DELETE");

                await consumer.SubscribeAsync("GUILD_ROLE_UPDATE");

                await consumer.SubscribeAsync("READY");

                await consumer.SubscribeAsync("RESUMED");

                serviceCollection.AddSingleton <IGateway>(consumer);

                serviceCollection.AddSingleton(
                    new RedisConnectionPool(configuration.Configuration.RedisConnectionString));

                serviceCollection.AddTransient(
                    x => x.GetRequiredService <RedisConnectionPool>().Get());

                serviceCollection.AddTransient <ICacheClient, StackExchangeCacheClient>();
                serviceCollection.AddTransient <IExtendedCacheClient, StackExchangeCacheClient>();

                ISplitClient client = null;
                if (!string.IsNullOrEmpty(configuration.Configuration.OptionalValues?.SplitioSdkKey))
                {
                    var splitConfig = new ConfigurationOptions();
                    var factory     = new SplitFactory(
                        configuration.Configuration.OptionalValues?.SplitioSdkKey, splitConfig);
                    client = factory.Client();
                    try
                    {
                        client.BlockUntilReady(30000);
                    }
                    catch (TimeoutException)
                    {
                        Log.Error("Couldn't initialize splitIO in time.");
                    }
                }

                serviceCollection.AddSingleton(x => client);
            }

            serviceCollection.AddSingleton <IDiscordClient, DiscordClient>();

            // Setup web services
            serviceCollection.AddSingleton <UrbanDictionaryApi>();

            // Setup miscellanious services
            serviceCollection.AddSingleton <ConfigurationManager>();
            serviceCollection.AddSingleton(
                await BackgroundStore.LoadFromFileAsync("./resources/backgrounds.json"));

            ISentryClient sentryClient = null;

            if (!string.IsNullOrWhiteSpace(configuration.Configuration.SharpRavenKey))
            {
                sentryClient = new SentryClient(
                    new SentryOptions
                {
                    Dsn = new Dsn(configuration.Configuration.SharpRavenKey)
                });
            }
            serviceCollection.AddSingleton(s => sentryClient);

            serviceCollection.AddSingleton <IMessageWorker <IDiscordMessage>, MessageWorker>();
            serviceCollection.AddSingleton <TransactionEvents>();
            serviceCollection.AddSingleton(await BuildLocalesAsync());

            serviceCollection.AddScoped <ISettingsService, SettingsService>();
            serviceCollection.AddScoped <IUserService, UserService>();
            serviceCollection.AddScoped <IDailyService, DailyService>();
            serviceCollection.AddSingleton <AccountService>();
            serviceCollection.AddScoped <PastaService>();

            serviceCollection.AddSingleton <RedditService>();
            serviceCollection.AddSingleton <AchievementCollection>();
            serviceCollection.AddScoped <AchievementService>();

            serviceCollection.AddSingleton <ISchedulerService, SchedulerService>();
            serviceCollection.AddScoped <IGuildService, GuildService>();
            serviceCollection.AddScoped <MarriageService>();
            serviceCollection.AddScoped <IRpsService, RpsService>();
            serviceCollection.AddScoped <ILocalizationService, LocalizationService>();
            serviceCollection.AddScoped <PermissionService>();
            serviceCollection.AddScoped <ScopeService>();
            serviceCollection.AddScoped <ITransactionService, TransactionService>();
            serviceCollection.AddScoped <IBankAccountService, BankAccountService>();
            serviceCollection.AddSingleton <LotteryEventHandler>();
            serviceCollection.AddScoped <ILotteryService, LotteryService>();
            serviceCollection.AddSingleton <IOsuApiClient>(
                _ => configuration.Configuration.OptionalValues?.OsuApiKey == null
                    ? null
                    : new OsuApiClientV1(configuration.Configuration.OptionalValues.OsuApiKey));
            serviceCollection.AddScoped <BlackjackService>();
            serviceCollection.AddScoped <LeaderboardsService>();

            serviceCollection.AddSingleton(new PrefixCollectionBuilder()
                                           .AddAsDefault(new DynamicPrefixTrigger(">"))
                                           .Add(new PrefixTrigger("miki."))
                                           .Add(new MentionTrigger())
                                           .Build());

            serviceCollection.AddScoped <IPrefixService, PrefixService>();

            serviceCollection.AddSingleton(
                x => new CommandTreeBuilder(x).Create(Assembly.GetExecutingAssembly()));

            serviceCollection.AddSingleton <CommandTreeService>();

            serviceCollection.AddSingleton <IAsyncEventingExecutor <IDiscordMessage> >(
                services => new CommandPipelineBuilder(services)
                .UseStage(new CorePipelineStage())
                .UseFilters(new BotFilter(), new UserFilter())
                .UsePrefixes()
                .UseStage(new FetchDataStage())
                .UseLocalization()
                .UseArgumentPack()
                .UseCommandHandler()
                .UsePermissions()
                .UseScopes()
                .Build());

            serviceCollection.AddSingleton <DatadogRoutine>();
        }