This commit is contained in:
2020-01-27 17:54:51 +00:00
parent 2d0a8e711d
commit 629cc300e4
19 changed files with 106 additions and 151 deletions

View File

@@ -4,28 +4,23 @@ eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOiIxNTcxODU5OTU0IiwiZXhwIjoiMTU3MjQ
## IMMEDIATE ITEMS
TODO: Ensure scaleability by checking for performance issues now before replicating code (particularly in widget etc)
- As per this document https://docs.microsoft.com/en-us/aspnet/core/performance/performance-best-practices?view=aspnetcore-3.1
- For scaleability go back to async only for any db calls functions like creating widgets etc
UPDATE SPEC DOCS with new format and names etc or at least remove nonsense as necessary
UPDATE MANUAL API REGARDING LISTS
TODO: REFACTOR GetNoLogAsync function is used in many places redundantly when the logging version could do the same thing but not log it with an optional bool switch so refactor that shit
TODO: REFACTOR biz objects have two creates, an async and sync one, WTF is that about? See if can make it just one async version.
- https://docs.microsoft.com/en-us/aspnet/core/performance/performance-best-practices?view=aspnetcore-3.1
TODO: Need route to gather all object role rights in a format useful to display in UI so that a biz manager can see at a glance the rights for different roles to objects
- This way it's dynamic and picked up from the code itself which is always the source of truth so no need to put in the manual
- Would likely want to display multiple ways: for a specific object or role or selected user maybe too in the user info form ("effective roles")
- Move this over to client once the backend supports it
TODO: REFACTOR GetNoLogAsync function is used in many places redundantly when the logging version could do the same thing but not log it with an optional bool switch so refactor that shit
TODO: REFACTOR biz objects have two creates, an async and sync one, WTF is that about? See if can make it just one async version.
UPDATE SPEC DOCS with new format and names etc or at least remove nonsense as necessary
UPDATE MANUAL API REGARDING LISTS
TODO: DataFilter how to distinguish between filtering on specific ID value or on value column
- Might need to add a filter on ID type of thing maybe?

View File

@@ -230,7 +230,7 @@ namespace AyaNova.Api.Controllers
});
//EVENT LOG
EventLogProcessor.LogEventToDatabaseAndSaveEntireContext(new Event(UserId, attachToObject.ObjectId, attachToObject.ObjectType, AyaEvent.AttachmentCreate, v.DisplayFileName), ct);
EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, attachToObject.ObjectId, attachToObject.ObjectType, AyaEvent.AttachmentCreate, v.DisplayFileName), ct);
//SEARCH INDEXING
// Search.ProcessNewObjectKeywords( UserLocaleIdFromContext.Id(HttpContext.Items), v.Id, AyaType.FileAttachment, v.DisplayFileName, v.DisplayFileName, v.Notes, v.StoredFileName);
@@ -303,7 +303,7 @@ namespace AyaNova.Api.Controllers
FileUtil.deleteFileAttachment(dbObj, ct);
//Event log process delete
EventLogProcessor.LogEventToDatabaseAndSaveEntireContext(new Event(UserId, dbObj.AttachToObjectId, dbObj.AttachToObjectType, AyaEvent.AttachmentDelete, dbObj.DisplayFileName), ct);
EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, dbObj.AttachToObjectId, dbObj.AttachToObjectType, AyaEvent.AttachmentDelete, dbObj.DisplayFileName), ct);
//Delete search index
Search.ProcessDeletedObjectKeywords(dbObj.Id, AyaType.FileAttachment);
@@ -385,7 +385,7 @@ namespace AyaNova.Api.Controllers
}
//Log
EventLogProcessor.LogEventToDatabaseAndSaveEntireContext(new Event(UserId, dbObj.AttachToObjectId, dbObj.AttachToObjectType, AyaEvent.AttachmentDownload, dbObj.DisplayFileName), ct);
EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, dbObj.AttachToObjectId, dbObj.AttachToObjectType, AyaEvent.AttachmentDownload, dbObj.DisplayFileName), ct);
return PhysicalFile(filePath, mimetype, dbObj.DisplayFileName);

View File

@@ -121,7 +121,7 @@ namespace AyaNova.Api.Controllers
}
var ret = AyaNova.Core.License.LicenseInfoAsJson;
//Log
EventLogProcessor.LogEventToDatabaseAndSaveEntireContext(new Event(UserIdFromContext.Id(HttpContext.Items), 0, AyaType.License, AyaEvent.LicenseFetch), ct);
EventLogProcessor.LogEventToDatabaseAsync(new Event(UserIdFromContext.Id(HttpContext.Items), 0, AyaType.License, AyaEvent.LicenseFetch), ct);
return Ok(ApiOkResponse.Response(ret, true));
}
@@ -169,7 +169,7 @@ namespace AyaNova.Api.Controllers
var ret = Core.License.RequestTrial(requestData.EmailAddress, requestData.RegisteredTo, log);
//Log
EventLogProcessor.LogEventToDatabaseAndSaveEntireContext(new Event(UserIdFromContext.Id(HttpContext.Items), 0, AyaType.License, AyaEvent.LicenseTrialRequest), ct);
EventLogProcessor.LogEventToDatabaseAsync(new Event(UserIdFromContext.Id(HttpContext.Items), 0, AyaType.License, AyaEvent.LicenseTrialRequest), ct);
return Ok(ApiOkResponse.Response(ret, true));
}

View File

@@ -360,7 +360,7 @@ namespace AyaNova.Api.Controllers
return BadRequest(new ApiErrorResponse(biz.Errors));
}
//Log
EventLogProcessor.DeleteObject(biz.UserId, AyaType.Locale, dbObj.Id, dbObj.Name, ct);
EventLogProcessor.DeleteObjectLogAsync(biz.UserId, AyaType.Locale, dbObj.Id, dbObj.Name, ct);
await ct.SaveChangesAsync();
//Delete children / attached objects

View File

@@ -66,7 +66,7 @@ namespace AyaNova.Api.Controllers
string sResult = await GetTheMetrics("plain");
//Log
EventLogProcessor.LogEventToDatabaseAndSaveEntireContext(new Event(UserIdFromContext.Id(HttpContext.Items), 0, AyaType.Metrics, AyaEvent.Retrieved), ct);
EventLogProcessor.LogEventToDatabaseAsync(new Event(UserIdFromContext.Id(HttpContext.Items), 0, AyaType.Metrics, AyaEvent.Retrieved), ct);
return Content(sResult);
}
@@ -94,7 +94,7 @@ namespace AyaNova.Api.Controllers
JObject json = JObject.Parse(sResult);
//Log
EventLogProcessor.LogEventToDatabaseAndSaveEntireContext(new Event(UserIdFromContext.Id(HttpContext.Items), 0, AyaType.Metrics, AyaEvent.Retrieved), ct);
EventLogProcessor.LogEventToDatabaseAsync(new Event(UserIdFromContext.Id(HttpContext.Items), 0, AyaType.Metrics, AyaEvent.Retrieved), ct);
return Ok(ApiOkResponse.Response(json, true));
}

View File

@@ -88,7 +88,7 @@ namespace AyaNova.Api.Controllers
serverState.SetState(desiredState, state.Reason);
//Log
EventLogProcessor.LogEventToDatabaseAndSaveEntireContext(new Event(UserIdFromContext.Id(HttpContext.Items), 0, AyaType.ServerState, AyaEvent.ServerStateChange, $"{state.ServerState}-{state.Reason}"), ct);
EventLogProcessor.LogEventToDatabaseAsync(new Event(UserIdFromContext.Id(HttpContext.Items), 0, AyaType.ServerState, AyaEvent.ServerStateChange, $"{state.ServerState}-{state.Reason}"), ct);
return NoContent();
}

View File

@@ -54,7 +54,7 @@ namespace AyaNova.Api.Controllers
return StatusCode(503, new ApiErrorResponse(ApiErrorCode.API_CLOSED, null, serverState.Reason));
}
return Ok(ApiOkResponse.Response(TagUtil.PickListFiltered(ct, query),true));
return Ok(ApiOkResponse.Response(TagUtil.PickListFilteredAsync(ct, query),true));
}
@@ -72,7 +72,7 @@ namespace AyaNova.Api.Controllers
return StatusCode(503, new ApiErrorResponse(ApiErrorCode.API_CLOSED, null, serverState.Reason));
}
return Ok(ApiOkResponse.Response(TagUtil.CloudListFiltered(ct, query), true));
return Ok(ApiOkResponse.Response(TagUtil.CloudListFilteredAsync(ct, query), true));
}

View File

@@ -104,7 +104,7 @@ namespace AyaNova.Api.Controllers
JobsBiz.AddJob(j, ct);
//Log
EventLogProcessor.LogEventToDatabaseAndSaveEntireContext(new Event(UserIdFromContext.Id(HttpContext.Items), 0, AyaType.TrialSeeder, AyaEvent.Created, size), ct);
EventLogProcessor.LogEventToDatabaseAsync(new Event(UserIdFromContext.Id(HttpContext.Items), 0, AyaType.TrialSeeder, AyaEvent.Created, size), ct);
return Accepted(new { JobId = j.GId });//202 accepted
}

View File

@@ -65,7 +65,7 @@ namespace AyaNova.Biz
//Handle child and associated items:
//EVENT LOG
EventLogProcessor.LogEventToDatabaseAndSaveEntireContext(new Event(UserId, outObj.Id, BizType, AyaEvent.Created), ct);
EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, outObj.Id, BizType, AyaEvent.Created), ct);
//SEARCH INDEXING
// Search.ProcessNewObjectKeywords(UserLocaleId, outObj.Id, BizType, outObj.Name, outObj.Name);
@@ -95,7 +95,7 @@ namespace AyaNova.Biz
//Handle child and associated items:
//EVENT LOG
EventLogProcessor.LogEventToDatabaseAndSaveEntireContext(new Event(UserId, outObj.Id, BizType, AyaEvent.Created), TempContext);
EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, outObj.Id, BizType, AyaEvent.Created), TempContext);
//SEARCH INDEXING
// Search.ProcessNewObjectKeywords(UserLocaleId, outObj.Id, BizType, outObj.Name, outObj.Name);
@@ -116,7 +116,7 @@ namespace AyaNova.Biz
if (ret != null)
{
//Log
EventLogProcessor.LogEventToDatabaseAndSaveEntireContext(new Event(UserId, fetchId, BizType, AyaEvent.Retrieved), ct);
EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, fetchId, BizType, AyaEvent.Retrieved), ct);
}
return ret;
}
@@ -175,7 +175,7 @@ namespace AyaNova.Biz
return false;
//Log modification and save context
EventLogProcessor.LogEventToDatabaseAndSaveEntireContext(new Event(UserId, dbObj.Id, BizType, AyaEvent.Modified), ct);
EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, dbObj.Id, BizType, AyaEvent.Modified), ct);
//Update keywords
// Search.ProcessUpdatedObjectKeywords(UserLocaleId, dbObj.Id, BizType, dbObj.Name, dbObj.Name);
@@ -201,7 +201,7 @@ namespace AyaNova.Biz
//Delete sibling objects
//Event log process delete
EventLogProcessor.DeleteObject(UserId, BizType, dbObj.Id, dbObj.Name, ct);
EventLogProcessor.DeleteObjectLogAsync(UserId, BizType, dbObj.Id, dbObj.Name, ct);
ct.SaveChanges();
//Delete search index

View File

@@ -56,7 +56,7 @@ namespace AyaNova.Biz
if (log)
{
//Log
EventLogProcessor.LogEventToDatabaseAndSaveEntireContext(new Event(UserId, ret.Id, BizType, AyaEvent.Retrieved), ct);
EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, ret.Id, BizType, AyaEvent.Retrieved), ct);
}
return ret;
}
@@ -85,7 +85,7 @@ namespace AyaNova.Biz
return false;
//Log modification and save context
EventLogProcessor.LogEventToDatabaseAndSaveEntireContext(new Event(UserId, dbObj.Id, BizType, AyaEvent.Modified), ct);
EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, dbObj.Id, BizType, AyaEvent.Modified), ct);
return true;
}
@@ -100,7 +100,7 @@ namespace AyaNova.Biz
ct.DataListTemplate.Remove(dbObj);
ct.SaveChanges();
//Event log process delete
EventLogProcessor.DeleteObject(UserId, BizType, dbObj.Id, dbObj.DataListKey, ct);
EventLogProcessor.DeleteObjectLogAsync(UserId, BizType, dbObj.Id, dbObj.DataListKey, ct);
ct.SaveChanges();
return true;
}

View File

@@ -1,12 +1,7 @@
using System;
using System.Text;
using System.Linq;
using System.Threading.Tasks;
using System.Collections.Generic;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using AyaNova.Models;
using AyaNova.Util;
namespace AyaNova.Biz
@@ -21,10 +16,10 @@ namespace AyaNova.Biz
/// <param name="newEvent"></param>
/// <param name="ct"></param>
/// <returns></returns>
internal static void LogEventToDatabaseAndSaveEntireContext(Event newEvent, AyContext ct)
internal static async Task LogEventToDatabaseAsync(Event newEvent, AyContext ct)
{
ct.Event.Add(newEvent);
ct.SaveChanges();
await ct.Event.AddAsync(newEvent);
await ct.SaveChangesAsync();
}
@@ -38,10 +33,11 @@ namespace AyaNova.Biz
/// <param name="ayId"></param>
/// <param name="textra"></param>
/// <param name="ct"></param>
internal static void DeleteObject(long userId, AyaType ayType, long ayId, string textra, AyContext ct)
internal static async Task DeleteObjectLogAsync(long userId, AyaType ayType, long ayId, string textra, AyContext ct)
{
ct.Database.ExecuteSqlInterpolated($"delete from aevent where aytype = {ayType} and ayid={ayId}");
ct.Event.Add(new Event(userId, ayId, ayType, AyaEvent.Deleted, textra));
await ct.Database.ExecuteSqlInterpolatedAsync($"delete from aevent where aytype = {ayType} and ayid={ayId}");
await ct.Event.AddAsync(new Event(userId, ayId, ayType, AyaEvent.Deleted, textra));
await ct.SaveChangesAsync();
}
/// <summary>
@@ -53,7 +49,7 @@ namespace AyaNova.Biz
//This is also an example of conditional where statements
//Set up the query
var q = ct.Event.Select(m => m);
var q = ct.Event.Select(m => m).AsNoTracking();
q = q.Where(m => m.AyId == opt.AyId);

View File

@@ -71,7 +71,7 @@ namespace AyaNova.Biz
//Handle child and associated items:
//EVENT LOG
EventLogProcessor.LogEventToDatabaseAndSaveEntireContext(new Event(UserId, outObj.Id, BizType, AyaEvent.Created), ct);
EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, outObj.Id, BizType, AyaEvent.Created), ct);
//SEARCH INDEXING
// Search.ProcessNewObjectKeywords(UserLocaleId, outObj.Id, BizType, outObj.Name, outObj.Name);
@@ -141,7 +141,7 @@ namespace AyaNova.Biz
dbObj.Template = JsonUtil.CompactJson(dbObj.Template);
//Log modification and save context
EventLogProcessor.LogEventToDatabaseAndSaveEntireContext(new Event(UserId, dbObj.Id, BizType, AyaEvent.Modified), ct);
EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, dbObj.Id, BizType, AyaEvent.Modified), ct);
//Update keywords
// Search.ProcessUpdatedObjectKeywords(UserLocaleId, dbObj.Id, BizType, dbObj.Name, dbObj.Name);

View File

@@ -349,9 +349,9 @@ namespace AyaNova.Biz
//handle EventLog entries for users now that we have the user's created
//Created
EventLogProcessor.LogEventToDatabaseAndSaveEntireContext(new Event(Creator, RavenId, ayaType, AyaEvent.Created, Created), ct);
EventLogProcessor.LogEventToDatabaseAsync(new Event(Creator, RavenId, ayaType, AyaEvent.Created, Created), ct);
//MODIFIED
EventLogProcessor.LogEventToDatabaseAndSaveEntireContext(new Event(Modifier, RavenId, ayaType, AyaEvent.Modified, Modified), ct);
EventLogProcessor.LogEventToDatabaseAsync(new Event(Modifier, RavenId, ayaType, AyaEvent.Modified, Modified), ct);
}

View File

@@ -77,7 +77,7 @@ namespace AyaNova.Biz
ct.Locale.Add(NewLocale);
await ct.SaveChangesAsync();
//Log
EventLogProcessor.LogEventToDatabaseAndSaveEntireContext(new Event(UserId, NewLocale.Id, AyaType.Locale, AyaEvent.Created), ct);
EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, NewLocale.Id, AyaType.Locale, AyaEvent.Created), ct);
return NewLocale;
}
@@ -242,7 +242,7 @@ namespace AyaNova.Biz
ct.SaveChanges();
//Log
EventLogProcessor.LogEventToDatabaseAndSaveEntireContext(new Event(UserId, dbParent.Id, AyaType.Locale, AyaEvent.Modified), ct);
EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, dbParent.Id, AyaType.Locale, AyaEvent.Modified), ct);
return true;
}
@@ -269,7 +269,7 @@ namespace AyaNova.Biz
ct.SaveChanges();
//Log
EventLogProcessor.LogEventToDatabaseAndSaveEntireContext(new Event(UserId, dbObj.Id, AyaType.Locale, AyaEvent.Modified), ct);
EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, dbObj.Id, AyaType.Locale, AyaEvent.Modified), ct);
return true;
}
@@ -611,7 +611,7 @@ namespace AyaNova.Biz
ct.SaveChanges();
//Log now that we have the Id, note that there is no source created / modified for this so just attributing to current userId
EventLogProcessor.LogEventToDatabaseAndSaveEntireContext(new Event(UserId, l.Id, AyaType.Locale, AyaEvent.Created), ct);
EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, l.Id, AyaType.Locale, AyaEvent.Created), ct);
}
break;

View File

@@ -4,6 +4,7 @@ using AyaNova.Util;
using System.Linq;
using Microsoft.EntityFrameworkCore;
using AyaNova.Models;
using System.Threading.Tasks;
namespace AyaNova.Biz
{
@@ -42,7 +43,7 @@ namespace AyaNova.Biz
public static void ProcessDeleteTagsInRepository(AyContext ct, List<string> deleteTags)
public static async Task ProcessDeleteTagsInRepositoryAsync(AyContext ct, List<string> deleteTags)
{
if (deleteTags.Count == 0) return;
foreach (string s in deleteTags)
@@ -55,7 +56,7 @@ namespace AyaNova.Biz
do
{
//START: Get tag word and concurrency token and count
var ExistingTag = ct.Tag.FirstOrDefault(x => x.Name == s);
var ExistingTag = await ct.Tag.FirstOrDefaultAsync(x => x.Name == s);
//if not present, then nothing to do
if (ExistingTag != null)
{
@@ -73,7 +74,7 @@ namespace AyaNova.Biz
try
{
ct.SaveChanges();
await ct.SaveChangesAsync();
bDone = true;
}
catch (Exception ex) when (ex is DbUpdateConcurrencyException)//allow for possible other types
@@ -86,7 +87,7 @@ namespace AyaNova.Biz
}
}
public static void ProcessUpdateTagsInRepository(AyContext ct, List<string> newTags, List<string> originalTags = null)
public static async Task ProcessUpdateTagsInRepositoryAsync(AyContext ct, List<string> newTags, List<string> originalTags = null)
{
//just in case no new tags are present which could mean a user removed all tags from a record so this
//needs to proceed with the code below even if newTags is null as long as originalTags isn't also null
@@ -124,11 +125,11 @@ namespace AyaNova.Biz
do
{
//START: Get tag word and concurrency token and count
var ExistingTag = ct.Tag.FirstOrDefault(x => x.Name == s);
var ExistingTag = await ct.Tag.FirstOrDefaultAsync(x => x.Name == s);
//if not present, then add it with a count of 0
if (ExistingTag == null)
{
ct.Tag.Add(new Tag() { Name = s, RefCount = 1 });
await ct.Tag.AddAsync(new Tag() { Name = s, RefCount = 1 });
}
else
{
@@ -137,7 +138,7 @@ namespace AyaNova.Biz
}
try
{
ct.SaveChanges();
await ct.SaveChangesAsync();
bDone = true;
}
catch (Exception ex) when (ex is DbUpdateConcurrencyException)//this allows for other types
@@ -149,43 +150,57 @@ namespace AyaNova.Biz
}
//DELETE TAGS
ProcessDeleteTagsInRepository(ct, deleteTags);
await ProcessDeleteTagsInRepositoryAsync(ct, deleteTags);
}
//Pick list for driving pick list route
//going with contains for now as I think it's more useful in the long run and still captures startswith intent by user
public static List<string> PickListFiltered(AyContext ct, string q)
public static async Task<List<string>> PickListFilteredAsync(AyContext ct, string q)
{
//This path is intended for internal use and accepts that there may not be a filter specified
//however the client will always require a filter to display a tag list for choosing from
if (string.IsNullOrWhiteSpace(q))
{
return ct.Tag.OrderBy(x => x.Name).Select(x => x.Name).ToList();
return await ct.Tag.OrderBy(x => x.Name)
.Select(x => x.Name)
.AsNoTracking()
.ToListAsync();
}
else
{
q = NormalizeTag(q);
return ct.Tag.Where(x => x.Name.Contains(q)).OrderBy(x => x.Name).Select(x => x.Name).Take(25).ToList();
return await ct.Tag
.Where(x => x.Name.Contains(q))
.OrderBy(x => x.Name)
.Select(x => x.Name)
.Take(25)
.AsNoTracking()
.ToListAsync();
}
}
//Cloud list
public static List<TagCloudItem> CloudListFiltered(AyContext ct, string q)
public static async Task<List<TagCloudItem>> CloudListFilteredAsync(AyContext ct, string q)
{
//This path is intended for internal use and accepts that there may not be a filter specified
//however the client will always require a filter to display a tag list for choosing from
if (string.IsNullOrWhiteSpace(q))
{
return ct.Tag.OrderByDescending(x => x.RefCount).Select(x => new TagCloudItem() { Name = x.Name, RefCount = x.RefCount }).ToList();
return await ct.Tag.OrderByDescending(x => x.RefCount).Select(x => new TagCloudItem() { Name = x.Name, RefCount = x.RefCount }).AsNoTracking().ToListAsync();
}
else
{
q = NormalizeTag(q);
//TODO: Use the EF CORE TAKE method to restrict the results to a maximum limit
//however need to ensure it doesn't balk when the limit is higher than the number of results (probably not but test that)
return ct.Tag.Where(x => x.Name.Contains(q)).OrderByDescending(x => x.RefCount).Select(x => new TagCloudItem() { Name = x.Name, RefCount = x.RefCount }).ToList();
return await ct.Tag
.Where(x => x.Name.Contains(q))
.OrderByDescending(x => x.RefCount)
.Select(x => new TagCloudItem() { Name = x.Name, RefCount = x.RefCount })
.AsNoTracking()
.ToListAsync();
}
}

View File

@@ -81,13 +81,13 @@ namespace AyaNova.Biz
//Handle child and associated items
//Log event
EventLogProcessor.LogEventToDatabaseAndSaveEntireContext(new Event(UserId, inObj.Id, BizType, AyaEvent.Created), ct);
EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, inObj.Id, BizType, AyaEvent.Created), ct);
//SEARCH INDEXING
SearchIndex(inObj, true);
//TAGS
TagUtil.ProcessUpdateTagsInRepository(ct, inObj.Tags, null);
TagUtil.ProcessUpdateTagsInRepositoryAsync(ct, inObj.Tags, null);
return inObj;
@@ -123,13 +123,13 @@ namespace AyaNova.Biz
//Handle child and associated items
//Log event
EventLogProcessor.LogEventToDatabaseAndSaveEntireContext(new Event(UserId, inObj.Id, BizType, AyaEvent.Created), TempContext);
EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, inObj.Id, BizType, AyaEvent.Created), TempContext);
//SEARCH INDEXING
SearchIndex(inObj, true);
//TAGS
TagUtil.ProcessUpdateTagsInRepository(TempContext, inObj.Tags, null);
TagUtil.ProcessUpdateTagsInRepositoryAsync(TempContext, inObj.Tags, null);
return inObj;
@@ -147,7 +147,7 @@ namespace AyaNova.Biz
if (ret != null)
{
//Log
EventLogProcessor.LogEventToDatabaseAndSaveEntireContext(new Event(UserId, fetchId, BizType, AyaEvent.Retrieved), ct);
EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, fetchId, BizType, AyaEvent.Retrieved), ct);
}
return ret;
}
@@ -302,11 +302,11 @@ namespace AyaNova.Biz
//Log modification and save context
EventLogProcessor.LogEventToDatabaseAndSaveEntireContext(new Event(UserId, dbObj.Id, BizType, AyaEvent.Modified), ct);
EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, dbObj.Id, BizType, AyaEvent.Modified), ct);
SearchIndex(dbObj, false);
TagUtil.ProcessUpdateTagsInRepository(ct, dbObj.Tags, SnapshotOfOriginalDBObj.Tags);
TagUtil.ProcessUpdateTagsInRepositoryAsync(ct, dbObj.Tags, SnapshotOfOriginalDBObj.Tags);
return true;
}
@@ -339,10 +339,10 @@ namespace AyaNova.Biz
return false;
//Log modification and save context
EventLogProcessor.LogEventToDatabaseAndSaveEntireContext(new Event(UserId, dbObj.Id, BizType, AyaEvent.Modified), ct);
EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, dbObj.Id, BizType, AyaEvent.Modified), ct);
SearchIndex(dbObj, false);
TagUtil.ProcessUpdateTagsInRepository(ct, dbObj.Tags, SnapshotOfOriginalDBObj.Tags);
TagUtil.ProcessUpdateTagsInRepositoryAsync(ct, dbObj.Tags, SnapshotOfOriginalDBObj.Tags);
return true;
}
@@ -379,10 +379,10 @@ namespace AyaNova.Biz
ct.Database.ExecuteSqlInterpolated($"delete from auseroptions where userid={dbObj.Id}");
EventLogProcessor.DeleteObject(UserId, BizType, dbObj.Id, dbObj.Name, ct);
EventLogProcessor.DeleteObjectLogAsync(UserId, BizType, dbObj.Id, dbObj.Name, ct);
ct.SaveChanges();
Search.ProcessDeletedObjectKeywords(dbObj.Id, BizType);
TagUtil.ProcessDeleteTagsInRepository(ct, dbObj.Tags);
TagUtil.ProcessDeleteTagsInRepositoryAsync(ct, dbObj.Tags);
return true;
}

View File

@@ -59,7 +59,7 @@ namespace AyaNova.Biz
ct.SaveChanges();
//Log
EventLogProcessor.LogEventToDatabaseAndSaveEntireContext(new Event(UserId, dbObj.Id, AyaType.UserOptions, AyaEvent.Modified), ct);
EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, dbObj.Id, AyaType.UserOptions, AyaEvent.Modified), ct);
return true;
}
@@ -79,7 +79,7 @@ namespace AyaNova.Biz
ct.SaveChanges();
//Log
EventLogProcessor.LogEventToDatabaseAndSaveEntireContext(new Event(UserId, dbObj.Id, AyaType.UserOptions, AyaEvent.Modified), ct);
EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, dbObj.Id, AyaType.UserOptions, AyaEvent.Modified), ct);
return true;
}

View File

@@ -56,7 +56,7 @@ namespace AyaNova.Biz
if (log && ret != null)
{
//Log
EventLogProcessor.LogEventToDatabaseAndSaveEntireContext(new Event(UserId, fetchId, BizType, AyaEvent.Retrieved), ct);
EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, fetchId, BizType, AyaEvent.Retrieved), ct);
}
return ret;
}
@@ -66,7 +66,7 @@ namespace AyaNova.Biz
//CREATE
//Called from route and also seeder
internal Widget Create(Widget inObj)
internal async Task<Widget> CreateAsync(Widget inObj)
{
Validate(inObj, null);
if (HasErrors)
@@ -81,57 +81,20 @@ namespace AyaNova.Biz
outObj.Tags = TagUtil.NormalizeTags(outObj.Tags);
outObj.CustomFields = JsonUtil.CompactJson(outObj.CustomFields);
//Save to db
//add syncronously and don't save but let the log save
//THIS SAVED 1 SECOND OUT OF 22 for seeding 500 widgets
ct.Widget.Add(outObj);
//Save to db
await ct.Widget.AddAsync(outObj);
await ct.SaveChangesAsync();
//Handle child and associated items:
EventLogProcessor.LogEventToDatabaseAndSaveEntireContext(new Event(UserId, outObj.Id, BizType, AyaEvent.Created), ct);
//This takes 16 seconds out of 22 when seeding 500 widgets
SearchIndex(outObj, true);
//This takes 2 seconds out of 22 when seeding 500 widgets
TagUtil.ProcessUpdateTagsInRepository(ct, outObj.Tags, null);
EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, outObj.Id, BizType, AyaEvent.Created), ct);
SearchIndex(outObj, true);
TagUtil.ProcessUpdateTagsInRepositoryAsync(ct, outObj.Tags, null);
return outObj;
}
}
// //Internal version for seeding
// internal Widget Create(AyContext TempContext, Widget inObj)
// {
// Validate(inObj, null);
// if (HasErrors)
// return null;
// else
// {
// //do stuff with widget
// Widget outObj = inObj;
// //Test get serial id visible id number from generator
// outObj.Serial = ServerBootConfig.WIDGET_SERIAL.GetNext();
// outObj.Tags = TagUtil.NormalizeTags(outObj.Tags);
// outObj.CustomFields = JsonUtil.CompactJson(outObj.CustomFields);
// TempContext.Widget.Add(outObj);
// TempContext.SaveChanges();
// //Handle child and associated items:
// EventLogProcessor.LogEventToDatabaseAndSaveEntireContext(new Event(UserId, outObj.Id, BizType, AyaEvent.Created), TempContext);
// SearchIndex(outObj, true);
// TagUtil.ProcessUpdateTagsInRepository(TempContext, outObj.Tags, null);
// return outObj;
// }
// }
////////////////////////////////////////////////////////////////////////////////////////////////
//DUPLICATE
@@ -153,9 +116,9 @@ namespace AyaNova.Biz
await ct.SaveChangesAsync();
//Handle child and associated items:
EventLogProcessor.LogEventToDatabaseAndSaveEntireContext(new Event(UserId, outObj.Id, BizType, AyaEvent.Created), ct);
EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, outObj.Id, BizType, AyaEvent.Created), ct);
SearchIndex(outObj, true);
TagUtil.ProcessUpdateTagsInRepository(ct, outObj.Tags, null);
TagUtil.ProcessUpdateTagsInRepositoryAsync(ct, outObj.Tags, null);
return outObj;
}
@@ -188,9 +151,9 @@ namespace AyaNova.Biz
return false;
//Log event and save context
EventLogProcessor.LogEventToDatabaseAndSaveEntireContext(new Event(UserId, dbObj.Id, BizType, AyaEvent.Modified), ct);
EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, dbObj.Id, BizType, AyaEvent.Modified), ct);
SearchIndex(dbObj, false);
TagUtil.ProcessUpdateTagsInRepository(ct, dbObj.Tags, SnapshotOfOriginalDBObj.Tags);
TagUtil.ProcessUpdateTagsInRepositoryAsync(ct, dbObj.Tags, SnapshotOfOriginalDBObj.Tags);
return true;
}
@@ -218,10 +181,10 @@ namespace AyaNova.Biz
return false;
//Log event and save context
EventLogProcessor.LogEventToDatabaseAndSaveEntireContext(new Event(UserId, dbObj.Id, BizType, AyaEvent.Modified), ct);
EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, dbObj.Id, BizType, AyaEvent.Modified), ct);
SearchIndex(dbObj, false);
TagUtil.ProcessUpdateTagsInRepository(ct, dbObj.Tags, SnapshotOfOriginalDBObj.Tags);
TagUtil.ProcessUpdateTagsInRepositoryAsync(ct, dbObj.Tags, SnapshotOfOriginalDBObj.Tags);
return true;
}
@@ -256,10 +219,10 @@ namespace AyaNova.Biz
ct.SaveChanges();
//Log event and save context
EventLogProcessor.DeleteObject(UserId, BizType, dbObj.Id, dbObj.Name, ct);
EventLogProcessor.DeleteObjectLogAsync(UserId, BizType, dbObj.Id, dbObj.Name, ct);
ct.SaveChanges();
Search.ProcessDeletedObjectKeywords(dbObj.Id, BizType);
TagUtil.ProcessDeleteTagsInRepository(ct, dbObj.Tags);
TagUtil.ProcessDeleteTagsInRepositoryAsync(ct, dbObj.Tags);
return true;
}

View File

@@ -399,6 +399,8 @@ namespace AyaNova.Util
}
finally
{
//TODO: fully async: watch the job and don't turn the state back until the job is done?
log.LogInformation($"Seeder: setting server state back to {wasServerState.ToString()}");
apiServerState.SetState(wasServerState, wasReason);
}
@@ -570,22 +572,6 @@ namespace AyaNova.Util
//
public static void GenSeedWidget(ILogger log, int count)
{
//COMMIT BEFORE GOING NON ASYNC AGAIN TO SEE IF MEDIUM 500 WIDGETS STILL TAKES SO LONG:
//ASYNC CACHED STUFF 2020-01-23 15:58:31.1619|INFO|Seeder|500 Widgets seeded in 54890 ms
//NON ASYNC ORIGINAL METHOD 2020-01-23 16:19:59.9131|INFO|Seeder|500 Widgets seeded in 51442 ms
//NON ASYNC HERE BUT CALLING ASYNC CREATE IN WIDGET: 2020-01-23 16:23:58.9478|INFO|Seeder|500 Widgets seeded in 53362 ms
//NOT CALLING SAVE ON WIDGET BUT DOING ALL OTHER CODE: 2020-01-23 16:25:45.0293|INFO|Seeder|500 Widgets seeded in 30 ms
//So slowness is all in the save code, let's see whats what there...
// first tried not caching teh widgetbiz object: 2020-01-23 16:28:58.0876|INFO|Seeder|500 Widgets seeded in 53577 ms
//so that's pointless to cache it
//ONE LAST THING IN HERE, trying *NOT* caching the db context and create each time: 2020-01-23 16:32:13.8966|INFO|Seeder|500 Widgets seeded in 22679 ms
// - Holy shit, that's back to where it was a few days ago, so for some reason using the same context over and over is slowing shit down drastically
// ripping that out now.
//OK, making changes in CREATE code in widgetbiz
//First removed extra save call and async db access shaved off a second
//the commented out the Search indexer and it dropped from 22 seconds to 4.5!!!!
//So the search indexing code is super fucking slow 2020-01-23 16:45:20.9518|INFO|Seeder|500 Widgets seeded in 4572 ms
var f = new Bogus.Faker();