rda-python-dsquasar 3.0.13__tar.gz → 3.0.15__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.
- {rda_python_dsquasar-3.0.13/src/rda_python_dsquasar.egg-info → rda_python_dsquasar-3.0.15}/PKG-INFO +1 -1
- {rda_python_dsquasar-3.0.13 → rda_python_dsquasar-3.0.15}/pyproject.toml +1 -1
- {rda_python_dsquasar-3.0.13 → rda_python_dsquasar-3.0.15}/src/rda_python_dsquasar/dsquasar.py +53 -18
- {rda_python_dsquasar-3.0.13 → rda_python_dsquasar-3.0.15/src/rda_python_dsquasar.egg-info}/PKG-INFO +1 -1
- {rda_python_dsquasar-3.0.13 → rda_python_dsquasar-3.0.15}/LICENSE +0 -0
- {rda_python_dsquasar-3.0.13 → rda_python_dsquasar-3.0.15}/MANIFEST.in +0 -0
- {rda_python_dsquasar-3.0.13 → rda_python_dsquasar-3.0.15}/README.md +0 -0
- {rda_python_dsquasar-3.0.13 → rda_python_dsquasar-3.0.15}/setup.cfg +0 -0
- {rda_python_dsquasar-3.0.13 → rda_python_dsquasar-3.0.15}/src/rda_python_dsquasar/__init__.py +0 -0
- {rda_python_dsquasar-3.0.13 → rda_python_dsquasar-3.0.15}/src/rda_python_dsquasar/ds_quasar.py +0 -0
- {rda_python_dsquasar-3.0.13 → rda_python_dsquasar-3.0.15}/src/rda_python_dsquasar/dsquasar.usg +0 -0
- {rda_python_dsquasar-3.0.13 → rda_python_dsquasar-3.0.15}/src/rda_python_dsquasar/dstacc.py +0 -0
- {rda_python_dsquasar-3.0.13 → rda_python_dsquasar-3.0.15}/src/rda_python_dsquasar/taccrec.py +0 -0
- {rda_python_dsquasar-3.0.13 → rda_python_dsquasar-3.0.15}/src/rda_python_dsquasar/tacctar.py +0 -0
- {rda_python_dsquasar-3.0.13 → rda_python_dsquasar-3.0.15}/src/rda_python_dsquasar.egg-info/SOURCES.txt +0 -0
- {rda_python_dsquasar-3.0.13 → rda_python_dsquasar-3.0.15}/src/rda_python_dsquasar.egg-info/dependency_links.txt +0 -0
- {rda_python_dsquasar-3.0.13 → rda_python_dsquasar-3.0.15}/src/rda_python_dsquasar.egg-info/entry_points.txt +0 -0
- {rda_python_dsquasar-3.0.13 → rda_python_dsquasar-3.0.15}/src/rda_python_dsquasar.egg-info/requires.txt +0 -0
- {rda_python_dsquasar-3.0.13 → rda_python_dsquasar-3.0.15}/src/rda_python_dsquasar.egg-info/top_level.txt +0 -0
- {rda_python_dsquasar-3.0.13 → rda_python_dsquasar-3.0.15}/test/test_dsquasar.py +0 -0
{rda_python_dsquasar-3.0.13/src/rda_python_dsquasar.egg-info → rda_python_dsquasar-3.0.15}/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: rda_python_dsquasar
|
|
3
|
-
Version: 3.0.
|
|
3
|
+
Version: 3.0.15
|
|
4
4
|
Summary: RDA Python package to backup and recover RDA data archives to and from GLOBUS Quasar backup server
|
|
5
5
|
Author-email: Zaihua Ji <zji@ucar.edu>
|
|
6
6
|
Project-URL: Homepage, https://github.com/NCAR/rda-python-dsquasar
|
{rda_python_dsquasar-3.0.13 → rda_python_dsquasar-3.0.15}/src/rda_python_dsquasar/dsquasar.py
RENAMED
|
@@ -104,7 +104,7 @@ class DsQuasar(PgCMD, PgSplit):
|
|
|
104
104
|
# for -A 3 but tar files for -A 2/-A 4.
|
|
105
105
|
self.MAXWORKERS = 2 # default maximum concurrent workers per command (-W)
|
|
106
106
|
self.WORKGRACE = 6*3600 # 6 hours before a running job is judged on progress
|
|
107
|
-
self.
|
|
107
|
+
self.MINWPROJ = 0.9 # projected done fraction at the walltime that counts as finishing
|
|
108
108
|
self.PGBACK = {
|
|
109
109
|
'workdir' : "{}/{}/quasar_backup".format(self.PGLOG['GDEXWORK'], self.PGLOG['COMMONUSER']),
|
|
110
110
|
'mproc' : 1,
|
|
@@ -114,6 +114,8 @@ class DsQuasar(PgCMD, PgSplit):
|
|
|
114
114
|
'backflag' : None,
|
|
115
115
|
'actmsg' : None,
|
|
116
116
|
'pstep' : 0, # record progress step for under dscheck control
|
|
117
|
+
'dcnt' : 0, # files done so far, recorded as dscheck.dcount every pstep
|
|
118
|
+
'dsize' : 0,
|
|
117
119
|
'errcnt' : 0,
|
|
118
120
|
'bckcnt' : 0,
|
|
119
121
|
'maxcnt' : 10,
|
|
@@ -399,6 +401,17 @@ class DsQuasar(PgCMD, PgSplit):
|
|
|
399
401
|
return tcnt
|
|
400
402
|
return self.pgget('bfile', '', bcnd, self.LGWNEX)
|
|
401
403
|
|
|
404
|
+
# describe how much of the registered work this run has finished. the tar counts alone
|
|
405
|
+
# do not show it: -A 3 tars each input file right after creating it, so the 'N' count
|
|
406
|
+
# stays near zero exactly while building is the busy phase, which reads as almost done
|
|
407
|
+
# when the run is barely started. dcount/fcount is the honest measure. the live dcnt is
|
|
408
|
+
# used rather than the recorded dcount, which is only flushed to RDADB every pstep files
|
|
409
|
+
def batch_done_count(self):
|
|
410
|
+
fcnt = self.DSCHK['fcount'] if 'fcount' in self.DSCHK else 0
|
|
411
|
+
dcnt = self.PGBACK['dcnt']
|
|
412
|
+
if not fcnt: return "{} file(s) done".format(dcnt)
|
|
413
|
+
return "{} of {} file(s) done({}%)".format(dcnt, fcnt, int(100*dcnt/fcnt))
|
|
414
|
+
|
|
402
415
|
# look up the dscheck record registered for a worker's argv, using the same lookup key
|
|
403
416
|
# init_dscheck builds
|
|
404
417
|
def lookup_worker_dscheck(self, argv):
|
|
@@ -409,18 +422,29 @@ class DsQuasar(PgCMD, PgSplit):
|
|
|
409
422
|
dargv = dargv[0:100]
|
|
410
423
|
return self.get_dscheck("dsquasar", dargv, self.PGBACK['workdir'], self.PGLOG['CURUID'], dargx, self.LOGWRN)
|
|
411
424
|
|
|
412
|
-
# a running batch job counts as stalled once it has run longer than WORKGRACE and
|
|
413
|
-
#
|
|
414
|
-
#
|
|
415
|
-
#
|
|
416
|
-
#
|
|
417
|
-
#
|
|
425
|
+
# a running batch job counts as stalled once it has run longer than WORKGRACE and its
|
|
426
|
+
# progress so far projects to less than MINWPROJ of its recorded work by the walltime:
|
|
427
|
+
# such a job cannot finish this attempt however long it is left alone, so an extra
|
|
428
|
+
# worker is what helps it, not more retries.
|
|
429
|
+
# the test is on the RATE, not on an absolute done fraction as it first was. a fixed
|
|
430
|
+
# 1% threshold only catches a job that is nearly frozen, and reads a job that needs
|
|
431
|
+
# weeks as progressing: the real case was 2% done after 13H35M of a 24 hour walltime,
|
|
432
|
+
# which is above 1% yet projects to 3.5% by the walltime and ~28 days to finish, and so
|
|
433
|
+
# never got a second worker.
|
|
434
|
+
# the done fraction dcount/fcount is used instead of a raw count because dcount counts
|
|
435
|
+
# GDEX files for -A 3 but tar files for -A 2/-A 4. a job that is not locked, not started
|
|
436
|
+
# yet, or whose process is gone is not stalled: init_dscheck already restarts a dead one.
|
|
437
|
+
# WALLTIME is the 24 hours asked for at submit time, since only the submitting process
|
|
438
|
+
# runs this and set_walltime_deadline reads the granted walltime back in the batch job.
|
|
439
|
+
# when the daemon caps it to a shorter queue limit the projection is optimistic, which
|
|
440
|
+
# errs towards leaving the job alone.
|
|
418
441
|
def worker_progress_stalled(self, pgrec):
|
|
419
442
|
if not (pgrec['pid'] and pgrec['stttime']): return False
|
|
420
443
|
if self.check_host_pid(pgrec['lockhost'], pgrec['pid']) <= 0: return False
|
|
421
|
-
|
|
444
|
+
elapsed = tm() - pgrec['stttime']
|
|
445
|
+
if elapsed < self.WORKGRACE: return False
|
|
422
446
|
done = pgrec['dcount']/pgrec['fcount'] if pgrec['fcount'] else 0
|
|
423
|
-
return done
|
|
447
|
+
return (done*self.WALLTIME/elapsed) < self.MINWPROJ
|
|
424
448
|
|
|
425
449
|
# whether more than one worker may run the current action. two workers stay off each
|
|
426
450
|
# other's files only through dataset locking, so the action must lock what it works on:
|
|
@@ -566,6 +590,7 @@ class DsQuasar(PgCMD, PgSplit):
|
|
|
566
590
|
'size' : 0, 'infiles' : [], 'instr' : '', 'qdsids' : [], 'abids' : [],
|
|
567
591
|
'dslocks' : [], 'qfcnt' : 0, 'qsize' : 0, 'qcnt' : 0}
|
|
568
592
|
for dsid in bfiles:
|
|
593
|
+
self.check_batch_deadline()
|
|
569
594
|
if len(qinfo['dsids']) == self.DSCNT: self.process_one_backup_file(qinfo, True, False)
|
|
570
595
|
if self.PGBACK['dolock'] and dsid not in qinfo['dslocks']:
|
|
571
596
|
if self.lock_dataset(dsid, 1, self.LOGERR) < 1: continue
|
|
@@ -682,6 +707,7 @@ class DsQuasar(PgCMD, PgSplit):
|
|
|
682
707
|
if self.lock_dataset(dsid, 1, self.LOGERR) < 1: continue
|
|
683
708
|
qinfo['dslocks'].append(dsid)
|
|
684
709
|
for bid in bfiles[dsid]:
|
|
710
|
+
self.check_batch_deadline()
|
|
685
711
|
# the status 'N' records were gathered before this dataset was locked, so they
|
|
686
712
|
# can be hours old; confirm each one is still untarred before spending a tar on
|
|
687
713
|
# it. holding the dataset lock makes this check race free against a second
|
|
@@ -729,6 +755,7 @@ class DsQuasar(PgCMD, PgSplit):
|
|
|
729
755
|
'size' : 0, 'fromfiles' : [], 'tofiles' : [], 'qdsids' : [],
|
|
730
756
|
'qfcnt' : 0, 'qsize' : 0, 'qcnt' : 0}
|
|
731
757
|
for bid in bfiles:
|
|
758
|
+
self.check_batch_deadline()
|
|
732
759
|
binfo = bfiles[bid]
|
|
733
760
|
for dsid in binfo['dsids']:
|
|
734
761
|
if dsid not in qinfo['dsids']: qinfo['dsids'].append(dsid)
|
|
@@ -840,21 +867,27 @@ class DsQuasar(PgCMD, PgSplit):
|
|
|
840
867
|
self.pglog("Cannot clean the progress report of {}; it is emailed again".format(cnd), self.LOGWRN)
|
|
841
868
|
return estat
|
|
842
869
|
|
|
843
|
-
# guard the long PBS batch jobs (-A 2/3/4/6) against the walltime: once past MAXRUNTIME
|
|
870
|
+
# guard the long PBS batch jobs (-A 2/3/4/6/7) against the walltime: once past MAXRUNTIME
|
|
844
871
|
# the run keeps going, but a progress report is parked in dscheck.einfo so that
|
|
845
872
|
# something is reported even if PBS kills the job at the walltime. the final report
|
|
846
873
|
# follows and drops the parked one if the run does finish in time. the live email
|
|
847
874
|
# buffers are saved and put back, so the final report still carries everything logged
|
|
848
875
|
# before the cutoff.
|
|
849
|
-
# both queue depths are reported rather than the current phase's
|
|
850
|
-
#
|
|
851
|
-
#
|
|
876
|
+
# both queue depths are reported rather than the current phase's, because -A 3 tars each
|
|
877
|
+
# input file right after creating it, so its status 'N' count stays near zero while that
|
|
878
|
+
# is the busy phase. they are worded as STATES ('left to build', 'tarred') and not as
|
|
879
|
+
# work this run will do: only -A 4 and -A 6 transfer, so calling the status 'T' count
|
|
880
|
+
# 'to transfer' in an -A 2 or -A 3 report claims work that run never performs.
|
|
852
881
|
# a no-op for command-line runs, other actions, before the cutoff, or once a progress
|
|
853
882
|
# report is cached.
|
|
883
|
+
# called from the top of every per-item loop, not only where a tar is dispatched: a long
|
|
884
|
+
# stretch of files that are skipped (already backed up, or not enough accumulated size to
|
|
885
|
+
# tar yet) would otherwise walk past the cutoff without ever reaching the check, which is
|
|
886
|
+
# how a 23h run reported nothing.
|
|
854
887
|
def check_batch_deadline(self):
|
|
855
888
|
act = self.PGBACK['action']
|
|
856
889
|
if self.PGBACK['einfo'] or not (self.PGBACK['doemail'] and self.PGLOG['DSCHECK']): return
|
|
857
|
-
if self.PGLOG['CURBID'] < 1 or act not in (self.TARACT, self.CTACTS, self.BCKACT, self.TBACTS): return
|
|
890
|
+
if self.PGLOG['CURBID'] < 1 or act not in (self.TARACT, self.CTACTS, self.BCKACT, self.TBACTS, self.CBACTS): return
|
|
858
891
|
elapsed = tm() - self.PGBACK['starttime']
|
|
859
892
|
if elapsed < self.MAXRUNTIME: return
|
|
860
893
|
tcnt = self.batch_tar_count('N')
|
|
@@ -862,12 +895,13 @@ class DsQuasar(PgCMD, PgSplit):
|
|
|
862
895
|
etime = self.seconds_to_string_time(int(elapsed))
|
|
863
896
|
amsg = self.ACTMSG[act]
|
|
864
897
|
bmsg = self.BACKMSG[self.PGBACK['backflag']] if self.PGBACK['backflag'] else 'backup'
|
|
865
|
-
|
|
866
|
-
|
|
898
|
+
dmsg = self.batch_done_count()
|
|
899
|
+
rmsg = "{} {} tar file(s) left to build and {} tarred".format(tcnt, bmsg, bcnt)
|
|
900
|
+
msg = "{}: Still running after {} of the {} PBS walltime, {}, with {}".format(amsg, etime, self.seconds_to_string_time(self.WALLTIME), dmsg, rmsg)
|
|
867
901
|
self.pglog(self.INDENT + msg, self.LOGACT)
|
|
868
902
|
saved = {key : self.PGLOG[key] for key in ('EMLMSG', 'ERRMSG', 'ERRCNT', 'SUMMSG', 'PRGMSG')}
|
|
869
|
-
self.set_email("{}: {} still in progress after {}, with {}!".format(self.PGBACK['cmd'], amsg, etime, rmsg), self.EMLTOP)
|
|
870
|
-
title = "dsquasar: {} in progress ({}
|
|
903
|
+
self.set_email("{}: {} still in progress after {}, {}, with {}!".format(self.PGBACK['cmd'], amsg, etime, dmsg, rmsg), self.EMLTOP)
|
|
904
|
+
title = "dsquasar: {} in progress ({})".format(amsg, dmsg)
|
|
871
905
|
if self.PGBACK['errcnt']: title += " Error({})".format(self.PGBACK['errcnt'])
|
|
872
906
|
self.report_dscheck_email(title, 1)
|
|
873
907
|
self.PGLOG.update(saved)
|
|
@@ -1092,6 +1126,7 @@ class DsQuasar(PgCMD, PgSplit):
|
|
|
1092
1126
|
fcate = filetype.lower()
|
|
1093
1127
|
tname = fcate + 'file'
|
|
1094
1128
|
for i in range(fcnt):
|
|
1129
|
+
self.check_batch_deadline()
|
|
1095
1130
|
pgrec = recs[i]
|
|
1096
1131
|
if not self.evaluate_file_stat(dsid, fcate, pgrec): continue
|
|
1097
1132
|
fname = pgrec[tname]
|
{rda_python_dsquasar-3.0.13 → rda_python_dsquasar-3.0.15/src/rda_python_dsquasar.egg-info}/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: rda_python_dsquasar
|
|
3
|
-
Version: 3.0.
|
|
3
|
+
Version: 3.0.15
|
|
4
4
|
Summary: RDA Python package to backup and recover RDA data archives to and from GLOBUS Quasar backup server
|
|
5
5
|
Author-email: Zaihua Ji <zji@ucar.edu>
|
|
6
6
|
Project-URL: Homepage, https://github.com/NCAR/rda-python-dsquasar
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{rda_python_dsquasar-3.0.13 → rda_python_dsquasar-3.0.15}/src/rda_python_dsquasar/__init__.py
RENAMED
|
File without changes
|
{rda_python_dsquasar-3.0.13 → rda_python_dsquasar-3.0.15}/src/rda_python_dsquasar/ds_quasar.py
RENAMED
|
File without changes
|
{rda_python_dsquasar-3.0.13 → rda_python_dsquasar-3.0.15}/src/rda_python_dsquasar/dsquasar.usg
RENAMED
|
File without changes
|
|
File without changes
|
{rda_python_dsquasar-3.0.13 → rda_python_dsquasar-3.0.15}/src/rda_python_dsquasar/taccrec.py
RENAMED
|
File without changes
|
{rda_python_dsquasar-3.0.13 → rda_python_dsquasar-3.0.15}/src/rda_python_dsquasar/tacctar.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|