From 0b8a2edee70cedb62059a29039eb06d3809efd19 Mon Sep 17 00:00:00 2001 From: Rushabh Mehta Date: Thu, 17 Mar 2022 14:54:17 +0530 Subject: [PATCH] fix(build): separate assets.json and assets-rtl.json to fix concurrency issue --- esbuild/esbuild.js | 22 ++++++++++++---------- frappe/utils/__init__.py | 37 ++++++++++++++++++++++++------------- 2 files changed, 36 insertions(+), 23 deletions(-) diff --git a/esbuild/esbuild.js b/esbuild/esbuild.js index 43c01e88fb..ff31aa4b74 100644 --- a/esbuild/esbuild.js +++ b/esbuild/esbuild.js @@ -286,7 +286,7 @@ function get_watch_config() { notify_redis({ error }); } else { let { - assets_json, + new_assets_json, prev_assets_json } = await write_assets_json(result.metafile); @@ -294,7 +294,7 @@ function get_watch_config() { if (prev_assets_json) { changed_files = get_rebuilt_assets( prev_assets_json, - assets_json + new_assets_json ); let timestamp = new Date().toLocaleTimeString(); @@ -384,6 +384,7 @@ let prev_assets_json; let curr_assets_json; async function write_assets_json(metafile) { + let rtl = false; prev_assets_json = curr_assets_json; let out = {}; for (let output in metafile.outputs) { @@ -392,13 +393,14 @@ async function write_assets_json(metafile) { if (info.entryPoint) { let key = path.basename(info.entryPoint); if (key.endsWith('.css') && asset_path.includes('/css-rtl/')) { + rtl = true; key = `rtl_${key}`; } out[key] = asset_path; } } - let assets_json_path = path.resolve(assets_path, "assets.json"); + let assets_json_path = path.resolve(assets_path, `assets${rtl?'-rtl':''}.json`); let assets_json; try { assets_json = await fs.promises.readFile(assets_json_path, "utf-8"); @@ -407,21 +409,21 @@ async function write_assets_json(metafile) { } assets_json = JSON.parse(assets_json); // update with new values - assets_json = Object.assign({}, assets_json, out); - curr_assets_json = assets_json; + let new_assets_json = Object.assign({}, assets_json, out); + curr_assets_json = new_assets_json; await fs.promises.writeFile( assets_json_path, - JSON.stringify(assets_json, null, 4) + JSON.stringify(new_assets_json, null, 4) ); - await update_assets_json_in_cache(assets_json); + await update_assets_json_in_cache(); return { - assets_json, + new_assets_json, prev_assets_json }; } -function update_assets_json_in_cache(assets_json) { +function update_assets_json_in_cache() { // update assets_json cache in redis, so that it can be read directly by python return new Promise(resolve => { let client = get_redis_subscriber("redis_cache"); @@ -429,7 +431,7 @@ function update_assets_json_in_cache(assets_json) { client.on("error", _ => { log_warn("Cannot connect to redis_cache to update assets_json"); }); - client.set("assets_json", JSON.stringify(assets_json), err => { + client.del("assets_json", err => { client.unref(); resolve(); }); diff --git a/frappe/utils/__init__.py b/frappe/utils/__init__.py index 1233bcd30f..c361b5b430 100644 --- a/frappe/utils/__init__.py +++ b/frappe/utils/__init__.py @@ -796,22 +796,33 @@ def get_assets_json(): # using .get instead of .get_value to avoid pickle.loads try: - assets_json = cache.get("assets_json") - except ConnectionError: - assets_json = None - - # if value found, decode it - if assets_json is not None: - try: - assets_json = assets_json.decode('utf-8') - except (UnicodeDecodeError, AttributeError): + if not frappe.conf.developer_mode: + assets_json = cache.get("assets_json").decode('utf-8') + else: assets_json = None + except (UnicodeDecodeError, AttributeError, ConnectionError): + assets_json = None if not assets_json: - assets_json = frappe.read_file("assets/assets.json") - cache.set_value("assets_json", assets_json, shared=True) - - frappe.local.assets_json = frappe.safe_decode(assets_json) + # get merged assets.json and assets-rtl.json + assets_dict = frappe.parse_json( + frappe.read_file("assets/assets.json") + ) + + assets_rtl = frappe.read_file("assets/assets-rtl.json") + if assets_rtl: + assets_dict.update( + frappe.parse_json(assets_rtl) + ) + frappe.local.assets_json = frappe.as_json(assets_dict) + # save in cache + cache.set_value("assets_json", frappe.local.assets_json, + shared=True) + + return assets_dict + else: + # from cache, decode and send + frappe.local.assets_json = frappe.safe_decode(assets_json) return frappe.parse_json(frappe.local.assets_json)