|
8 | 8 | import globus_sdk |
9 | 9 |
|
10 | 10 | from hera_librarian.transfer import TransferStatus |
| 11 | +from hera_librarian.utils import GLOBUS_ERROR_EVENTS |
11 | 12 |
|
12 | 13 | from .core import CoreAsyncTransferManager |
13 | 14 |
|
@@ -148,6 +149,8 @@ def _get_transfer_data(self, label: str, settings: "ServerSettings"): |
148 | 149 | verify_checksum=True, # We do this ourselves, but globus will auto-retry if it detects failed files |
149 | 150 | preserve_timestamp=True, |
150 | 151 | notify_on_succeeded=False, |
| 152 | + skip_source_errors=False, |
| 153 | + fail_on_quota_errors=True, |
151 | 154 | ) |
152 | 155 |
|
153 | 156 | return transfer_data |
@@ -273,7 +276,9 @@ def batch_transfer( |
273 | 276 | # Globus transfer. |
274 | 277 | relative_local_path = self._subtract_local_root(local_path, settings) |
275 | 278 | transfer_data.add_item( |
276 | | - str(relative_local_path), str(remote_path), recursive=local_path.is_dir() |
| 279 | + str(relative_local_path), |
| 280 | + str(remote_path), |
| 281 | + recursive=local_path.is_dir(), |
277 | 282 | ) |
278 | 283 |
|
279 | 284 | # submit the transfer |
@@ -328,5 +333,49 @@ def transfer_status(self, settings: "ServerSettings") -> TransferStatus: |
328 | 333 | return TransferStatus.COMPLETED |
329 | 334 | elif task_doc["status"] == "FAILED": |
330 | 335 | return TransferStatus.FAILED |
| 336 | + # When there are errors, better fail the task and try again. There is |
| 337 | + # a different check for faults to make the state transition as clear as |
| 338 | + # possible. |
| 339 | + elif task_doc["faults"] > 0: |
| 340 | + task_event_list = transfer_client.task_event_list(self.task_id) |
| 341 | + for event in task_event_list: |
| 342 | + if event["code"] in GLOBUS_ERROR_EVENTS and event["is_error"]: |
| 343 | + return TransferStatus.FAILED |
| 344 | + return TransferStatus.FAILED |
331 | 345 | else: # "status" == "ACTIVE" |
332 | 346 | return TransferStatus.INITIATED |
| 347 | + |
| 348 | + def fail_transfer(self, settings: "ServerSettings") -> bool: |
| 349 | + """ |
| 350 | + A GLobus task needs to be canceled because it has errors. |
| 351 | +
|
| 352 | + Parameters |
| 353 | + ---------- |
| 354 | + settings : ServerSettings object |
| 355 | + The settings for the Librarian server. These settings should include |
| 356 | + the Globus login information. |
| 357 | +
|
| 358 | + Returns |
| 359 | + ------- |
| 360 | + bool |
| 361 | + Whether we could successfully cancelled a transfer (True) or not |
| 362 | + (False). |
| 363 | +
|
| 364 | + """ |
| 365 | + authorizer = self.authorize(settings=settings) |
| 366 | + if authorizer is None: |
| 367 | + # We *should* be able to just assume that we have already |
| 368 | + # authenticated and should be able to query the status of our |
| 369 | + # transfer. However, if for whatever reason we're not able to talk |
| 370 | + # to Globus (network issues, Globus outage, etc.), we won't be able |
| 371 | + # to find out our transfer's status -- let's bail and assume we |
| 372 | + # failed |
| 373 | + return False |
| 374 | + |
| 375 | + transfer_client = globus_sdk.TransferClient(authorizer=authorizer) |
| 376 | + |
| 377 | + try: |
| 378 | + _ = transfer_client.cancel_task(self.task_id) |
| 379 | + except globus_sdk.TransferAPIError as e: |
| 380 | + return False |
| 381 | + return True |
0 commit comments