/// <summary> /// <see cref="RecoveryModule"/> used to enforce a fail-safe recovery and take <see cref="RecoveryAction"/> when the /// json parsing fails. /// </summary> public static T WithRecovery <T>(this T _instance, RecoveryAction action) where T : JsonSettings { return(_instance.WithModule <T>(new RecoveryModule(action))); }
public RecoveryModule(RecoveryAction recoveryAction) { RecoveryAction = recoveryAction; }
protected virtual void HandleRecovery(JsonSettings sender, RecoveryAction action, ref bool recovered, ref bool handled) { //versions mismatch, handle if (recovered || handled) { return; } switch (action) { case RecoveryAction.Throw: throw new JsonSettingsRecoveryException($"Loading {sender._childtype.Name} settings{(sender is IVersionable v ? $" version '{v.Version}'" : "")}"); case RecoveryAction.RenameAndLoadDefault: { if (loadedPath == null) { throw new ArgumentNullException(nameof(loadedPath)); } //parse current name var versionMatch = VersioningModule.VersionMatcher.Match(loadedPath); int fileVersion = versionMatch.Success ? int.Parse(versionMatch.Groups[2].Value) + 1 : 0; var cleanName = loadedPath; if (!string.IsNullOrEmpty(versionMatch.Groups[0].Value)) { cleanName = cleanName.Replace(versionMatch.Groups[0].Value, ""); } var lastIdx = cleanName.LastIndexOf('.'); if (lastIdx == -1) { lastIdx = loadedPath.Length; } uint nonVersionable = 0; //figure naming of existing and rename string newFileName = cleanName; if (File.Exists(newFileName)) { do { newFileName = cleanName.Insert(lastIdx, $".{(sender is IVersionable versionable ? versionable.Version : "")}{(fileVersion++ == 0 ? "" : $"-{fileVersion}")}"); } while (File.Exists(newFileName)); try { File.Move(cleanName, newFileName); } catch (Exception) { // swallow try { File.Delete(loadedPath); } catch (Exception) { // swallow } } } //save internalCalls++; try { sender.FileName = loadedPath = cleanName; sender.LoadDefault(ConstructingParameters); sender.Save(); recovered = true; handled = true; } finally { internalCalls--; } return; } case RecoveryAction.LoadDefault: sender.LoadDefault(ConstructingParameters); recovered = true; handled = true; return; case RecoveryAction.LoadDefaultAndSave: sender.LoadDefault(ConstructingParameters); sender.Save(); recovered = true; handled = true; return; default: throw new ArgumentOutOfRangeException(); } }
public ActionResult Recovery( [FromQuery] string key, [FromQuery] RecoveryAction action ) { if (key != Environment.GetEnvironmentVariable("PRIVATE_API_KEY")) { return(Unauthorized("Key is wrong!")); } switch (action) { case RecoveryAction.RepairElastic: Logger.LogPrint("Repairing ElasticSearch"); _crawler.Stop(); _reibe.Stop(); _searchEngine.DeleteAllBeatmaps(); foreach (var beatmapSet in _contextFactory.Get().BeatmapSet) { beatmapSet.ChildrenBeatmaps = _contextFactory.Get().Beatmaps.Where(b => b.ParentSetId == beatmapSet.SetId).ToList(); _searchEngine.IndexBeatmap(beatmapSet); } if (Environment.GetEnvironmentVariable("CRAWLER_DISABLED") != "true") { _crawler.BeginCrawling(); } if (Environment.GetEnvironmentVariable("CHEESEGULL_CRAWLER_DISABLED") != "true") { _reibe.BeginCrawling(); } break; case RecoveryAction.RecrawlEverything: Logger.LogPrint("Recrawl Everything!"); _crawler.Stop(); _reibe.Stop(); _searchEngine.DeleteAllBeatmaps(); using (var db = _contextFactory.GetForWrite()) { db.Context.Database.ExecuteSqlCommand("SET FOREIGN_KEY_CHECKS = 0;" + "TRUNCATE TABLE `Beatmaps`;" + "ALTER TABLE `Beatmaps` AUTO_INCREMENT = 1;" + "TRUNCATE TABLE `BeatmapSet`;" + "ALTER TABLE `BeatmapSet` AUTO_INCREMENT = 1;" + "SET FOREIGN_KEY_CHECKS = 1;"); } using (var cacheDb = _cache.GetForWrite()) { cacheDb.Context.Database.ExecuteSqlCommand( "DELETE FROM `CacheBeatmaps`;" + "DELETE FROM `CacheBeatmapSet`;"); } if (Environment.GetEnvironmentVariable("CRAWLER_DISABLED") != "true") { _crawler.BeginCrawling(); } if (Environment.GetEnvironmentVariable("CHEESEGULL_CRAWLER_DISABLED") != "true") { _reibe.BeginCrawling(); } break; case RecoveryAction.RecrawlUnknown: Logger.LogPrint("Recrawl All unknown maps!"); _crawler.Stop(); using (var db = _contextFactory.GetForWrite()) { for (var i = 0; i < db.Context.BeatmapSet.Last().SetId; i++) { if (!db.Context.BeatmapSet.Any(set => set.SetId == i)) { _crawler.Crawl(i, db.Context); } } } _crawler.BeginCrawling(); break; default: return(BadRequest("Unknown Action type!")); } return(Ok("Success!")); }