This commit is contained in:
2018-12-19 18:16:14 +00:00
parent 948cfa2fc8
commit 1344986eae

View File

@@ -45,11 +45,49 @@ namespace AyaNova.Biz
public static void ProcessDeleteTagsInRepository(AyContext ct, List<string> deleteTags)
{
if (deleteTags.Count == 0) return;
foreach (string s in deleteTags)
{
bool bDone = false;
//Keep on trying until there is success
//this allows for concurrency issues
//I considered a circuit breaker / timeout here, but theoretically it should not be an issue
//at some point it should not be a concurrency issue anymore
do
{
//START: Get tag word and concurrency token and count
var ExistingTag = ct.Tag.FirstOrDefault(x => x.Name == s);
//if not present, then nothing to do
if (ExistingTag != null)
{
//No longer needed?
if (ExistingTag.RefCount == 1)
{
ct.Remove(ExistingTag);
}
else
{
//Decrement the refcount
ExistingTag.RefCount -= 1;
}
try
{
ct.SaveChanges();
bDone = true;
}
catch (Exception ex) when (ex is DbUpdateConcurrencyException)//allow for possible other types
{
//allow others to flow past
// string sss = ex.ToString();
}
}
} while (bDone == false);
}
}
public static void ProcessUpdateTagsInRepository(AyContext ct, List<string> newTags, List<string> originalTags = null)
{
if (newTags.Count == 0 && (originalTags == null || originalTags.Count == 0)) return;
List<string> deleteTags = new List<string>();
@@ -58,12 +96,10 @@ namespace AyaNova.Biz
if (originalTags != null)
{
//Update
//This logic is supposed to only come up with CHANGES, if the item is in both lists then it should disappear and not need to be dealt with
//This logic to only come up with CHANGES, if the item is in both lists then it will disappear and not need to be dealt with as it's refcount is unchanged in this operation
//testing will validate it
deleteTags = originalTags.Except(newTags).ToList();
addTags = newTags.Except(originalTags).ToList();
}
else
{
@@ -73,12 +109,13 @@ namespace AyaNova.Biz
//ADD / INCREMENT TAGS
foreach (string s in addTags)
{
bool bDone = false;
//Keep on trying until there is success
//this allows for concurrency issues
//I considered a circuit breaker / timeout here, but theoretically it should not be an issue
//at some point it should not be a concurrency issue anymore
do
{
//START: Get tag word and concurrency token and count
@@ -98,65 +135,16 @@ namespace AyaNova.Biz
ct.SaveChanges();
bDone = true;
}
catch (Exception ex) when(ex is DbUpdateConcurrencyException )
catch (Exception ex) when (ex is DbUpdateConcurrencyException)//this allows for other types
{
//allow others to flow past
string sss=ex.ToString();
//string sss = ex.ToString();
}
//If that fails due to others added it or works, either way go back to START:
//UPDATE: INCREMENT the refcount and update the record
//If that fails due to a concurrency exception go to START:
} while (bDone == false);
}
//Add / increase reference count for added tags
//remove / decrease reference count for removed tags
// var v=ct.Event.Any(x=>x.Textra=="word");
//https://stackoverflow.com/questions/10233298/increment-a-value-in-postgres
/*
ONE SHOT WAY WHICH IS BOSS!!
UPDATE totals
SET total = total + 1
WHERE name = 'bill';
If you want to make sure the current value is indeed 203 (and not accidently increase it again) you can also add another condition:
UPDATE totals
SET total = total + 1
WHERE name = 'bill'
AND total = 203;
*/
//WAY I PROBABLY SHOULD USE AND GROK for inventory later:
//https://stackoverflow.com/questions/14718929/best-practice-to-lock-a-record-for-editing-while-using-entity-framework
//Catch the concurrency exception, refetch and try again a certain number of times maximum until it's resolved
//maybe wrap that in a method I can re-use.
//Create table tags, word varchar 255, refcount longint, concurrency token
//so do this:
//REMOVE / DECREMENT TAGS
//Iterate remove tags
//Fetch the tag if it exists and decrement it's ref count
//Iterate addTags
//Fetch the tag if it exists and update it's ref count
//DELETE TAGS
ProcessDeleteTagsInRepository(ct, deleteTags);
}