/// <summary> /// Retry when an Exception has occured /// </summary> /// <param name="updateStatusContent"></param> /// <param name="e">Exception</param> private async Task RetrySaveChangesAsync(FileIndexItem updateStatusContent, Exception e) { _logger?.LogInformation(e, "[RetrySaveChangesAsync] retry catch-ed exception "); _logger?.LogInformation("[RetrySaveChangesAsync] next retry ~>"); async Task LocalRetrySaveChangesAsyncQuery() { // InvalidOperationException: A second operation started on this context before a previous operation completed. // https://go.microsoft.com/fwlink/?linkid=2097913 await Task.Delay(5); var context = new InjectServiceScope(_scopeFactory).Context(); context.Attach(updateStatusContent).State = EntityState.Modified; await context.SaveChangesAsync(); context.Attach(updateStatusContent).State = EntityState.Detached; await context.DisposeAsync(); } try { await LocalRetrySaveChangesAsyncQuery(); } catch (MySqlException mySqlException) { _logger?.LogError(mySqlException, "[RetrySaveChangesAsync] MySqlException catch-ed and retry again"); await LocalRetrySaveChangesAsyncQuery(); } catch (DbUpdateConcurrencyException concurrencyException) { SolveConcurrency.SolveConcurrencyExceptionLoop(concurrencyException.Entries); try { _logger?.LogInformation("[RetrySaveChangesAsync] SolveConcurrencyExceptionLoop disposed item"); var context = new InjectServiceScope(_scopeFactory).Context(); await context.SaveChangesAsync(); } catch (DbUpdateConcurrencyException retry2Exception) { _logger?.LogInformation(retry2Exception, "[RetrySaveChangesAsync] save failed after DbUpdateConcurrencyException"); } } }
/// <summary> /// Get all objects inside a folder /// </summary> /// <param name="filePaths">parent paths</param> /// <param name="fallbackDelay">delay when fallback</param> /// <returns>list of all objects inside the folder</returns> public async Task <List <FileIndexItem> > GetAllObjectsAsync(List <string> filePaths, int fallbackDelay = 5000) { if (!filePaths.Any()) { return(new List <FileIndexItem>()); } async Task <List <FileIndexItem> > LocalGetAllObjectsAsync() { var dbContext = new InjectServiceScope(_scopeFactory).Context(); var result = FormatOk(await GetAllObjectsQuery(dbContext, filePaths) .ToListAsync()); await dbContext.DisposeAsync(); return(result); } try { return(FormatOk(await GetAllObjectsQuery(_context, filePaths) .ToListAsync())); } catch (ObjectDisposedException) { return(await LocalGetAllObjectsAsync()); } catch (InvalidOperationException) { // System.InvalidOperationException: ExecuteReader can only be called when the connection is open. return(await LocalGetAllObjectsAsync()); } catch (MySqlConnector.MySqlException exception) { _logger.LogError(exception, $"catch-ed mysql error [next delay {fallbackDelay}]"); await Task.Delay(fallbackDelay); return(await LocalGetAllObjectsAsync()); } }