report_webkit not thread-safe: risk of document corruption

Bug #1290820 reported by Florent
18
This bug affects 2 people
Affects Status Importance Assigned to Milestone
Odoo Addons (MOVED TO GITHUB)
New
Undecided
Unassigned
OpenERP Community Backports (Addons)
Status tracked in 7.0
7.0
Fix Released
Undecided
Unassigned

Bug Description

While generating a high number of PDF (20 000) with report_webkit, we got a PDF generated with wrong content.

We tracked down the bug being a collision on temporary HTML files created by this module.

Our hotfix is: http://hastebin.com/yiregeqoso.diff

Tags: maintenance

Related branches

Revision history for this message
Nicolas Bessi - Camptocamp (nbessi-c2c-deactivatedaccount) wrote :

Copy of hot fix for memory in order to do the MP on OCB and official

=== modified file 'report_webkit/webkit_report.py'
--- report_webkit/webkit_report.py 2013-10-27 12:31:04 +0000
+++ report_webkit/webkit_report.py 2014-03-11 11:44:49 +0000
@@ -35,6 +35,7 @@
 import sys
 from openerp import report
 import tempfile
+import thread
 import time
 import logging

@@ -157,6 +158,7 @@
             webkit_header = report_xml.webkit_header
         tmp_dir = tempfile.gettempdir()
         out_filename = tempfile.mktemp(suffix=".pdf", prefix="webkit.tmp.")
+ timestamp = '%x.%x' % (thread.get_ident(), 1e7 * time.time())
         file_to_del = [out_filename]
         if comm_path:
             command = [comm_path]
@@ -169,7 +171,7 @@
         if header :
             head_file = file( os.path.join(
                                   tmp_dir,
- str(time.time()) + '.head.html'
+ timestamp + '.head.html'
                                  ),
                                 'w'
                             )
@@ -180,7 +182,7 @@
         if footer :
             foot_file = file( os.path.join(
                                   tmp_dir,
- str(time.time()) + '.foot.html'
+ timestamp + '.foot.html'
                                  ),
                                 'w'
                             )
@@ -203,7 +205,7 @@
             command.extend(['--page-size', str(webkit_header.format).replace(',', '.')])
         count = 0
         for html in html_list :
- html_file = file(os.path.join(tmp_dir, str(time.time()) + str(count) +'.body.html'), 'w')
+ html_file = file(os.path.join(tmp_dir, timestamp + str(count) +'.body.html'), 'w')
             count += 1
             html_file.write(html.encode('utf-8'))
             html_file.close()

Revision history for this message
Florent (florent.x) wrote :

I've just discovered something worse: "self.parser_instance" is shared between threads.

And this shared "parser_instance" has important attributes :

 * self.parser_instance.cr: which means that the same PostgreSQL cursor is accessed from more than one thread : it breaks randomly

 * self.parser_instance.localcontext['objects'] : which means that it might explain that the wrong document was generated (the issue reported here, on bug #1290820)

These is really a can of worms when using "report_webkit" in a Production environment.

We have a local patch for it, I'll do a second merge proposal soon.

Revision history for this message
Yannick Vaucher @ Camptocamp (yvaucher-c2c) wrote :

I confirm this bug as I had the same issue.
As I don't see your second MP I'll create a other MP to solve the issue with self.parser_instance

About file names, I prefered to use NamedTemporaryFiles
https://code.launchpad.net/~camptocamp/openobject-addons/7.0-fix-1319095/+merge/219399

Revision history for this message
Yannick Vaucher @ Camptocamp (yvaucher-c2c) wrote :
tags: added: maintenance
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Duplicates of this bug

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.