private void OnStop(int shardId) { var db = _redis.GetDatabase(); var msg = _defaultShardState.Clone(); msg.ShardId = shardId; db.ListSetByIndex(_key + "_shardstats", shardId, JsonConvert.SerializeObject(msg), CommandFlags.FireAndForget); var p = _shardProcesses[shardId]; _shardProcesses[shardId] = null; try { p?.Kill(); } catch { } try { p?.Dispose(); } catch { } }
public ShardsCoordinator() { //load main stuff LogSetup.SetupLogger(-1); _log = LogManager.GetCurrentClassLogger(); _creds = new BotCredentials(); _log.Info("Starting NadekoBot v" + StatsService.BotVersion); _key = _creds.RedisKey(); _redis = ConnectionMultiplexer.Connect("127.0.0.1"); new RedisImagesCache(_redis, _creds).Reload(); //reload images into redis //setup initial shard statuses _defaultShardState = new ShardComMessage() { ConnectionState = Discord.ConnectionState.Disconnected, Guilds = 0, Time = DateTime.UtcNow }; var db = _redis.GetDatabase(); //clear previous statuses db.KeyDelete(_key + "_shardstats"); _shardProcesses = new Process[_creds.TotalShards]; for (int i = 0; i < _creds.TotalShards; i++) { //add it to the list of shards which should be started #if DEBUG if (i > 0) { _shardStartQueue.Enqueue(i); } else { _shardProcesses[i] = Process.GetCurrentProcess(); } #else _shardStartQueue.Enqueue(i); #endif //set the shard's initial state in redis cache var msg = _defaultShardState.Clone(); msg.ShardId = i; //this is to avoid the shard coordinator thinking that //the shard is unresponsive while starting up var delay = 45; #if GLOBAL_NADEKO delay = 180; #endif msg.Time = DateTime.UtcNow + TimeSpan.FromSeconds(delay * (i + 1)); db.ListRightPush(_key + "_shardstats", JsonConvert.SerializeObject(msg), flags: CommandFlags.FireAndForget); } _curProcessId = Process.GetCurrentProcess().Id; //subscribe to shardcoord events var sub = _redis.GetSubscriber(); //send is called when shard status is updated. Every 7.5 seconds atm sub.Subscribe(_key + "_shardcoord_send", OnDataReceived, CommandFlags.FireAndForget); //called to stop the shard, although the shard will start again when it finds out it's dead sub.Subscribe(_key + "_shardcoord_stop", OnStop, CommandFlags.FireAndForget); //called kill the bot sub.Subscribe(_key + "_die", (ch, x) => Environment.Exit(0), CommandFlags.FireAndForget); }
public ShardsCoordinator() { //load main stuff LogSetup.SetupLogger(-1); _log = LogManager.GetCurrentClassLogger(); _creds = new BotCredentials(); _log.Info("Starting NadekoBot v" + StatsService.BotVersion); _key = _creds.RedisKey(); _log.Info("Redis options: " + _creds.RedisOptions); var conf = ConfigurationOptions.Parse(_creds.RedisOptions); _redis = ConnectionMultiplexer.Connect(conf); var imgCache = new RedisImagesCache(_redis, _creds); //reload images into redis if (!imgCache.AllKeysExist().GetAwaiter().GetResult()) // but only if the keys don't exist. If images exist, you have to reload them manually { imgCache.Reload().GetAwaiter().GetResult(); } else { _log.Info("Images are already present in redis. Use .imagesreload to force update if needed."); } //setup initial shard statuses _defaultShardState = new ShardComMessage() { ConnectionState = Discord.ConnectionState.Disconnected, Guilds = 0, Time = DateTime.UtcNow }; var db = _redis.GetDatabase(); //clear previous statuses db.KeyDelete(_key + "_shardstats"); _shardProcesses = new Process[_creds.TotalShards]; var shardIds = Enumerable.Range(1, _creds.TotalShards - 1) .Shuffle() .Prepend(0) .ToArray(); for (var i = 0; i < shardIds.Length; i++) { var id = shardIds[i]; //add it to the list of shards which should be started #if DEBUG if (id > 0) { _shardStartQueue.Enqueue(id); } else { _shardProcesses[id] = Process.GetCurrentProcess(); } #else _shardStartQueue.Enqueue(id); #endif //set the shard's initial state in redis cache var msg = _defaultShardState.Clone(); msg.ShardId = id; //this is to avoid the shard coordinator thinking that //the shard is unresponsive while starting up var delay = 45; #if GLOBAL_NADEKO delay = 180; #endif msg.Time = DateTime.UtcNow + TimeSpan.FromSeconds(delay * (id + 1)); db.ListRightPush(_key + "_shardstats", JsonConvert.SerializeObject(msg), flags: CommandFlags.FireAndForget); } _curProcessId = Process.GetCurrentProcess().Id; //subscribe to shardcoord events var sub = _redis.GetSubscriber(); //send is called when shard status is updated. Every 7.5 seconds atm sub.Subscribe(_key + "_shardcoord_send", OnDataReceived, CommandFlags.FireAndForget); //called to stop the shard, although the shard will start again when it finds out it's dead sub.Subscribe(_key + "_shardcoord_stop", OnStop, CommandFlags.FireAndForget); //called kill the bot sub.Subscribe(_key + "_die", (ch, x) => Environment.Exit(0), CommandFlags.FireAndForget); }