fix: ensure that prepared report is set even on timeout (#25565)
* fix: ensure that prepared report is set even on timeout Under following condition prepared report is never enabled: - Process takes too much time and is killed - HTTP timeout Fix: - We spawn a thread and ask it to wait till prepared report threshold time is elapsed and set prepared report on it. - Condvar is used to immdiately wake up and end the thread if report finsihed early. * refactor: use threading.Timer No need to implement it ourselves
This commit is contained in:
parent
a12fc118f4
commit
6613ed76fe
1 changed files with 18 additions and 8 deletions
|
|
@ -2,6 +2,7 @@
|
|||
# License: MIT. See LICENSE
|
||||
import datetime
|
||||
import json
|
||||
import threading
|
||||
|
||||
import frappe
|
||||
import frappe.desk.query_report
|
||||
|
|
@ -15,6 +16,8 @@ from frappe.modules.export_file import export_to_files
|
|||
from frappe.utils import cint, cstr
|
||||
from frappe.utils.safe_exec import check_safe_sql_query, safe_exec
|
||||
|
||||
PREPARED_REPORT_THRESHOLD = 20 # seconds
|
||||
|
||||
|
||||
class Report(Document):
|
||||
# begin: auto-generated types
|
||||
|
|
@ -153,21 +156,24 @@ class Report(Document):
|
|||
|
||||
def execute_script_report(self, filters):
|
||||
# save the timestamp to automatically set to prepared
|
||||
threshold = 15
|
||||
|
||||
start_time = datetime.datetime.now()
|
||||
|
||||
if not self.prepared_report:
|
||||
set_prepared_report = threading.Timer(
|
||||
interval=PREPARED_REPORT_THRESHOLD,
|
||||
function=enable_prepared_report,
|
||||
kwargs={"report": self.name, "site": frappe.local.site},
|
||||
)
|
||||
set_prepared_report.start()
|
||||
|
||||
# The JOB
|
||||
if self.is_standard == "Yes":
|
||||
res = self.execute_module(filters)
|
||||
else:
|
||||
res = self.execute_script(filters)
|
||||
|
||||
# automatically set as prepared
|
||||
set_prepared_report.cancel()
|
||||
execution_time = (datetime.datetime.now() - start_time).total_seconds()
|
||||
if execution_time > threshold and not self.prepared_report:
|
||||
frappe.enqueue(enable_prepared_report, report=self.name)
|
||||
|
||||
frappe.cache.hset("report_execution_time", self.name, execution_time)
|
||||
|
||||
return res
|
||||
|
|
@ -414,5 +420,9 @@ def get_group_by_column_label(args, meta):
|
|||
return label
|
||||
|
||||
|
||||
def enable_prepared_report(report: str):
|
||||
frappe.db.set_value("Report", report, "prepared_report", 1)
|
||||
def enable_prepared_report(*, site: str, report: str):
|
||||
frappe.init(site)
|
||||
frappe.connect()
|
||||
frappe.db.set_value("Report", report, "prepared_report", 1, update_modified=True)
|
||||
frappe.db.commit()
|
||||
frappe.destroy()
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue