Repository navigation
Read audit names in one query per record type - #1000
Merged
Merged
Conversation
The end-of-request flush named every referenced record with its own query, one after another, while the staff member waited: a product with dozens of categories, attributes or tier prices took dozens of round trips. The references are now collected for all entries of the flush first and read with one $in query per record type (IAuditRecordReader.ReadMany); describing the entries then reads nothing. Inserted records keep the entity as their after state instead of being read back at the flush.
Comment on lines
+31
to
+33
| foreach (var value in values.Distinct()) | ||
| if (await Read(entityType, value, key, field) is { } record) | ||
| records[value] = record; |
Comment on lines
+53
to
+56
| catch (Exception) | ||
| { | ||
| //fails again when described | ||
| } |
Comment on lines
+71
to
+74
| catch (Exception) | ||
| { | ||
| //read one by one when described | ||
| } |
Comment on lines
+311
to
+314
| catch (Exception) | ||
| { | ||
| entry = null; | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Type: improvement
Issue
Follow-up to #999. Every staff save ends with the audit flush, and the request waits for it. To show "name (id)" instead of a bare id, the flush named every referenced record with its own query, one after another (
AuditReferences.Describe,NameElements,LinkOwner). A change touching many list elements - a product with dozens of categories, specification attributes or tier prices, a copied product, an import - paid one database round trip per referenced record before the response went out.Inserted records were also read back from the database at the flush, although the inserted entity is the stored state.
Storefront traffic is not affected either way: the tracker is active only for staff requests.
Solution
AuditReferences.Prefetchwalks all entries of the flush first and only notes the records they need; they are then read with one$inquery per record type and field (IAuditRecordReader.ReadMany, only the name/store field projected). Describing the entries afterwards reads nothing. A record seen by several entries is read once per flush (before: cached per name, not per record).RepositoryAudit.Insertedhands the inserted entity to the tracker (as a full update already does), so the flush no longer reads inserted records back.ReadManyreads the records one by one.Breaking changes
IAuditRecordReaderhas a new memberReadMany(its implementations areMongoAuditRecordReaderandLiteDBAuditRecordReader).AuditReferencesgetsPrefetchandDescribeEntry. Nothing stored changes.Testing
Grand.Infrastructure.Tests279 and the audit tests ofGrand.Web.Admin.Testspass, with new tests for one read per record type (names, element names and owner stores), the fallback when the batched read fails, an insert not read back, and the LiteDBReadMany.MongoAuditRecordReader.ReadManychecked against a local MongoDB: by id, by a numeric key (OrderStatus.StatusId), only the requested field projected, missing ids left out.