diff --git a/devdocs/todo.txt b/devdocs/todo.txt index 2a2c83f2..f338e734 100644 --- a/devdocs/todo.txt +++ b/devdocs/todo.txt @@ -8,6 +8,11 @@ TODO: Ensure scaleability by checking for performance issues now before replicat - 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 +TODO: look for any line of code that does this or similar: await Task.CompletedTask; + - Needs to be turned into a true async function or not an async function + +TODO: Look at any of my middleware code as it's a HOT PATH, make sure it's async db access etc and nothing slowing it down + 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. diff --git a/server/AyaNova/ControllerHelpers/ApiUploadProcessor.cs b/server/AyaNova/ControllerHelpers/ApiUploadProcessor.cs index 813b9ffc..edddd5df 100644 --- a/server/AyaNova/ControllerHelpers/ApiUploadProcessor.cs +++ b/server/AyaNova/ControllerHelpers/ApiUploadProcessor.cs @@ -29,9 +29,9 @@ namespace AyaNova.Api.ControllerHelpers /// /// /// - internal static async Task ProcessAttachmentUpload(Microsoft.AspNetCore.Http.HttpContext httpContext) + internal static async Task ProcessAttachmentUploadAsync(Microsoft.AspNetCore.Http.HttpContext httpContext) { - return await ProcessUpload(httpContext, true); + return await ProcessUploadAsync(httpContext, true); } @@ -41,9 +41,9 @@ namespace AyaNova.Api.ControllerHelpers /// /// /// - internal static async Task ProcessUtilityFileUpload(Microsoft.AspNetCore.Http.HttpContext httpContext) + internal static async Task ProcessUtilityFileUploadAsync(Microsoft.AspNetCore.Http.HttpContext httpContext) { - return await ProcessUpload(httpContext, false); + return await ProcessUploadAsync(httpContext, false); } /// @@ -52,7 +52,7 @@ namespace AyaNova.Api.ControllerHelpers /// /// /// list of files and form field data (if present) - private static async Task ProcessUpload(Microsoft.AspNetCore.Http.HttpContext httpContext, bool processAsAttachment) + private static async Task ProcessUploadAsync(Microsoft.AspNetCore.Http.HttpContext httpContext, bool processAsAttachment) { ApiUploadedFilesResult result = new ApiUploadedFilesResult(); diff --git a/server/AyaNova/Controllers/AttachmentController.cs b/server/AyaNova/Controllers/AttachmentController.cs index 12823d1f..923f8ed9 100644 --- a/server/AyaNova/Controllers/AttachmentController.cs +++ b/server/AyaNova/Controllers/AttachmentController.cs @@ -71,7 +71,7 @@ namespace AyaNova.Api.Controllers /// /// Current download token for user [HttpGet("DownloadToken")] - public async Task GetDownloadToken() + public async Task GetDownloadTokenAsync() { if (!serverState.IsOpen) return StatusCode(503, new ApiErrorResponse(ApiErrorCode.API_CLOSED, null, serverState.Reason)); @@ -122,7 +122,7 @@ namespace AyaNova.Api.Controllers [HttpPost] [DisableFormValueModelBinding] [RequestSizeLimit(10737418241)]//10737418240 = 10gb https://github.com/aspnet/Announcements/issues/267 - public async Task Upload() + public async Task UploadAsync() { //Adapted from the example found here: https://docs.microsoft.com/en-us/aspnet/core/mvc/models/file-uploads#uploading-large-files-with-streaming @@ -136,7 +136,7 @@ namespace AyaNova.Api.Controllers if (!MultipartRequestHelper.IsMultipartContentType(Request.ContentType)) return BadRequest(new ApiErrorResponse(ApiErrorCode.INVALID_OPERATION, "FileUploadAttempt", $"Expected a multipart request, but got {Request.ContentType}")); - var uploadFormData = await ApiUploadProcessor.ProcessAttachmentUpload(HttpContext); + var uploadFormData = await ApiUploadProcessor.ProcessAttachmentUploadAsync(HttpContext); bool badRequest = false; string AttachToObjectType = string.Empty; @@ -272,7 +272,7 @@ namespace AyaNova.Api.Controllers /// /// Ok [HttpDelete("{id}")] - public async Task DeleteAttachment([FromRoute] long id) + public async Task DeleteAttachmentAsync([FromRoute] long id) { if (!serverState.IsOpen) @@ -321,7 +321,7 @@ namespace AyaNova.Api.Controllers /// /// [HttpGet("download/{id}")] - public async Task Download([FromRoute] long id, [FromQuery] string dlkey) + public async Task DownloadAsync([FromRoute] long id, [FromQuery] string dlkey) { //copied from Rockfish //https://dotnetcoretutorials.com/2017/03/12/uploading-files-asp-net-core/ diff --git a/server/AyaNova/Controllers/ImportAyaNova7Controller.cs b/server/AyaNova/Controllers/ImportAyaNova7Controller.cs index 1d980b6e..8c72a929 100644 --- a/server/AyaNova/Controllers/ImportAyaNova7Controller.cs +++ b/server/AyaNova/Controllers/ImportAyaNova7Controller.cs @@ -86,7 +86,7 @@ namespace AyaNova.Api.Controllers return BadRequest(new ApiErrorResponse(ApiErrorCode.INVALID_OPERATION, "FileUploadAttempt", $"Expected a multipart request, but got {Request.ContentType}")); } - var uploadFormData = await ApiUploadProcessor.ProcessUtilityFileUpload(HttpContext); + var uploadFormData = await ApiUploadProcessor.ProcessUtilityFileUploadAsync(HttpContext); bool badRequest = false; diff --git a/server/AyaNova/Controllers/SearchController.cs b/server/AyaNova/Controllers/SearchController.cs index c48c3f15..621e9f1c 100644 --- a/server/AyaNova/Controllers/SearchController.cs +++ b/server/AyaNova/Controllers/SearchController.cs @@ -66,7 +66,7 @@ namespace AyaNova.Api.Controllers } //Do the search - var SearchResults = await Search.DoSearch(ct, UserLocaleIdFromContext.Id(HttpContext.Items), UserRolesFromContext.Roles(HttpContext.Items), searchParams); + var SearchResults = await Search.DoSearchAsync(ct, UserLocaleIdFromContext.Id(HttpContext.Items), UserRolesFromContext.Roles(HttpContext.Items), searchParams); return Ok(ApiOkResponse.Response(SearchResults, true)); } diff --git a/server/AyaNova/biz/BizObjectExistsInDatabase.cs b/server/AyaNova/biz/BizObjectExistsInDatabase.cs index a3c31050..ae880391 100644 --- a/server/AyaNova/biz/BizObjectExistsInDatabase.cs +++ b/server/AyaNova/biz/BizObjectExistsInDatabase.cs @@ -20,9 +20,9 @@ namespace AyaNova.Biz { //THIS IS THE METHOD CALLED BY THE ATTACHMENT CONTROLLER - internal static bool Exists(AyaTypeId tid) + internal static async Task Exists(AyaTypeId tid) { - return Exists(tid.ObjectType, tid.ObjectId); + return await Exists(tid.ObjectType, tid.ObjectId); } diff --git a/server/AyaNova/biz/LocaleBiz.cs b/server/AyaNova/biz/LocaleBiz.cs index 0d9eabe9..0afb1ef3 100644 --- a/server/AyaNova/biz/LocaleBiz.cs +++ b/server/AyaNova/biz/LocaleBiz.cs @@ -54,7 +54,7 @@ namespace AyaNova.Biz AddError(ApiErrorCode.VALIDATION_INVALID_VALUE, "Id", "Source locale id does not exist"); //Ensure name is unique and not too long and not empty - Validate(inObj.Name, true); + ValidateAsync(inObj.Name, true); if (HasErrors) return null; @@ -262,7 +262,7 @@ namespace AyaNova.Biz //this will allow EF to check it out ct.Entry(dbObj).OriginalValues["ConcurrencyToken"] = inObj.ConcurrencyToken; - Validate(dbObj.Name, false); + ValidateAsync(dbObj.Name, false); if (HasErrors) return false; @@ -284,7 +284,7 @@ namespace AyaNova.Biz internal bool Delete(Locale dbObj) { //Determine if the object can be deleted, do the deletion tentatively - ValidateCanDelete(dbObj); + ValidateCanDeleteAsync(dbObj); if (HasErrors) return false; ct.Locale.Remove(dbObj); @@ -297,7 +297,7 @@ namespace AyaNova.Biz // //Can save or update? - private async Task Validate(string inObjName, bool isNew) + private async Task ValidateAsync(string inObjName, bool isNew) { //run validation and biz rules @@ -318,7 +318,7 @@ namespace AyaNova.Biz //Can delete? - private void ValidateCanDelete(Locale inObj) + private async Task ValidateCanDeleteAsync(Locale inObj) { //Decided to short circuit these; if there is one issue then return immediately (fail fast rule) @@ -336,7 +336,7 @@ namespace AyaNova.Biz } //See if any users exist with this locale selected in which case it's not deleteable - if (ct.User.Any(e => e.LocaleId == inObj.Id)) + if (await ct.User.AnyAsync(e => e.LocaleId == inObj.Id)) { AddError(ApiErrorCode.VALIDATION_REFERENTIAL_INTEGRITY, "object", "Can't be deleted in use by one or more Users"); return; diff --git a/server/AyaNova/biz/Search.cs b/server/AyaNova/biz/Search.cs index f72f69b9..0f56601d 100644 --- a/server/AyaNova/biz/Search.cs +++ b/server/AyaNova/biz/Search.cs @@ -107,7 +107,7 @@ namespace AyaNova.Biz } - public static async Task DoSearch(AyContext ct, long localeId, AuthorizationRoles currentUserRoles, SearchRequestParameters searchParameters) + public static async Task DoSearchAsync(AyContext ct, long localeId, AuthorizationRoles currentUserRoles, SearchRequestParameters searchParameters) { var ReturnObject = new SearchReturnObject(); diff --git a/server/AyaNova/biz/TrialBiz.cs b/server/AyaNova/biz/TrialBiz.cs index 25e1e71e..9948535d 100644 --- a/server/AyaNova/biz/TrialBiz.cs +++ b/server/AyaNova/biz/TrialBiz.cs @@ -42,7 +42,7 @@ namespace AyaNova.Biz switch (job.JobType) { case JobType.SeedTestData: - await ProcessSeedTestData(job); + await ProcessSeedTestDataAsync(job); // ProcessSeedTestData(job); break; default: @@ -55,7 +55,7 @@ namespace AyaNova.Biz /// Handle the job /// /// - private async Task ProcessSeedTestData(OpsJob job) + private async Task ProcessSeedTestDataAsync(OpsJob job) {// //NOTE: If this code throws an exception the caller will automatically set the job to failed and log the exeption so //basically any error condition during job processing should throw up an exception if it can't be handled @@ -74,7 +74,8 @@ namespace AyaNova.Biz Seeder.SeedDatabase(seedLevel, job.GId, timeZoneOffset); JobsBiz.LogJob(job.GId, "Finished.", ct); JobsBiz.UpdateJobStatus(job.GId, JobStatus.Completed, ct); - await Task.CompletedTask; + NO, BAD! Convert the logjob etc above to async + //await Task.CompletedTask; }