Monday, May 13, 2024
2 changes · 17.0
Enhancements to existing features
This update significantly speeds up the process of changing project settings (like billable status) when dealing with projects that have thousands of associated tasks and timesheets. The improvement optimizes how the system processes these changes, reducing the time from over 4 minutes to just over 1 minute—a 3.6x performance boost that directly improves user experience when managing large projects.
Original PR description
## Description The `onchange` triggered when changing the `allow_billable` setting of a large long living project with a high number of associated timesheets can take a quite a while. After…
## Description The `onchange` triggered when changing the `allow_billable` setting of a large long living project with a high number of associated timesheets can take a quite a while. After profiling, a significant portion of the bottleneck was coming from *frequent* calls to the `__hash__` function, called when initializing a new `set` in https://github.com/odoo/odoo/blob/cf9aa2a14761a417c641243fc0b2be121c387b46/odoo/models.py#L6838 Left Heavy profile:  ## Improvements - Invariant hoisting: the `set(self._ids)` can be lifted out of the lambda scope capture, passing only a reference to a local variable for all callsite of the lambda. This prevents the re-computation of `set(self._ids)` for each record in `cache_records` due to the linear iteration done by `filtered`. - `not isdisjoint` vs `intersection`: the lambda is checking for the existence of an intersection between 2 sets. But in python the `&` or `intersection` method *construct* a new instance of a `set`. In our case we don't care about the resulting intersection, only about the existence of it. We can improve the situation by inverting the logic using `not isdisjoint`, as `isdisjoint` is simpler internal implementation and doesn't construct any new set, it just checks for disjunction. - CPython `intersection`: https://github.com/python/cpython/blob/333c7dccd87c637d0b15cf81f9bbec28e39664fd/Objects/setobject.c#L1179-L1256 - CPython `isdisjoint`: https://github.com/python/cpython/blob/333c7dccd87c637d0b15cf81f9bbec28e39664fd/Objects/setobject.c#L1338-L1373 A local small `timeit` benchmark showed +- 25% faster performance in favor of `not isdisjoint`. ## Benchmark On a staging database (saas-17.1, blindly backported), the `onchange` triggered by setting a project `allow_billable` from `True` -> `False`, with 70k tasks, and 25k associated timesheets. | | Before | After | Speed Up | |---------|----------------------|---------------------|-------------| | Timings | 246.66 sec (4.1 min) | 66.83 sec (1.1 min) | 3.6x faster | ## Reference task-3872314 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Resolved issues and error corrections
This fix resolves a critical issue where event badge generation was causing website registrations to freeze indefinitely. The problem occurred when badge images weren't configured, causing the system to attempt unnecessary background image fetches that created database conflicts. With this fix, the badge generation process now works smoothly without blocking user registrations.
Original PR description
__Current behavior before commit:__ If the `badge_image` field of the event isn't set, the badge div's style defaults to `background-image: url();`. When `wkhtmltopdf` interprets this, it attempts to…
__Current behavior before commit:__ If the `badge_image` field of the event isn't set, the badge div's style defaults to `background-image: url();`. When `wkhtmltopdf` interprets this, it attempts to fetch the background image from the website's base URL. Consequently, each time the badge PDF is generated, `wkhtmltopdf` accesses the website's homepage, inadvertently altering the `website_visitor` table. If the badge PDF creation is triggered by a request from the website, it will lead to a deadlock due to simultaneous transactions on the same `website_visitor` row. __Description of the fix:__ Do not write the `background-image` instruction at all when `badge_image` is not set. __Steps to reproduce the issue on runbot:__ - Install `website_event` - Go to Email Templates > **Event: Registration Confirmation** > Settings - Put `Badge` in **Dynamic Reports** - Create a new Event and register to it on its website page -> The registration loads forever and it's impossible to go on any other page on the website opw-3884132