feat: optimize GetAccount for large number of policies and rules #4489
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.
Describe your changes
The policy rules are loaded one by one, for each policy. In a set-up with 480 policies, it generates 480 round trip to the database and a latency of about 500 ms. The fist change I propose here is therefore to load all the rules in one query, using a IN clause with the list of policy id's. This is very low risk and was tested "live" on my set-up.
The second change is low impact on the performance, it is just to avoid two times the same query which is silly. The ORM generates a select for all policies rules with the IN clause (exactly the same as my select). However the result of the select is not used, for some reason the ORM cannot attach it to the slice of rules pointers (hence the reason why it is done manually, as commented in the original code).
Because the code uses a generic "Preload(clause.Associations)" it is not possible to exclude one of the association to avoid this double select. Furthermore it seems a good practice to explicitly list the associations that should be preloaded, to have a more reliable behavior and better documented.
The refactored code produce the same account data on my set-up (large setup), I serialized the account in json and compared.
If requested I can a test in place for the GetAccount, the current seems very limitied (does not mirror the current schema).
I realize this change is important for large number of policies only, which might be an hedge case, but it is very low risk.
The saving is significant on my setup: from 600 -700 ms to 60 - 80ms. Of course I would prefer to have the change upstream than only in my setup.
Issue
4488
Stack
Checklist
Documentation
Select exactly one:
it is an internal optimization
Docs PR URL (required if "docs added" is checked)
Paste the PR link from https://github.com/netbirdio/docs here:
https://github.com/netbirdio/docs/pull/__