Skip to content
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

[14.0][ADD] web_assets_warmup #2614

Merged
merged 2 commits into from
Jan 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions setup/web_assets_warmup/odoo/addons/web_assets_warmup
6 changes: 6 additions & 0 deletions setup/web_assets_warmup/setup.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import setuptools

setuptools.setup(
setup_requires=['setuptools-odoo'],
odoo_addon=True,
)
Empty file added web_assets_warmup/README.rst
Empty file.
2 changes: 2 additions & 0 deletions web_assets_warmup/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
from . import models
from .hooks import post_load_hook
17 changes: 17 additions & 0 deletions web_assets_warmup/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Copyright 2020 Camptocamp SA
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl)
{
"name": "Generate assets when Odoo starts",
"summary": "Ensure that assets are generated when Odoo starts.",
"version": "14.0.1.0.0",
"category": "Hidden",
"author": "Camptocamp, Odoo Community Association (OCA)",
"license": "AGPL-3",
"depends": [
"web",
],
"website": "https://github.com/OCA/web",
"data": ["data/ir_cron.xml"],
"post_load": "post_load_hook",
"installable": True,
}
22 changes: 22 additions & 0 deletions web_assets_warmup/data/ir_cron.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8" ?>
<!-- Copyright 2020 Camptocamp SA
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -->
<odoo noupdate="1">

<record model="ir.cron" id="cron_generate_assets">
<field name='name'>Generate report assets</field>
<field name='interval_number'>1</field>
<field name='interval_type'>months</field>
<field name="numbercall">-1</field>
<field name="active" eval="True" />
<field name="doall" eval="False" />
<field
name="nextcall"
eval="(datetime.now() + timedelta(minutes=1)).strftime('%Y-%m-%d %H:%M:00')"
/>
<field name="model_id" ref="base.model_ir_actions_report" />
<field name="state">code</field>
<field name="code">model.cron_generate_assets()</field>
</record>

</odoo>
70 changes: 70 additions & 0 deletions web_assets_warmup/hooks.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
# Copyright 2020 Camptocamp SA
# Copyright 2023 Michael Tietz (MT Software) <mtietz@mt-software.de>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl)

import logging
import os

import psycopg2

from odoo import fields, registry

logger = logging.getLogger(__name__)


def active_cron_assets():
"""Plan the next execution of the cron responsible to generate assets."""
if os.environ.get("RUNNING_ENV") == "dev":
return

Check warning on line 18 in web_assets_warmup/hooks.py

View check run for this annotation

Codecov / codecov/patch

web_assets_warmup/hooks.py#L18

Added line #L18 was not covered by tests
dbname = os.environ.get("DB_NAME")
Copy link
Contributor

Choose a reason for hiding this comment

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

DB_NAME is not a core odoo var. The db name should be take from config.
Not blocking, you can fix this later as this one is waiting since quite some time.

reg = registry(dbname)
with reg.cursor() as cr:
cron_module, cron_ref = "web_assets_warmup", "cron_generate_assets"
query = """
SELECT model, res_id
FROM ir_model_data
WHERE module=%s
AND name=%s;
"""
args = (cron_module, cron_ref)
cr.execute(query, args)
row = cr.fetchone()
# post_load hook is called before the update of the module so the
# ir_cron record doesn't exist on first install
if row:
model, res_id = row

Check warning on line 35 in web_assets_warmup/hooks.py

View check run for this annotation

Codecov / codecov/patch

web_assets_warmup/hooks.py#L35

Added line #L35 was not covered by tests
if model != "ir.cron":
return

Check warning on line 37 in web_assets_warmup/hooks.py

View check run for this annotation

Codecov / codecov/patch

web_assets_warmup/hooks.py#L37

Added line #L37 was not covered by tests
# if there is already someone doing the same or already being executed
# we can skip the update of ir_cron
try:
with cr.savepoint():
cr.execute(

Check warning on line 42 in web_assets_warmup/hooks.py

View check run for this annotation

Codecov / codecov/patch

web_assets_warmup/hooks.py#L40-L42

Added lines #L40 - L42 were not covered by tests
"SELECT * FROM ir_cron WHERE id = %s FOR UPDATE NOWAIT;",
(res_id,),
)
query = """

Check warning on line 46 in web_assets_warmup/hooks.py

View check run for this annotation

Codecov / codecov/patch

web_assets_warmup/hooks.py#L46

Added line #L46 was not covered by tests
UPDATE ir_cron
SET active=true, nextcall=%s, priority=%s
WHERE id=%s
"""
nextcall = fields.Datetime.to_string(fields.Datetime.now())
args = (nextcall, -99, res_id)
cr.execute(query, args)
logger.info(

Check warning on line 54 in web_assets_warmup/hooks.py

View check run for this annotation

Codecov / codecov/patch

web_assets_warmup/hooks.py#L51-L54

Added lines #L51 - L54 were not covered by tests
"Cron '%s.%s' planned for execution at %s",
cron_module,
cron_ref,
nextcall,
)
except psycopg2.OperationalError as e:

Check warning on line 60 in web_assets_warmup/hooks.py

View check run for this annotation

Codecov / codecov/patch

web_assets_warmup/hooks.py#L60

Added line #L60 was not covered by tests
if e.pgcode == "55P03":
logger.info(

Check warning on line 62 in web_assets_warmup/hooks.py

View check run for this annotation

Codecov / codecov/patch

web_assets_warmup/hooks.py#L62

Added line #L62 was not covered by tests
"Cron '%s.%s' is currently being executed or updated",
cron_module,
cron_ref,
)


def post_load_hook():
active_cron_assets()
1 change: 1 addition & 0 deletions web_assets_warmup/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import ir_actions_report
37 changes: 37 additions & 0 deletions web_assets_warmup/models/ir_actions_report.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# Copyright 2020 Camptocamp SA
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl)

import logging

from odoo import api, models

logger = logging.getLogger(__name__)


class IrActionsReport(models.Model):
_inherit = "ir.actions.report"

@api.model
def cron_generate_assets(self):
"""Ensure that the assets are well-generated in the database."""
logger.info("Ensure that assets are generated and stored in the database...")

Check warning on line 17 in web_assets_warmup/models/ir_actions_report.py

View check run for this annotation

Codecov / codecov/patch

web_assets_warmup/models/ir_actions_report.py#L17

Added line #L17 was not covered by tests
# Call `_get_asset_nodes` as done when printing a report based on
# `web.report_layout` template (used by `web.html_container`)
options = {

Check warning on line 20 in web_assets_warmup/models/ir_actions_report.py

View check run for this annotation

Codecov / codecov/patch

web_assets_warmup/models/ir_actions_report.py#L20

Added line #L20 was not covered by tests
"commit_assetsbundle": False,
"debug": False,
"inherit_branding": False,
"dev_mode": False,
"caller_template": "web.html_container",
}
assets_template_ids = [

Check warning on line 27 in web_assets_warmup/models/ir_actions_report.py

View check run for this annotation

Codecov / codecov/patch

web_assets_warmup/models/ir_actions_report.py#L27

Added line #L27 was not covered by tests
"web.report_assets_common",
"web.assets_common",
"web.report_assets_pdf",
]
for xml_id in assets_template_ids:
self.env["ir.qweb"]._get_asset_nodes(

Check warning on line 33 in web_assets_warmup/models/ir_actions_report.py

View check run for this annotation

Codecov / codecov/patch

web_assets_warmup/models/ir_actions_report.py#L33

Added line #L33 was not covered by tests
xmlid=xml_id, options=options, css=True, js=True
)
logger.info("Ensure that assets are generated and stored in the database: done")
return True

Check warning on line 37 in web_assets_warmup/models/ir_actions_report.py

View check run for this annotation

Codecov / codecov/patch

web_assets_warmup/models/ir_actions_report.py#L36-L37

Added lines #L36 - L37 were not covered by tests
2 changes: 2 additions & 0 deletions web_assets_warmup/readme/CONTRIBUTORS.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
* Sébastien Alix <sebastien.alix@camptocamp.com>
* Michael Tietz (MT Software) <mtietz@mt-software.de>
9 changes: 9 additions & 0 deletions web_assets_warmup/readme/DESCRIPTION.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
Ensure that assets are generated and stored in the DB when Odoo starts

If the assets from the database are not up-to-date, they are regenerated by
Odoo when we print a report, but to do so Odoo forces the commit, so if an
exception occurs after (or during) the report rendering, it let the database in
a broken state (picking have been validated in this case).

To prevent this issue, we need to ensure that the assets are well-generated
when Odoo starts, not when the report is printed.
Loading
Loading