From 9242fbe848bc389c97f273e74f59c46683ee2bc6 Mon Sep 17 00:00:00 2001 From: Licho Date: Sun, 3 Dec 2023 11:27:22 +0100 Subject: [PATCH] forum indexing runs on separate thread to not block saving, it can gracefully fail and also word saving now retries in case there is a concurrency issue --- Zero-K.info/AppCode/ForumPostIndexer.cs | 47 ++++++++++++++++++++----- 1 file changed, 38 insertions(+), 9 deletions(-) diff --git a/Zero-K.info/AppCode/ForumPostIndexer.cs b/Zero-K.info/AppCode/ForumPostIndexer.cs index b0978091de..2e12aa7c11 100644 --- a/Zero-K.info/AppCode/ForumPostIndexer.cs +++ b/Zero-K.info/AppCode/ForumPostIndexer.cs @@ -3,6 +3,8 @@ using System.Collections.Generic; using System.Data.Entity; using System.Data.Entity.Infrastructure; +using System.Data.SqlClient; +using System.Diagnostics; using System.Linq; using System.Threading.Tasks; using PlasmaShared; @@ -29,18 +31,31 @@ public void IndexAll() { int GetWordID(string word) { int id; if (wordIDs.TryGetValue(word, out id)) return id; - using (var db = new ZkDataContext()) + + for (int i = 0; i < 3; i++) // try 3 times { - var entry = db.IndexWords.FirstOrDefault(x => x.Text == word); - if (entry == null) + try + { + using (var db = new ZkDataContext()) + { + var entry = db.IndexWords.FirstOrDefault(x => x.Text == word); + if (entry == null) + { + entry = new Word { Text = word }; + db.IndexWords.Add(entry); + db.SaveChanges(); + } + + wordIDs[entry.Text] = entry.WordID; + return entry.WordID; + } + } + catch (SqlException ex) { - entry = new Word { Text = word }; - db.IndexWords.Add(entry); - db.SaveChanges(); + Trace.TraceWarning("Problem indexing word {0}: {1}", word, ex.Message); } - wordIDs[entry.Text] = entry.WordID; - return entry.WordID; } + throw new Exception("Failed to index word " + word); } public IQueryable FilterPosts(IQueryable input, string term) { @@ -55,7 +70,21 @@ public List SplitTermToWordIDs(string term) { void ZkDataContextOnAfterEntityChange(object sender, ZkDataContext.EntityEntry dbEntityEntry) { var post = dbEntityEntry.Entity as ForumPost; - if (post != null && (dbEntityEntry.State == EntityState.Added || dbEntityEntry.State == EntityState.Modified)) IndexPost(post); + if (post != null && (dbEntityEntry.State == EntityState.Added || dbEntityEntry.State == EntityState.Modified)) + { + Task.Run(() => + { + try + { + IndexPost(post); + } + catch (Exception ex) + { + Trace.TraceWarning("Problem indexing post {0}: {1}", post.ForumPostID, ex.Message); + } + }); + + } } public static string SanitizeWord(string word) {