# HG changeset patch # User Edouard Tisserant # Date 1613623186 -3600 # Node ID d32e6246cd59f74aa784b52fd9180178263c872a # Parent b8c0dfdf364b68721a7f2cf848ea22ce2bbfba5f SVGHMI: Optimization for JsonTable : reload JSON only when necessary, and avoid concurrent http requests. diff -r b8c0dfdf364b -r d32e6246cd59 svghmi/widget_jsontable.ysl2 --- a/svghmi/widget_jsontable.ysl2 Tue Feb 16 11:47:52 2021 +0100 +++ b/svghmi/widget_jsontable.ysl2 Thu Feb 18 05:39:46 2021 +0100 @@ -7,6 +7,9 @@ cache = [0,100,50]; init() { this.spread_json_data_bound = this.spread_json_data.bind(this); + this.handle_http_response_bound = this.handle_http_response.bind(this); + this.fetch_error_bound = this.fetch_error.bind(this); + this.promised = false; } handle_http_response(response) { @@ -16,7 +19,12 @@ return response.json(); } + fetch_error(e){ + console.log("HTTP fetch error, message = " + e.message + "Widget:" + this.element_id); + } + do_http_request(...opt) { + this.abort_controller = new AbortController(); const query = { args: this.args, range: this.cache[1], @@ -29,17 +37,36 @@ const options = { method: 'POST', body: JSON.stringify(query), - headers: {'Content-Type': 'application/json'} + headers: {'Content-Type': 'application/json'}, + signal: this.abort_controller.signal }; - fetch(this.args[0], options) - .then(this.handle_http_response) - .then(this.spread_json_data_bound); - - } + return fetch(this.args[0], options) + .then(this.handle_http_response_bound) + .then(this.spread_json_data_bound) + .catch(this.fetch_error_bound); + + } + unsub(){ + this.abort_controller.abort(); + super.unsub(); + } + dispatch(value, oldval, index) { - this.cache[index] = value; - this.do_http_request(); + + if(this.cache[index] != value) + this.cache[index] = value; + else + return; + + if(!this.promised){ + this.promised = true; + Promise.resolve().then(() => { + return this.do_http_request().finally(() => { + this.promised = false; + }); + }) + } } make_on_click(...options){ let that = this; @@ -196,16 +223,14 @@ param "expressions"; param "widget_elts"; param "label"; - const "gid", "@id"; // use intermediate variables for optimization - const "varprefix" > obj_«$gid»_ + const "varprefix" > obj_«@id»_ | try { foreach "$expressions/expression"{ | let «$varprefix»«position()» = «@content»; | if(«$varprefix»«position()» == undefined) { - | console.log("«$varprefix»«position()» = «@content»"); | throw null; | } } @@ -224,7 +249,7 @@ with "widget_elts", "$widget_elts"; } | } catch(err) { - | id("«$gid»").style = "display:none"; + | id("«@id»").style = "display:none"; | } } @@ -236,9 +261,10 @@ | visible: «count($data_elt/*[@inkscape:label])», | spread_json_data: function(janswer) { | let [range,position,jdata] = janswer; - | this.apply_hmi_value(1, range); - | this.apply_hmi_value(2, position); - | this.apply_hmi_value(3, this.visible); + | [[1, range], [2, position], [3, this.visible]].map(([i,v]) => { + | this.apply_hmi_value(i,v); + | this.cache[i] = v; + | }); apply "$data_elt", mode="json_table_render_except_comments" { with "expressions","$initexpr_ns"; with "widget_elts","$hmi_element/*[@inkscape:label = 'data']/descendant::svg:*";