8000 Speed up resource updates when there are no matching webhooks by SpecLad · Pull Request #7553 · cvat-ai/cvat · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Speed up resource updates when there are no matching webhooks #7553

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

Merged
merged 1 commit into from
Mar 11, 2024

Conversation

SpecLad
Copy link
Contributor
@SpecLad SpecLad commented Mar 5, 2024

Motivation and context

The signal handling code in cvat.apps.webhooks.signals always fetches the old version of the resource from the database and serializes it. But if no webhook is defined for the current resource, this work is pointless.

Select the webhooks first, and only then (if necessary) serialize the old resource. Also, move the diffing of the old and new versions to the post_save signal handler, to avoid serializing the new version a second time. This leads to a considerable speedup for resources with complicated serializers, such as tasks and jobs, when no webhooks are attached. In my experiments, saving of annotations was sped up by 20-25% with this patch.

This patch also makes the signal handlers more hygienic with the use of temporary attributes. Both the attributes it uses are now prefixed with _webhooks to avoid collisions, and removed after they are used.

How has this been tested?

I think the existing tests are sufficient to cover this.

Checklist

  • I submit my changes into the develop branch
  • I have created a changelog fragment
  • [ ] I have updated the documentation accordingly
  • [ ] I have added tests to cover my changes
  • [ ] I have linked related issues (see GitHub docs)
  • [ ] I have increased versions of npm packages if it is necessary
    (cvat-canvas,
    cvat-core,
    cvat-data and
    cvat-ui)

License

  • I submit my code changes under the same MIT License that covers the project.
    Feel free to contact the maintainers if that's a concern.

@SpecLad
Copy link
Contributor Author
SpecLad commented Mar 5, 2024

/check

Copy link
Contributor
github-actions bot commented Mar 5, 2024

❌ Some checks failed
📄 See logs here

Copy link
Contributor
github-actions bot commented Mar 5, 2024

✔️ All checks completed successfully
📄 See logs here

@SpecLad SpecLad force-pushed the webhooks-lazy-rendering branch from ca4adc7 to 505bbd2 Compare March 5, 2024 15:26
@SpecLad SpecLad changed the title WIP Calculate diff for webhooks lazily Speed up resource updates when there are no matching webhooks Mar 5, 2024
@SpecLad SpecLad marked this pull request as ready for review March 5, 2024 15:29
Copy link
codecov bot commented Mar 5, 2024

Codecov Report

Merging #7553 (648a842) into develop (14b592f) will increase coverage by 0.02%.
Report is 10 commits behind head on develop.
The diff coverage is 100.00%.

Additional details and impacted files
@@             Coverage Diff             @@
##           develop    #7553      +/-   ##
===========================================
+ Coverage    83.53%   83.55%   +0.02%     
===========================================
  Files          372      372              
  Lines        39661    39710      +49     
  Branches      3724     3729       +5     
===========================================
+ Hits         33130    33180      +50     
+ Misses        6531     6530       -1     
Components Coverage Δ
cvat-ui 79.46% <ø> (+0.03%) ⬆️
cvat-server 87.32% <100.00%> (+0.01%) ⬆️

@SpecLad SpecLad requested review from Marishka17 and removed request for nmanovic and Marishka17 March 6, 2024 16:55
old_instance = sender.objects.get(pk=instance.pk)
created = False
except ObjectDoesNotExist:
created = True
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need to handle it like this? If instance.pk is not None but the instance does not exist anymore, it means that the object was deleted before this code was executed. After initializing created = True the code below will check the wrong event "created:object". IMHO, we should stop handling here (return from function).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If instance.pk is not None but the instance does not exist anymore,

I wasn't thinking of this case, but rather of the case where an object is created with a preset public key value. I don't think we do that anywhere right now, but I figured the code should be robust and handle that situation.

But also, in the case you describe, I don't see how my code is incorrect? If the instance was deleted prior the call to save, then .save will re-create it, so created:* seems like the correct event.

Comment on lines 192 to 202
old_data = instance._webhooks_old_data
del instance._webhooks_old_data

if not created and old_data is not None:
diff = get_instance_diff(old_data=old_data, data=serializer.data)

if diff:
data["before_update"] = {
attr: value["old_value"]
for attr, value in diff.items()
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably it will be better to set _webhooks_old_data attribute only when object was updated and _webhooks_selected_webhooks is not empty

Suggested change
old_data = instance._webhooks_old_data
del instance._webhooks_old_data
if not created and old_data is not None:
diff = get_instance_diff(old_data=old_data, data=serializer.data)
if diff:
data["before_update"] = {
attr: value["old_value"]
for attr, value in diff.items()
}
if not created and (old_data := getattr(instance, '_webhooks_old_data', None)):
del instance._webhooks_old_data
if diff := get_instance_diff(old_data=old_data, data=serializer.data):
data["before_update"] = {
attr: value["old_value"]
for attr, value in diff.items()
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought through this code again, and I decided to update it in a different way. I want to make sure that the value of created is consistent between the pre_save and post_save handlers, so I now initialize it based on the value of _webhooks_old_data.

The signal handling code in `cvat.apps.webhooks.signals` always fetches
the old version of the resource from the database and serializes it. But if
no webhook is defined for the current resource, this work is pointless.

Select the webhooks first, and only then (if necessary) serialize the old
resource. Also, move the diffing of the old and new versions to the
`post_save` signal handler, to avoid serializing the new version a second
time. This leads to a considerable speedup for resources with complicated
serializers, such as tasks and jobs, when no webhooks are attached.

This patch also makes the signal handlers more hygienic with the use of
temporary attributes. Both the attributes it uses are now prefixed with
`_webhooks` to avoid collisions, and removed after they are used.
@SpecLad SpecLad force-pushed the webhooks-lazy-rendering branch from 505bbd2 to 648a842 Compare March 8, 2024 11:36
@SpecLad SpecLad merged commit c8376b7 into cvat-ai:develop Mar 11, 2024
@SpecLad SpecLad deleted the webhooks-lazy-rendering branch March 11, 2024 10:46
@cvat-bot cvat-bot bot mentioned this pull request Mar 11, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants
0