Made the various JSON based client-server interface a bit more resilient against slow data transfer. eric7

Wed, 24 Apr 2024 15:16:12 +0200

author
Detlev Offenbach <detlev@die-offenbachs.de>
date
Wed, 24 Apr 2024 15:16:12 +0200
branch
eric7
changeset 10697
8a609e4c71b6
parent 10696
55e4a7497833
child 10698
ed332f3d26a7

Made the various JSON based client-server interface a bit more resilient against slow data transfer.

src/eric7/Debugger/DebuggerInterfacePython.py file | annotate | diff | comparison | revisions
src/eric7/EricNetwork/EricJsonServer.py file | annotate | diff | comparison | revisions
src/eric7/Utilities/BackgroundService.py file | annotate | diff | comparison | revisions
--- a/src/eric7/Debugger/DebuggerInterfacePython.py	Wed Apr 24 15:15:33 2024 +0200
+++ b/src/eric7/Debugger/DebuggerInterfacePython.py	Wed Apr 24 15:16:12 2024 +0200
@@ -1404,8 +1404,15 @@
         @param sock reference to the socket to read data from
         @type QTcpSocket
         """
+        headerSize = struct.calcsize(b"!II")
+
         while sock and sock.bytesAvailable():
-            header = sock.read(struct.calcsize(b"!II"))
+            now = time.monotonic()
+            while sock.bytesAvailable() < headerSize:
+                sock.waitForReadyRead(50)
+                if time.monotonic() - now > 2.0:  # 2 seconds timeout
+                    return
+            header = sock.read(headerSize)
             length, datahash = struct.unpack(b"!II", header)
 
             data = bytearray()
--- a/src/eric7/EricNetwork/EricJsonServer.py	Wed Apr 24 15:15:33 2024 +0200
+++ b/src/eric7/EricNetwork/EricJsonServer.py	Wed Apr 24 15:16:12 2024 +0200
@@ -10,6 +10,7 @@
 import contextlib
 import json
 import struct
+import time
 import zlib
 
 from PyQt6.QtCore import (
@@ -149,6 +150,8 @@
         @param idString id of the connection
         @type str
         """
+        headerSize = struct.calcsize(b"!II")
+
         if idString:
             try:
                 connection = self.__connections[idString]
@@ -158,15 +161,26 @@
             connection = self.__connection
 
         while connection and connection.bytesAvailable():
-            header = connection.read(struct.calcsize(b"!II"))
+            now = time.monotonic()
+            while connection.bytesAvailable() < headerSize:
+                connection.waitForReadyRead(50)
+                if time.monotonic() - now > 2.0:  # 2 seconds timeout
+                    return
+            header = connection.read(headerSize)
             length, datahash = struct.unpack(b"!II", header)
 
             data = bytearray()
+            now = time.monotonic()
             while len(data) < length:
                 maxSize = length - len(data)
                 if connection.bytesAvailable() < maxSize:
                     connection.waitForReadyRead(50)
-                data += connection.read(maxSize)
+                newData = connection.read(maxSize)
+                if newData:
+                    data += newData
+                else:
+                    if time.monotonic() - now > 2.0:  # 2 seconds timeout
+                        break
 
             if zlib.adler32(data) & 0xFFFFFFFF != datahash:
                 # corrupted data -> discard and continue
--- a/src/eric7/Utilities/BackgroundService.py	Wed Apr 24 15:15:33 2024 +0200
+++ b/src/eric7/Utilities/BackgroundService.py	Wed Apr 24 15:16:12 2024 +0200
@@ -13,8 +13,8 @@
 import os
 import struct
 import sys
-
-from zlib import adler32
+import time
+import zlib
 
 from PyQt6.QtCore import QProcess, QThread, QTimer, pyqtSignal
 from PyQt6.QtNetwork import QHostAddress, QTcpServer
@@ -175,7 +175,7 @@
             packedData = json.dumps([fx, fn, data])
             packedData = bytes(packedData, "utf-8")
             header = struct.pack(
-                b"!II", len(packedData), adler32(packedData) & 0xFFFFFFFF
+                b"!II", len(packedData), zlib.adler32(packedData) & 0xFFFFFFFF
             )
             connection.write(header)
             connection.write(b"JOB   ")  # 6 character message type
@@ -189,22 +189,35 @@
         @type str
         @exception RuntimeError raised if hashes don't match
         """
+        headerSize = struct.calcsize(b"!II")
+
         data = ""
         fx = ""
 
         connection = self.connections[lang]
-        while connection.bytesAvailable():
-            header = connection.read(struct.calcsize(b"!II"))
+        while connection and connection.bytesAvailable():
+            now = time.monotonic()
+            while connection.bytesAvailable() < headerSize:
+                connection.waitForReadyRead(50)
+                if time.monotonic() - now > 2.0:  # 2 seconds timeout
+                    return
+            header = connection.read(headerSize)
             length, datahash = struct.unpack(b"!II", header)
 
             packedData = b""
+            now = time.monotonic()
             while len(packedData) < length:
                 maxSize = length - len(packedData)
                 if connection.bytesAvailable() < maxSize:
                     connection.waitForReadyRead(50)
-                packedData += connection.read(maxSize)
+                newData = connection.read(maxSize)
+                if newData:
+                    packedData += newData
+                else:
+                    if time.monotonic() - now > 2.0:  # 2 seconds timeout
+                        break
 
-            if adler32(packedData) & 0xFFFFFFFF != datahash:
+            if zlib.adler32(packedData) & 0xFFFFFFFF != datahash:
                 raise RuntimeError("Hashes not equal")
             packedData = packedData.decode("utf-8")
             # "check" if is's a tuple of 3 values

eric ide

mercurial