-
-
Notifications
You must be signed in to change notification settings - Fork 218
[change] Reduce sortedm2m queries for templates #204 #1010
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
[change] Reduce sortedm2m queries for templates #204 #1010
Conversation
Known Issues:
|
b7e4d02
to
46f4a12
Compare
Hi @DragnEmperor |
d29a35b
to
9088448
Compare
As now we are fetching templates via js only, I have done some modifications for the failing test cases.
|
@@ -479,15 +479,6 @@ def test_device_organization_fk_autocomplete_view(self): | |||
hidden=[data['org2'].name, data['inactive'].name], | |||
) | |||
|
|||
def test_device_templates_m2m_queryset(self): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please mention in description why these tests are removed from here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi Kapil,
I have added in the commit description and in the comment above the reason for removing these test cases.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are you asserting the number of queries to verify the optimizations? Or what are you doing to ensure that the optimization is effective within automated tests?
@@ -1626,89 +1567,6 @@ def test_add_vpn(self): | |||
response, 'value="openwisp_controller.vpn_backends.OpenVpn" selected' | |||
) | |||
|
|||
def test_vpn_clients_deleted(self): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why are these tests being moved?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As we are adding the templates via js so i migrated these tests to selenium tests. I have added this in conversation above. I will update the description of PR itself for more clarity.
Yes I have checked the queries and while there is an improvement its not much i think ( around 4-5 queries less now, some queries' results are cached so i am not exactly sure of the count) |
c98b148
to
4f85589
Compare
@nemesifier @pandafy
With the changes, templates are being added via js using |
# ensuring queries are consistent for different number of templates | ||
def test_templates_fetch_queries_1(self): | ||
config = self._create_config(organization=self._get_org()) | ||
self._verify_template_queries(config, 1) | ||
|
||
def test_templates_fetch_queries_5(self): | ||
config = self._create_config(organization=self._get_org()) | ||
self._verify_template_queries(config, 1) | ||
|
||
def test_templates_fetch_queries_10(self): | ||
config = self._create_config(organization=self._get_org()) | ||
self._verify_template_queries(config, 1) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@DragnEmperor can you help me understand why do we need three tests?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have added these checks to ensure that queries are not changed and remain the same irrespective of number of templates
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The count argument is 1
in all the tests. Is that correct?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes that was my mistake, these should be correct in new commit.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please merge with the latest master and run openwisp-qa-format
again.
I see some changes from other PRs that have already been merged which are showing up again here, I hope that updating on master and running openwisp-qa-format
fixes that, if not please look into resolving it as it makes reviewing tougher with no added benefits.
c8856a4
to
cb3aac4
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's one failing test: test_multiple_organization_templates
.
@DragnEmperor thank you for your effort! You can leave this to us now and focus on the other work you have.
.only("templates") | ||
.get(pk=config_id) | ||
.templates.filter(org_filters) | ||
.filter(**filter_options) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I spotted something that is worrying me: we aren't enforcing/asserting that this config is really assigned to a device which is related to organization_id
. In theory it would be possible to call an organization_id
which is valid and a config_id
which shouldn't be allowed.
So I think filter options should include device__organization_id=organization_id
, what do you think?
Watch out from query count increase due to this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider the following scenario:
There are two organizations: OrgA and OrgB. OrgA has a device that is linked to a configuration object.
A user attempts to change the organization of this device from OrgA to OrgB. At this point, the organization_id
URL keyword argument contains the UUID of OrgB. However, since the change hasn't been saved yet, the device object in the database is still associated with OrgA.
If we filter the Config
queryset using OrgB (based on your suggestion), it will raise a Config.DoesNotExist
error, because the configuration is still linked to OrgA. As a result, we won’t be able to retrieve information about the current state of shared configuration templates.
.only("templates") | ||
.get(pk=group_id) | ||
.templates.filter(org_filters) | ||
.filter(**filter_options) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's the value of filter_options
here? Can we add organization_id=organization_id
here?
if (isDeviceGroup() && !$(".add-form").length) { | ||
// Get the group id from the URL | ||
// TODO: This is fragile, consider using a more robust way to get the group id. | ||
var pathParts = window.location.pathname.split("/"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We are overriding /templates/admin/device_group/change_form.html
, so why don't we add the group ID there as an HTML element which is easy to retrieve here?
window._deviceGroup = true; | ||
window._deviceGroupId = "{{ original.pk }}"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We were already setting the _devieGroup
property here to determine whether the relevant_template,js script was loading from device page or device group page. I have updated the logic to pass the device group ID to the JS.
@nemesifier if you prefer an HTML element, I would update the code accordingly.
To remove queries generated by sortedm2m, 'formfield_for_manytomany' is overriden such that on page loads, we can get templates using 'get_relevant_templates'. Added device/group id to identify selected templates. Changes are made in JS to ensure templates are viewed and changes are saved as per initial behaviour. Ordering is not maintained. Closes openwisp#204 Signed-off-by: DragnEmperor <[email protected]>
Using the 'sort_value' of the 'through_model', created a subquery which annotates a sort_value and selected field to each template. The sort_value is used for ordering the templates and also for checking if template is selected or not using a large default value which happens if template is not selected for a device config or group. Signed-off-by: DragnEmperor <[email protected]>
As now templates are being loaded via js, normal tests were failing. For these failing tests, added relevant selenium tests. Modified `get-relevant_templates` to allow fetching templates during device creation by superuser and org users. Signed-off-by: DragnEmperor <[email protected]>
Added a test to assert the queries executed during templates fetch on device change page. Previous count of this fetch combined with `get_relevant_templates` was 26 due to template fetch query being duplicated. With new changes the count is down to 24. Signed-off-by: DragnEmperor <[email protected]>
The queries for fetching the templates with sorted in `get_relevant_templates` via Subquery, while were working, were a bit complex to understand for future. Fetching templates using config/devicegroup maintains sorting, making the fetching query much readable. Signed-off-by: DragnEmperor <[email protected]>
Formatted the changes as per the new QA checks and rules in `openwisp-qa-format`. For the tests inside `test_views` to work properly, made minor modifications in `get_relevant_templates`. Also fixed the type in template count in `test_templates_fetch_queries`. Signed-off-by: DragnEmperor <[email protected]>
c082f0e
to
b00bcc8
Compare
b00bcc8
to
b4d0b93
Compare
43899e1
to
ccdf7ea
Compare
Checklist
Reference to Existing Issue
Closes #204
Closes #1050
Description of Changes
To remove queries generated by sortedm2m, 'formfield_for_manytomany' is overridden such that on page load, we can get templates using 'get_relevant_templates'.
Added device/group id in 'get_relevant_templates' to identify selected templates. Changes are made in 'relevantTemplates.js' to ensure templates are viewed and changes are saved as per initial behavior.
As now we are fetching templates via js only, I have done some modifications for the failing test cases.
test_device_templates_m2m_queryset
there is a similar selenium test casetest_multiple_organization_templates
test_configuration_templates_removed
,test_vpn_clients_deleted
, have added new selenium test casestest_add_remove_templates
,test_vpn_clients_deleted
.