public void SetLocalisation(string path, string variant) { if (string.IsNullOrEmpty(path)) { throw new Exception("path null or empty"); } if (string.IsNullOrEmpty(variant)) { var meta = repo.GetPuckMeta().Where(x => x.Name == DBNames.PathToLocale && x.Key == path).ToList(); meta.ForEach(x => { repo.DeletePuckMeta(x); }); if (meta.Count > 0) { repo.SaveChanges(); } } else { var meta = repo.GetPuckMeta().Where(x => x.Name == DBNames.PathToLocale && x.Key == path).ToList(); meta.ForEach(x => repo.DeletePuckMeta(x)); var newMeta = new PuckMeta(); newMeta.Name = DBNames.PathToLocale; newMeta.Key = path; newMeta.Value = variant; repo.AddPuckMeta(newMeta); repo.SaveChanges(); } StateHelper.UpdatePathLocaleMappings(true); }
public static void Sync(CancellationToken ct) { bool taken = false; using (var scope = PuckCache.ServiceProvider.CreateScope()) { var contentService = scope.ServiceProvider.GetService <I_Content_Service>(); var searcher = scope.ServiceProvider.GetService <I_Content_Searcher>(); var repo = scope.ServiceProvider.GetService <I_Puck_Repository>(); var config = scope.ServiceProvider.GetService <IConfiguration>(); var cache = scope.ServiceProvider.GetService <IMemoryCache>(); try { Monitor.TryEnter(lck, lock_wait, ref taken); if (!taken) { return; } var serverName = ApiHelper.ServerName(); var meta = repo.GetPuckMeta().Where(x => x.Name == DBNames.SyncId && x.Key == serverName).FirstOrDefault(); if (meta == null) { return; } var syncId = int.Parse(meta.Value); var instructionsQuery = repo.GetPuckInstruction().Where(x => x.Id > syncId && x.ServerName != serverName); var instructionsCount = instructionsQuery.Count(); if (instructionsCount == 0) { return; } void handleMaxInstructions() { //todo, update settings and republish entire site if (!PuckCache.IsRepublishingEntireSite) { PuckCache.IsRepublishingEntireSite = true; var republishTask = contentService.RePublishEntireSite2(); republishTask.GetAwaiter().GetResult(); } StateHelper.UpdateTaskMappings(); StateHelper.UpdateRedirectMappings(); StateHelper.UpdatePathLocaleMappings(); StateHelper.UpdateDomainMappings(); StateHelper.UpdateCacheMappings(); StateHelper.UpdateCrops(); } void updateMaxInstructionId(List <PuckInstruction> instructions) { //update syncId //var maxInstructionId = instructions.Max(x => x.Id); var maxInstructionIdOrDefault = repo.GetPuckInstruction().Max(x => (int?)x.Id); var maxInstructionId = maxInstructionIdOrDefault.HasValue ? maxInstructionIdOrDefault.Value : 0; meta.Value = maxInstructionId.ToString(); repo.SaveChanges(); OnAfterSync(null, new AfterSyncEventArgs { Instructions = instructions }); } //dosync var hasPublishInstruction = false; var haveRepublished = false; if (instructionsCount > PuckCache.MaxSyncInstructions) { handleMaxInstructions(); updateMaxInstructionId(new List <PuckInstruction>()); } else { var instructions = instructionsQuery.ToList(); var instructionTotal = 0; instructions.ForEach(x => instructionTotal += x.Count); if (instructionTotal > PuckCache.MaxSyncInstructions) { handleMaxInstructions(); } else { foreach (var instruction in instructions) { try { if (instruction.InstructionKey == InstructionKeys.RemoveFromCache) { var keys = instruction.InstructionDetail.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries); foreach (var key in keys) { cache.Remove(key); } } else if (instruction.InstructionKey == InstructionKeys.SetSearcher) { searcher.SetSearcher(); } else if (instruction.InstructionKey == InstructionKeys.Delete) { hasPublishInstruction = true; if (Indexer.CanWrite) { var qh = new QueryHelper <BaseModel>(prependTypeTerm: false); qh.SetQuery(instruction.InstructionDetail); var models = qh.GetAllNoCast(limit: int.MaxValue, fallBackToBaseModel: true); Indexer.Delete(models); } else { searcher.SetSearcher(); } } else if (instruction.InstructionKey == InstructionKeys.RepublishSite && !haveRepublished) { if (Indexer.CanWrite) { if (!PuckCache.IsRepublishingEntireSite) { PuckCache.IsRepublishingEntireSite = true; var republishTask = contentService.RePublishEntireSite2(); republishTask.GetAwaiter().GetResult(); hasPublishInstruction = true; } } else { searcher.SetSearcher(); } haveRepublished = true; } else if (instruction.InstructionKey == InstructionKeys.Publish) { hasPublishInstruction = true; var toIndex = new List <BaseModel>(); //instruction detail holds comma separated list of ids and variants in format id:variant,id:variant var idList = instruction.InstructionDetail.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries); if (Indexer.CanWrite) { foreach (var idAndVariant in idList) { var idAndVariantArr = idAndVariant.Split(new char[] { ':' }, StringSplitOptions.RemoveEmptyEntries); var id = Guid.Parse(idAndVariantArr[0]); var variant = idAndVariantArr[1]; var publishedOrCurrentRevision = repo.PublishedOrCurrentRevision(id, variant); if (publishedOrCurrentRevision != null) { var model = publishedOrCurrentRevision.ToBaseModel(); if (model != null) { toIndex.Add(model); } } } Indexer.Index(toIndex); } else { searcher.SetSearcher(); } } else if (instruction.InstructionKey == InstructionKeys.UpdateCrops) { StateHelper.UpdateCrops(); } else if (instruction.InstructionKey == InstructionKeys.UpdateCacheMappings) { StateHelper.UpdateCacheMappings(); } else if (instruction.InstructionKey == InstructionKeys.UpdateDomainMappings) { StateHelper.UpdateDomainMappings(); } else if (instruction.InstructionKey == InstructionKeys.UpdatePathLocales) { StateHelper.UpdatePathLocaleMappings(); } else if (instruction.InstructionKey == InstructionKeys.UpdateRedirects) { StateHelper.UpdateRedirectMappings(); } else if (instruction.InstructionKey == InstructionKeys.UpdateTaskMappings) { StateHelper.UpdateTaskMappings(); } } catch (Exception ex) { PuckCache.PuckLog.Log( $"error processing sync instruction (id:{instruction.Id}), skipping. error message:{ex.Message}" , ex.StackTrace , level: "error" , exceptionType: ex.GetType() ); } } if (hasPublishInstruction) { if (((config.GetValue <bool?>("UseAzureDirectory") ?? false) || (config.GetValue <bool?>("UseSyncDirectory") ?? false)) && config.GetValue <bool>("IsEditServer")) { var newInstruction = new PuckInstruction(); newInstruction.InstructionKey = InstructionKeys.SetSearcher; newInstruction.Count = 1; newInstruction.ServerName = ApiHelper.ServerName(); repo.AddPuckInstruction(newInstruction); repo.SaveChanges(); } } } updateMaxInstructionId(instructions); } } catch (Exception ex) { PuckCache.PuckLog.Log(ex); } finally { if (taken) { Monitor.Exit(lck); } PuckCache.IsSyncQueued = false; } } }