Beispiel #1
0
 /// <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)));
 }
Beispiel #2
0
 public RecoveryModule(RecoveryAction recoveryAction)
 {
     RecoveryAction = recoveryAction;
 }
Beispiel #3
0
        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();
            }
        }
Beispiel #4
0
        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!"));
        }