rda-python-common 3.0.20__tar.gz → 3.0.21__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. {rda_python_common-3.0.20/src/rda_python_common.egg-info → rda_python_common-3.0.21}/PKG-INFO +2 -2
  2. {rda_python_common-3.0.20 → rda_python_common-3.0.21}/README.md +1 -1
  3. {rda_python_common-3.0.20 → rda_python_common-3.0.21}/pyproject.toml +1 -1
  4. {rda_python_common-3.0.20 → rda_python_common-3.0.21}/src/rda_python_common/__init__.py +1 -1
  5. {rda_python_common-3.0.20 → rda_python_common-3.0.21}/src/rda_python_common/pg_file.py +21 -7
  6. {rda_python_common-3.0.20 → rda_python_common-3.0.21/src/rda_python_common.egg-info}/PKG-INFO +2 -2
  7. {rda_python_common-3.0.20 → rda_python_common-3.0.21}/LICENSE +0 -0
  8. {rda_python_common-3.0.20 → rda_python_common-3.0.21}/setup.cfg +0 -0
  9. {rda_python_common-3.0.20 → rda_python_common-3.0.21}/src/rda_python_common/PgCMD.py +0 -0
  10. {rda_python_common-3.0.20 → rda_python_common-3.0.21}/src/rda_python_common/PgDBI.py +0 -0
  11. {rda_python_common-3.0.20 → rda_python_common-3.0.21}/src/rda_python_common/PgFile.py +0 -0
  12. {rda_python_common-3.0.20 → rda_python_common-3.0.21}/src/rda_python_common/PgLOG.py +0 -0
  13. {rda_python_common-3.0.20 → rda_python_common-3.0.21}/src/rda_python_common/PgLock.py +0 -0
  14. {rda_python_common-3.0.20 → rda_python_common-3.0.21}/src/rda_python_common/PgOPT.py +0 -0
  15. {rda_python_common-3.0.20 → rda_python_common-3.0.21}/src/rda_python_common/PgSIG.py +0 -0
  16. {rda_python_common-3.0.20 → rda_python_common-3.0.21}/src/rda_python_common/PgSplit.py +0 -0
  17. {rda_python_common-3.0.20 → rda_python_common-3.0.21}/src/rda_python_common/PgUtil.py +0 -0
  18. {rda_python_common-3.0.20 → rda_python_common-3.0.21}/src/rda_python_common/pg_cmd.py +0 -0
  19. {rda_python_common-3.0.20 → rda_python_common-3.0.21}/src/rda_python_common/pg_dbi.py +0 -0
  20. {rda_python_common-3.0.20 → rda_python_common-3.0.21}/src/rda_python_common/pg_lock.py +0 -0
  21. {rda_python_common-3.0.20 → rda_python_common-3.0.21}/src/rda_python_common/pg_log.py +0 -0
  22. {rda_python_common-3.0.20 → rda_python_common-3.0.21}/src/rda_python_common/pg_opt.py +0 -0
  23. {rda_python_common-3.0.20 → rda_python_common-3.0.21}/src/rda_python_common/pg_password.py +0 -0
  24. {rda_python_common-3.0.20 → rda_python_common-3.0.21}/src/rda_python_common/pg_sig.py +0 -0
  25. {rda_python_common-3.0.20 → rda_python_common-3.0.21}/src/rda_python_common/pg_split.py +0 -0
  26. {rda_python_common-3.0.20 → rda_python_common-3.0.21}/src/rda_python_common/pg_util.py +0 -0
  27. {rda_python_common-3.0.20 → rda_python_common-3.0.21}/src/rda_python_common/pgpassword.py +0 -0
  28. {rda_python_common-3.0.20 → rda_python_common-3.0.21}/src/rda_python_common/pgpassword.usg +0 -0
  29. {rda_python_common-3.0.20 → rda_python_common-3.0.21}/src/rda_python_common.egg-info/SOURCES.txt +0 -0
  30. {rda_python_common-3.0.20 → rda_python_common-3.0.21}/src/rda_python_common.egg-info/dependency_links.txt +0 -0
  31. {rda_python_common-3.0.20 → rda_python_common-3.0.21}/src/rda_python_common.egg-info/entry_points.txt +0 -0
  32. {rda_python_common-3.0.20 → rda_python_common-3.0.21}/src/rda_python_common.egg-info/requires.txt +0 -0
  33. {rda_python_common-3.0.20 → rda_python_common-3.0.21}/src/rda_python_common.egg-info/top_level.txt +0 -0
  34. {rda_python_common-3.0.20 → rda_python_common-3.0.21}/test/test_common.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: rda_python_common
3
- Version: 3.0.20
3
+ Version: 3.0.21
4
4
  Summary: RDA Python common library codes shared by other RDA python packages
5
5
  Author-email: Zaihua Ji <zji@ucar.edu>
6
6
  Project-URL: Homepage, https://github.com/NCAR/rda-python-common
@@ -189,7 +189,7 @@ PgLOG.pglog("hello", PgLOG.LOGWRN)
189
189
  python -c "import rda_python_common; print(rda_python_common.__version__)"
190
190
  ```
191
191
 
192
- You should see the installed version (currently `3.0.20`). If the import
192
+ You should see the installed version (currently `3.0.21`). If the import
193
193
  fails, double-check that the active Python environment is the one where you
194
194
  ran `pip install`.
195
195
 
@@ -165,7 +165,7 @@ PgLOG.pglog("hello", PgLOG.LOGWRN)
165
165
  python -c "import rda_python_common; print(rda_python_common.__version__)"
166
166
  ```
167
167
 
168
- You should see the installed version (currently `3.0.20`). If the import
168
+ You should see the installed version (currently `3.0.21`). If the import
169
169
  fails, double-check that the active Python environment is the one where you
170
170
  ran `pip install`.
171
171
 
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "rda_python_common"
7
- version = "3.0.20"
7
+ version = "3.0.21"
8
8
  authors = [
9
9
  { name="Zaihua Ji", email="zji@ucar.edu" },
10
10
  ]
@@ -22,7 +22,7 @@ object that existing callers expect.
22
22
 
23
23
  from . import PgLOG, PgUtil, PgDBI, PgFile, PgLock, PgCMD, PgSIG, PgOPT, PgSplit
24
24
 
25
- __version__ = "3.0.20"
25
+ __version__ = "3.0.21"
26
26
 
27
27
  __all__ = [
28
28
  "PgLOG",
@@ -107,6 +107,8 @@ class PgFile(PgUtil, PgSIG):
107
107
  self.DELDIRS = {}
108
108
  self.TASKIDS = {} # cache unfinished
109
109
  self.QCANCEL = {} # taskid -> why a task got cancelled, reported by the waiting caller
110
+ self.QFAULTS = {} # taskid -> polls in a row reporting a transient Globus fault
111
+ self.QFLIMIT = 30 # give a task that long (polls of ETIME) to recover before cancelling
110
112
  self.LHOST = "localhost"
111
113
  self.OHOST = self.PGLOG['OBJCTSTR']
112
114
  self.BHOST = self.PGLOG['BACKUPNM']
@@ -587,15 +589,18 @@ class PgFile(PgUtil, PgSIG):
587
589
  if ms:
588
590
  detail = ms.group(1)
589
591
  if detail not in astats:
590
- if logact&self.NOWAIT:
592
+ # Globus still calls the task ACTIVE, so this is a transient fault it
593
+ # keeps retrying on its own. Give it QFLIMIT polls in a row to recover
594
+ # before cancelling, counted per task so that a long transfer does not
595
+ # run out of patience simply for having been running a while
596
+ qcnt = self.QFAULTS[taskid] = self.QFAULTS.get(taskid, 0) + 1
597
+ if logact&self.NOWAIT and qcnt > self.QFLIMIT:
591
598
  # record why, and let the caller waiting on this task report it as a
592
599
  # single error naming the file; dumping the whole get-task output here
593
600
  # doubled every failure into two error entries, the first 17 lines long
594
601
  reason = detail
595
602
  ms = re.search(r'Bytes Transferred:\s+(\d+)', buf)
596
- if ms: reason += " after " + self.format_float_value(ms.group(1))
597
- ms = re.search(r'Files:\s+(\d+)', buf)
598
- if ms: reason += " of {} file(s)".format(ms.group(1))
603
+ if ms: reason += " after " + self.format_float_value(ms.group(1)) + " transferred"
599
604
  self.QCANCEL[taskid] = reason
600
605
  self.pglog("{}: Cancel Task due to {}".format(taskid, reason), self.LOGWRN)
601
606
  ccmd = f"{bcmd} cancel-task {taskid}"
@@ -603,6 +608,7 @@ class PgFile(PgUtil, PgSIG):
603
608
  else:
604
609
  time.sleep(self.PGSIG['ETIME'])
605
610
  continue
611
+ self.QFAULTS.pop(taskid, None) # recovered, start the count over
606
612
  break
607
613
  errmsg = "Error Execute: " + cmd
608
614
  if self.PGLOG['SYSERR']:
@@ -610,11 +616,14 @@ class PgFile(PgUtil, PgSIG):
610
616
  (hstat, msg) = self.host_down_status('', self.QHOSTS[endpoint], 1, logact)
611
617
  if hstat: errmsg += "\n" + msg
612
618
  self.errlog(errmsg, 'B', loop, logact)
613
- if ret == 'S' or ret == 'A': self.ECNTS['B'] = 0 # reset error count
619
+ if ret == 'S' or ret == 'A':
620
+ self.ECNTS['B'] = 0 # reset error count
621
+ else:
622
+ self.QFAULTS.pop(taskid, None) # task is over, stop tracking its faults
614
623
  return ret
615
624
 
616
625
  # return SUCCESS if Globus transfer is done; FAILURE otherwise
617
- def check_globus_finished(self, tofile, topoint, logact = 0):
626
+ def check_globus_finished(self, tofile, topoint, logact = 0, fcnt = 0):
618
627
  """Block until a previously submitted Globus task completes.
619
628
 
620
629
  Looks up the task ID in self.TASKIDS using 'endpoint-file' as the key.
@@ -625,6 +634,8 @@ class PgFile(PgUtil, PgSIG):
625
634
  tofile (str): Destination file path used to look up the task key.
626
635
  topoint (str): Destination Globus endpoint name.
627
636
  logact (int): Logging action flags; default 0.
637
+ fcnt (int): File count of a batch task, to name the files the key cannot;
638
+ default 0 for a single-file task.
628
639
 
629
640
  Returns:
630
641
  int: self.SUCCESS on completion, self.FAILURE on error or non-success status.
@@ -655,7 +666,10 @@ class PgFile(PgUtil, PgSIG):
655
666
  del self.TASKIDS[ckey]
656
667
  else:
657
668
  status = self.QSTATS[stat] if stat in self.QSTATS else 'UNKNOWN'
658
- errmsg = "{}: Status '{}' for Task {}".format(ckey, status, taskid)
669
+ # a batch task is keyed by its first file only, so name the whole batch
670
+ # instead of blaming the one file the key happens to carry
671
+ bmsg = " and {} more file(s)".format(fcnt - 1) if fcnt > 1 else ''
672
+ errmsg = "{}{}: Status '{}' for Task {}".format(ckey, bmsg, status, taskid)
659
673
  if taskid in self.QCANCEL:
660
674
  errmsg += " - " + self.QCANCEL.pop(taskid)
661
675
  self.errlog(errmsg, 'B', 1, logact)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: rda_python_common
3
- Version: 3.0.20
3
+ Version: 3.0.21
4
4
  Summary: RDA Python common library codes shared by other RDA python packages
5
5
  Author-email: Zaihua Ji <zji@ucar.edu>
6
6
  Project-URL: Homepage, https://github.com/NCAR/rda-python-common
@@ -189,7 +189,7 @@ PgLOG.pglog("hello", PgLOG.LOGWRN)
189
189
  python -c "import rda_python_common; print(rda_python_common.__version__)"
190
190
  ```
191
191
 
192
- You should see the installed version (currently `3.0.20`). If the import
192
+ You should see the installed version (currently `3.0.21`). If the import
193
193
  fails, double-check that the active Python environment is the one where you
194
194
  ran `pip install`.
195
195