Skip to content

Commit

Permalink
Merge pull request #934 from Ultimaker/CURA-11406_fix_auth_refresh_af…
Browse files Browse the repository at this point in the history
…ter_sleep

Fix OAuth token refresh after PC sleep
  • Loading branch information
rburema authored Feb 14, 2024
2 parents 95a1377 + 1fdfcb3 commit 5c19480
Showing 1 changed file with 49 additions and 26 deletions.
75 changes: 49 additions & 26 deletions UM/TaskManagement/HttpRequestManager.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ def __init__(self, max_concurrent_requests: int = 4, parent: Optional["QObject"]

# A FIFO queue for the pending requests.
self._request_queue = deque() # type: deque
self._urgent_request_queue = deque() # type: deque

# A set of all currently in progress requests
self._requests_in_progress = set() # type: Set[HttpRequestData]
Expand All @@ -112,6 +113,10 @@ def __init__(self, max_concurrent_requests: int = 4, parent: Optional["QObject"]
# and log them.
self._enable_request_benchmarking = enable_request_benchmarking

# It is possible to delay the non-urgent requests until further notice, so that more urgent ones
# can be processed in priority
self._delay_requests = False

@pyqtProperty(bool, notify = internetReachableChanged)
def isInternetReachable(self) -> bool:
return self._is_internet_reachable
Expand All @@ -125,13 +130,15 @@ def get(self, url: str,
download_progress_callback: Optional[Callable[[int, int], None]] = None,
upload_progress_callback: Optional[Callable[[int, int], None]] = None,
timeout: Optional[float] = None,
scope: Optional[HttpRequestScope] = None) -> "HttpRequestData":
scope: Optional[HttpRequestScope] = None,
urgent: bool = False) -> "HttpRequestData":
return self._createRequest("get", url, headers_dict = headers_dict,
callback = callback, error_callback = error_callback,
download_progress_callback = download_progress_callback,
upload_progress_callback = upload_progress_callback,
timeout = timeout,
scope = scope)
scope = scope,
urgent = urgent)

# Public API for creating an HTTP PUT request.
# Returns an HttpRequestData instance that represents this request.
Expand All @@ -143,13 +150,15 @@ def put(self, url: str,
download_progress_callback: Optional[Callable[[int, int], None]] = None,
upload_progress_callback: Optional[Callable[[int, int], None]] = None,
timeout: Optional[float] = None,
scope: Optional[HttpRequestScope] = None) -> "HttpRequestData":
scope: Optional[HttpRequestScope] = None,
urgent: bool = False) -> "HttpRequestData":
return self._createRequest("put", url, headers_dict = headers_dict, data = data,
callback = callback, error_callback = error_callback,
download_progress_callback = download_progress_callback,
upload_progress_callback = upload_progress_callback,
timeout = timeout,
scope = scope)
scope = scope,
urgent = urgent)

# Public API for creating an HTTP POST request. Returns a unique request ID for this request.
# Returns an HttpRequestData instance that represents this request.
Expand All @@ -161,13 +170,15 @@ def post(self, url: str,
download_progress_callback: Optional[Callable[[int, int], None]] = None,
upload_progress_callback: Optional[Callable[[int, int], None]] = None,
timeout: Optional[float] = None,
scope: Optional[HttpRequestScope] = None) -> "HttpRequestData":
scope: Optional[HttpRequestScope] = None,
urgent: bool = False) -> "HttpRequestData":
return self._createRequest("post", url, headers_dict = headers_dict, data = data,
callback = callback, error_callback = error_callback,
download_progress_callback = download_progress_callback,
upload_progress_callback = upload_progress_callback,
timeout = timeout,
scope = scope)
scope = scope,
urgent = urgent)

# Public API for creating an HTTP DELETE request.
# Returns an HttpRequestData instance that represents this request.
Expand All @@ -178,13 +189,15 @@ def delete(self, url: str,
download_progress_callback: Optional[Callable[[int, int], None]] = None,
upload_progress_callback: Optional[Callable[[int, int], None]] = None,
timeout: Optional[float] = None,
scope: Optional[HttpRequestScope] = None) -> "HttpRequestData":
scope: Optional[HttpRequestScope] = None,
urgent: bool = False) -> "HttpRequestData":
return self._createRequest("deleteResource", url, headers_dict=headers_dict,
callback=callback, error_callback=error_callback,
download_progress_callback=download_progress_callback,
upload_progress_callback=upload_progress_callback,
timeout=timeout,
scope=scope)
scope=scope,
urgent=urgent)

# Public API for aborting a given HttpRequestData. If the request is not pending or in progress, nothing
# will be done.
Expand All @@ -194,12 +207,22 @@ def abortRequest(self, request: "HttpRequestData") -> None:
if request in self._request_queue:
self._request_queue.remove(request)

elif request in self._urgent_request_queue:
self._urgent_request_queue.remove(request)

# If the request is currently in progress, abort it.
if request in self._requests_in_progress:
elif request in self._requests_in_progress:
if request.reply is not None and request.reply.isRunning():
request.reply.abort()
Logger.log("d", "%s aborted", request)

# Sets or unsets the normal requests delaying. As long as this is active, all the requests not specifically marked
# as urgent will stay waiting in the queue.
def setDelayRequests(self, delay_requests: bool) -> None:
self._delay_requests = delay_requests
if not self._delay_requests:
self.callLater(0, self._processNextRequestsInQueue)

@staticmethod
def readJSON(reply: QNetworkReply) -> Any:
""" Read a Json response into a Python object (list, dict, str depending on json type)
Expand Down Expand Up @@ -250,7 +273,8 @@ def _createRequest(self, http_method: str, url: str,
download_progress_callback: Optional[Callable[[int, int], None]] = None,
upload_progress_callback: Optional[Callable[[int, int], None]] = None,
timeout: Optional[float] = None,
scope: Optional[HttpRequestScope] = None ) -> "HttpRequestData":
scope: Optional[HttpRequestScope] = None,
urgent: bool = False) -> "HttpRequestData":
# Sanity checks
if timeout is not None and timeout <= 0:
raise ValueError("Timeout must be a positive number if provided, but [%s] was given" % timeout)
Expand Down Expand Up @@ -281,7 +305,10 @@ def _createRequest(self, http_method: str, url: str,
timeout = timeout)

with self._request_lock:
self._request_queue.append(request_data)
if urgent:
self._urgent_request_queue.append(request_data)
else:
self._request_queue.append(request_data)

# Schedule a call to process pending requests in the queue
if not self._process_requests_scheduled:
Expand All @@ -308,22 +335,18 @@ def _onRequestTimeout(self, request_data: "HttpRequestData") -> None:
# Processes the next requests in the pending queue. This function will issue as many requests to the QNetworkManager
# as possible but limited by the value "_max_concurrent_requests". It stops if there is no more pending requests.
def _processNextRequestsInQueue(self) -> None:
with self._request_lock:
self._processNextRequests(self._urgent_request_queue)
if not self._delay_requests:
self._processNextRequests(self._request_queue)
self._process_requests_scheduled = False

# Processes the next requests in the given pending queue
def _processNextRequests(self, queue: deque):
# Process all requests until the max concurrent number is hit or there's no more requests to process.
while True:
with self._request_lock:
# Do nothing if there's no more requests to process
if not self._request_queue:
self._process_requests_scheduled = False
return

# Do not exceed the max request limit
if len(self._requests_in_progress) >= self._max_concurrent_requests:
self._process_requests_scheduled = False
return

# Fetch the next request and process
next_request_data = self._request_queue.popleft()
self._processRequest(cast(HttpRequestData, next_request_data))
while queue and len(self._requests_in_progress) < self._max_concurrent_requests:
# Fetch the next request and process
self._processRequest(cast(HttpRequestData, queue.popleft()))

# Processes the given HttpRequestData by issuing the request using QNetworkAccessManager and moves the
# request into the currently in-progress list.
Expand Down

0 comments on commit 5c19480

Please sign in to comment.