From 9227c303c68fc30cebdb45fddbf808149f7507cc Mon Sep 17 00:00:00 2001 From: Remco Burema Date: Wed, 14 Apr 2021 13:59:21 +0200 Subject: [PATCH] Fix 'uploaded print-job cache' set before the mesh upload. Since we use that to detect when the mesh is already uploaded, and thus can be reprinted, this could cause problems, since, while we do properly set it to None when an error is returned, if the request never returns to us, or if a reprint is started while the mesh is still uploading, the print-job cache could be set while the mesh wasn't actually there yet. Which could in theory have maybe caused the problems we see. CURA-8004 --- .../src/Cloud/CloudOutputDevice.py | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py index 56144a54b3..c4efe6c85a 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py @@ -1,4 +1,4 @@ -# Copyright (c) 2020 Ultimaker B.V. +# Copyright (c) 2021 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. from time import time @@ -104,6 +104,7 @@ class CloudOutputDevice(UltimakerNetworkedPrinterOutputDevice): # Reference to the uploaded print job / mesh # We do this to prevent re-uploading the same file multiple times. self._tool_path = None # type: Optional[bytes] + self._pre_upload_print_job = None # type: Optional[CloudPrintJobResponse] self._uploaded_print_job = None # type: Optional[CloudPrintJobResponse] def connect(self) -> None: @@ -130,6 +131,7 @@ class CloudOutputDevice(UltimakerNetworkedPrinterOutputDevice): """Resets the print job that was uploaded to force a new upload, runs whenever the user re-slices.""" self._tool_path = None + self._pre_upload_print_job = None self._uploaded_print_job = None def matchesNetworkKey(self, network_key: str) -> bool: @@ -196,6 +198,7 @@ class CloudOutputDevice(UltimakerNetworkedPrinterOutputDevice): # The mesh didn't change, let's not upload it to the cloud again. # Note that self.writeFinished is called in _onPrintUploadCompleted as well. if self._uploaded_print_job: + Logger.log("i", "Current mesh is already attached to a print-job, immediately request reprint.") self._api.requestPrint(self.key, self._uploaded_print_job.job_id, self._onPrintUploadCompleted, self._onPrintUploadSpecificError) return @@ -227,7 +230,7 @@ class CloudOutputDevice(UltimakerNetworkedPrinterOutputDevice): if not self._tool_path: return self._onUploadError() self._progress.show() - self._uploaded_print_job = job_response # store the last uploaded job to prevent re-upload of the same file + self._pre_upload_print_job = job_response # store the last uploaded job to prevent re-upload of the same file self._api.uploadToolPath(job_response, self._tool_path, self._onPrintJobUploaded, self._progress.update, self._onUploadError) @@ -238,9 +241,11 @@ class CloudOutputDevice(UltimakerNetworkedPrinterOutputDevice): """ self._progress.update(100) - print_job = cast(CloudPrintJobResponse, self._uploaded_print_job) - if not print_job: # It's possible that another print job is requested in the meanwhile, which then fails to upload with an error, which sets self._uploaded_print_job to `None`. - # TODO: Maybe _onUploadError shouldn't set the _uploaded_print_job to None or we need to prevent such asynchronous cases. + print_job = cast(CloudPrintJobResponse, self._pre_upload_print_job) + if not print_job: # It's possible that another print job is requested in the meanwhile, which then fails to upload with an error, which sets self._pre_uploaded_print_job to `None`. + self._pre_upload_print_job = None + self._uploaded_print_job = None + Logger.log("w", "Interference from another job uploaded at roughly the same time, not uploading print!") return # Prevent a crash. self._api.requestPrint(self.key, print_job.job_id, self._onPrintUploadCompleted, self._onPrintUploadSpecificError) @@ -249,6 +254,7 @@ class CloudOutputDevice(UltimakerNetworkedPrinterOutputDevice): :param response: The response from the cloud API. """ + self._uploaded_print_job = self._pre_upload_print_job self._progress.hide() PrintJobUploadSuccessMessage().show() self.writeFinished.emit() @@ -264,6 +270,7 @@ class CloudOutputDevice(UltimakerNetworkedPrinterOutputDevice): PrintJobUploadErrorMessage(I18N_CATALOG.i18nc("@error:send", "Unknown error code when uploading print job: {0}", error_code)).show() self._progress.hide() + self._pre_upload_print_job = None self._uploaded_print_job = None self.writeError.emit() @@ -273,6 +280,7 @@ class CloudOutputDevice(UltimakerNetworkedPrinterOutputDevice): :param message: The message to display. """ self._progress.hide() + self._pre_upload_print_job = None self._uploaded_print_job = None PrintJobUploadErrorMessage(message).show() self.writeError.emit()