private static void StartQueue() { Task.Factory.StartNew(() => { while (_running) { try { var firstCmd = IncrementQueue.Take(); // Try and batch up a lot of the commands var commands = new List <IncrementCommand> { firstCmd }; while (commands.Count < 1000 && IncrementQueue.Count > 0) { commands.Add(IncrementQueue.Take()); } // Convert all the individual commands into aggregated updates var aggregated = commands .GroupBy(c => new { c.Emoji, c.SourceType }) .Select(g => new IncrementCommand() { SourceType = g.Key.SourceType, Emoji = g.Key.Emoji, Amount = g.Sum(c => c.Amount) }); using (var db = new WorkerDb()) { foreach (var cmd in aggregated) { var record = db.EmojiCounts.Find(cmd.Emoji, cmd.SourceType); if (record == null) { log.Warning("No record for {0}/{1}", cmd.SourceType, cmd.Emoji); return; } record.Count += cmd.Amount; } db.SaveChanges(); } log.Information("Updated stored emoji"); } catch (Exception e) { log.Error(e, "Failed to handle incoming command queue"); } } }); }
private static void SyncRedisToDb() { log.Information("Synchronizing emoji with redis/database..."); using (var db = new WorkerDb()) { var allEmoji = db.EmojiCounts.ToArray(); var mapped = allEmoji.GroupBy(e => e.Emoji).ToDictionary(e => e.Key, e => e.Sum(p => p.Count)); var changed = false; foreach (var emoji in EmojiData.KnownSymbols) { var record = allEmoji.First(e => e.Emoji == emoji && e.Source == EmojiCount.SourceUnknown); var efCount = mapped.ContainsKey(emoji) ? mapped[emoji] : 0; var reCountStr = _redisDb.StringGet(emoji); if (string.IsNullOrWhiteSpace(reCountStr)) { reCountStr = "0"; } var reCount = long.Parse(reCountStr); if (reCount == efCount) { continue; } if (reCount < efCount) { // Redis is wrong - fix it _redisDb.StringSet(emoji, efCount, flags: CommandFlags.FireAndForget); return; } record.Count += (reCount - efCount); changed = true; } if (changed) { db.SaveChanges(); } } log.Information("Done synchronizing emoji with redis/database"); }
private static void StartDatabase() { WorkerDb.ConnectionString = _config.GetConnectionString("emoji"); using (var context = new WorkerDb()) context.Database.Migrate(); using (var context = new WorkerDb()) { var sources = new string[] { EmojiCount.SourceMessage, EmojiCount.SourceReaction, EmojiCount.SourceUnknown, }; var records = context.EmojiCounts.ToArray(); if (records.Count() == (sources.Length * EmojiData.KnownSymbols.Count())) { log.Warning( "Skipping database record update - suspecting the emoji are already present. This may cause problems"); return; } var changed = false; foreach (var emoji in EmojiData.KnownSymbols) { foreach (var source in sources) { log.Information("Checking for {0}/{1} emoji...", source, emoji); var record = records.FirstOrDefault(e => e.Emoji == emoji && e.Source == source); if (record != null) { continue; } context.EmojiCounts.Add(new EmojiCount(emoji, source)); changed = true; } } if (changed) { context.SaveChanges(); } } }