Эх сурвалжийг харах

improve webxdc js to prevent races (#1718)

* improve webxdc js to prevent races

that were possibly introduced by https://github.com/deltachat/deltachat-ios/pull/1715#discussion_r989488545

* Apply suggestions from code review

Co-authored-by: bjoern <r10s@b44t.com>

Co-authored-by: bjoern <r10s@b44t.com>
Simon Laux 2 жил өмнө
parent
commit
4b6e16f754

+ 19 - 30
deltachat-ios/Controller/WebxdcViewController.swift

@@ -62,24 +62,35 @@ class WebxdcViewController: WebViewViewController {
         
         
         let script = """
         let script = """
         window.webxdc = (() => {
         window.webxdc = (() => {
-          let setUpdateListenerPromise = null
           var log = (s)=>webkit.messageHandlers.log.postMessage(s);
           var log = (s)=>webkit.messageHandlers.log.postMessage(s);
         
         
           var update_listener = () => {};
           var update_listener = () => {};
 
 
-          window.__webxdcUpdate = async (lastSerial) => {
+          let should_run_again = false;
+          let running = false;
+          let lastSerial = 0;
+          window.__webxdcUpdate = async () => {
+            if (running) {
+                should_run_again = true
+                return
+            }
+            should_run_again = false
+            running = true;
             try {
             try {
                 const updates = await fetch("webxdc-update.json?"+lastSerial).then((response) => response.json())
                 const updates = await fetch("webxdc-update.json?"+lastSerial).then((response) => response.json())
                 updates.forEach((update) => {
                 updates.forEach((update) => {
                   update_listener(update);
                   update_listener(update);
+                  if (lastSerial < update["max_serial"]){
+                    lastSerial = update["max_serial"]
+                  }
                 });
                 });
             } catch (e) {
             } catch (e) {
                 log("json error: "+ e.message)
                 log("json error: "+ e.message)
             } finally {
             } finally {
-              if (setUpdateListenerPromise) {
-                 setUpdateListenerPromise()
-                 setUpdateListenerPromise = null
-              }
+                running = false;
+                if (should_run_again) {
+                    await window.__webxdcUpdate()
+                }
             }
             }
           }
           }
 
 
@@ -90,11 +101,7 @@ class WebxdcViewController: WebViewViewController {
         
         
             setUpdateListener: (cb, serial) => {
             setUpdateListener: (cb, serial) => {
                 update_listener = cb
                 update_listener = cb
-                const promise = new Promise((res, _rej) => {
-                   setUpdateListenerPromise = res
-                })
-                webkit.messageHandlers.setUpdateListener.postMessage(typeof serial === "undefined" ? 0 : parseInt(serial));
-                return promise
+                return window.__webxdcUpdate()
             },
             },
 
 
             getAllUpdates: () => {
             getAllUpdates: () => {
@@ -266,18 +273,8 @@ class WebxdcViewController: WebViewViewController {
         }
         }
     }
     }
 
 
-    var lastSerial: Int?
     private func updateWebxdc() {
     private func updateWebxdc() {
-        if let lastSerial = lastSerial {
-            let statusUpdates = dcContext.getWebxdcStatusUpdates(msgId: messageId, lastKnownSerial: lastSerial)
-            if let data: Data = statusUpdates.data(using: .utf8),
-               let array = (try? JSONSerialization.jsonObject(with: data, options: [])) as? [Any],
-               let first = array.first as? [String: Any],
-               let maxSerial = first["max_serial"] as? Int {
-                self.lastSerial = maxSerial
-            }
-            webView.evaluateJavaScript("window.__webxdcUpdate(\(String(lastSerial)))", completionHandler: nil)
-        }
+        webView.evaluateJavaScript("window.__webxdcUpdate()", completionHandler: nil)
     }
     }
 
 
     @objc private func moreButtonPressed() {
     @objc private func moreButtonPressed() {
@@ -336,14 +333,6 @@ extension WebxdcViewController: WKScriptMessageHandler {
     func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
     func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
         let handler = WebxdcHandler(rawValue: message.name)
         let handler = WebxdcHandler(rawValue: message.name)
         switch handler {
         switch handler {
-        case .setUpdateListener:
-            guard let lastKnownSerial = message.body as? Int else {
-                logger.error("could not convert param \(message.body) to int")
-                return
-            }
-            lastSerial = lastKnownSerial
-            updateWebxdc()
-            
         case .log:
         case .log:
             guard let msg = message.body as? String else {
             guard let msg = message.body as? String else {
                 logger.error("could not convert param \(message.body) to string")
                 logger.error("could not convert param \(message.body) to string")