toil 6.1.0a1__py3-none-any.whl → 7.0.0__py3-none-any.whl

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 (104) hide show
  1. toil/__init__.py +1 -232
  2. toil/batchSystems/abstractBatchSystem.py +41 -17
  3. toil/batchSystems/abstractGridEngineBatchSystem.py +79 -65
  4. toil/batchSystems/awsBatch.py +8 -8
  5. toil/batchSystems/cleanup_support.py +7 -3
  6. toil/batchSystems/contained_executor.py +4 -5
  7. toil/batchSystems/gridengine.py +1 -1
  8. toil/batchSystems/htcondor.py +5 -5
  9. toil/batchSystems/kubernetes.py +25 -11
  10. toil/batchSystems/local_support.py +3 -3
  11. toil/batchSystems/lsf.py +9 -9
  12. toil/batchSystems/mesos/batchSystem.py +4 -4
  13. toil/batchSystems/mesos/executor.py +3 -2
  14. toil/batchSystems/options.py +9 -0
  15. toil/batchSystems/singleMachine.py +11 -10
  16. toil/batchSystems/slurm.py +129 -16
  17. toil/batchSystems/torque.py +1 -1
  18. toil/bus.py +45 -3
  19. toil/common.py +56 -31
  20. toil/cwl/cwltoil.py +442 -371
  21. toil/deferred.py +1 -1
  22. toil/exceptions.py +1 -1
  23. toil/fileStores/abstractFileStore.py +69 -20
  24. toil/fileStores/cachingFileStore.py +6 -22
  25. toil/fileStores/nonCachingFileStore.py +6 -15
  26. toil/job.py +270 -86
  27. toil/jobStores/abstractJobStore.py +37 -31
  28. toil/jobStores/aws/jobStore.py +280 -218
  29. toil/jobStores/aws/utils.py +60 -31
  30. toil/jobStores/conftest.py +2 -2
  31. toil/jobStores/fileJobStore.py +3 -3
  32. toil/jobStores/googleJobStore.py +3 -4
  33. toil/leader.py +89 -38
  34. toil/lib/aws/__init__.py +26 -10
  35. toil/lib/aws/iam.py +2 -2
  36. toil/lib/aws/session.py +62 -22
  37. toil/lib/aws/utils.py +73 -37
  38. toil/lib/conversions.py +24 -1
  39. toil/lib/ec2.py +118 -69
  40. toil/lib/expando.py +1 -1
  41. toil/lib/generatedEC2Lists.py +8 -8
  42. toil/lib/io.py +42 -4
  43. toil/lib/misc.py +1 -3
  44. toil/lib/resources.py +57 -16
  45. toil/lib/retry.py +12 -5
  46. toil/lib/threading.py +29 -14
  47. toil/lib/throttle.py +1 -1
  48. toil/options/common.py +31 -30
  49. toil/options/wdl.py +5 -0
  50. toil/provisioners/__init__.py +9 -3
  51. toil/provisioners/abstractProvisioner.py +12 -2
  52. toil/provisioners/aws/__init__.py +20 -15
  53. toil/provisioners/aws/awsProvisioner.py +406 -329
  54. toil/provisioners/gceProvisioner.py +2 -2
  55. toil/provisioners/node.py +13 -5
  56. toil/server/app.py +1 -1
  57. toil/statsAndLogging.py +93 -23
  58. toil/test/__init__.py +27 -12
  59. toil/test/batchSystems/batchSystemTest.py +40 -33
  60. toil/test/batchSystems/batch_system_plugin_test.py +79 -0
  61. toil/test/batchSystems/test_slurm.py +22 -7
  62. toil/test/cactus/__init__.py +0 -0
  63. toil/test/cactus/test_cactus_integration.py +58 -0
  64. toil/test/cwl/cwlTest.py +245 -236
  65. toil/test/cwl/seqtk_seq.cwl +1 -1
  66. toil/test/docs/scriptsTest.py +11 -14
  67. toil/test/jobStores/jobStoreTest.py +40 -54
  68. toil/test/lib/aws/test_iam.py +2 -2
  69. toil/test/lib/test_ec2.py +1 -1
  70. toil/test/options/__init__.py +13 -0
  71. toil/test/options/options.py +37 -0
  72. toil/test/provisioners/aws/awsProvisionerTest.py +51 -34
  73. toil/test/provisioners/clusterTest.py +99 -16
  74. toil/test/server/serverTest.py +2 -2
  75. toil/test/src/autoDeploymentTest.py +1 -1
  76. toil/test/src/dockerCheckTest.py +2 -1
  77. toil/test/src/environmentTest.py +125 -0
  78. toil/test/src/fileStoreTest.py +1 -1
  79. toil/test/src/jobDescriptionTest.py +18 -8
  80. toil/test/src/jobTest.py +1 -1
  81. toil/test/src/realtimeLoggerTest.py +4 -0
  82. toil/test/src/workerTest.py +52 -19
  83. toil/test/utils/toilDebugTest.py +62 -4
  84. toil/test/utils/utilsTest.py +23 -21
  85. toil/test/wdl/wdltoil_test.py +49 -21
  86. toil/test/wdl/wdltoil_test_kubernetes.py +77 -0
  87. toil/toilState.py +68 -9
  88. toil/utils/toilDebugFile.py +1 -1
  89. toil/utils/toilDebugJob.py +153 -26
  90. toil/utils/toilLaunchCluster.py +12 -2
  91. toil/utils/toilRsyncCluster.py +7 -2
  92. toil/utils/toilSshCluster.py +7 -3
  93. toil/utils/toilStats.py +310 -266
  94. toil/utils/toilStatus.py +98 -52
  95. toil/version.py +11 -11
  96. toil/wdl/wdltoil.py +644 -225
  97. toil/worker.py +125 -83
  98. {toil-6.1.0a1.dist-info → toil-7.0.0.dist-info}/LICENSE +25 -0
  99. toil-7.0.0.dist-info/METADATA +158 -0
  100. {toil-6.1.0a1.dist-info → toil-7.0.0.dist-info}/RECORD +103 -96
  101. {toil-6.1.0a1.dist-info → toil-7.0.0.dist-info}/WHEEL +1 -1
  102. toil-6.1.0a1.dist-info/METADATA +0 -125
  103. {toil-6.1.0a1.dist-info → toil-7.0.0.dist-info}/entry_points.txt +0 -0
  104. {toil-6.1.0a1.dist-info → toil-7.0.0.dist-info}/top_level.txt +0 -0
@@ -70,6 +70,14 @@ except ImportError:
70
70
  class ProxyConnectionError(BaseException): # type: ignore
71
71
  """Dummy class."""
72
72
 
73
+ class LocatorException(Exception):
74
+ """
75
+ Base exception class for all locator exceptions.
76
+ For example, job store/aws bucket exceptions where they already exist
77
+ """
78
+ def __init__(self, error_msg: str, locator: str, prefix: Optional[str]=None):
79
+ full_locator = locator if prefix is None else f"{prefix}:{locator}"
80
+ super().__init__(error_msg % full_locator)
73
81
 
74
82
  class InvalidImportExportUrlException(Exception):
75
83
  def __init__(self, url: ParseResult) -> None:
@@ -136,24 +144,24 @@ class NoSuchFileException(Exception):
136
144
  super().__init__(message)
137
145
 
138
146
 
139
- class NoSuchJobStoreException(Exception):
147
+ class NoSuchJobStoreException(LocatorException):
140
148
  """Indicates that the specified job store does not exist."""
141
- def __init__(self, locator: str):
149
+ def __init__(self, locator: str, prefix: str):
142
150
  """
143
151
  :param str locator: The location of the job store
144
152
  """
145
- super().__init__("The job store '%s' does not exist, so there is nothing to restart." % locator)
153
+ super().__init__("The job store '%s' does not exist, so there is nothing to restart.", locator, prefix)
146
154
 
147
155
 
148
- class JobStoreExistsException(Exception):
156
+ class JobStoreExistsException(LocatorException):
149
157
  """Indicates that the specified job store already exists."""
150
- def __init__(self, locator: str):
158
+ def __init__(self, locator: str, prefix: str):
151
159
  """
152
160
  :param str locator: The location of the job store
153
161
  """
154
162
  super().__init__(
155
163
  "The job store '%s' already exists. Use --restart to resume the workflow, or remove "
156
- "the job store with 'toil clean' to start the workflow from scratch." % locator)
164
+ "the job store with 'toil clean' to start the workflow from scratch.", locator, prefix)
157
165
 
158
166
 
159
167
  class AbstractJobStore(ABC):
@@ -835,16 +843,17 @@ class AbstractJobStore(ABC):
835
843
  root_job_description = self.load_root_job()
836
844
  reachable_from_root: Set[str] = set()
837
845
 
838
- # Add first root job outside of the loop below.
839
- reachable_from_root.add(str(root_job_description.jobStoreID))
840
- # add all of root's linked service jobs as well
841
- for service_jobstore_id in root_job_description.services:
842
- if haveJob(service_jobstore_id):
843
- reachable_from_root.add(service_jobstore_id)
844
- for merged_jobstore_id in root_job_description.merged_jobs:
846
+
847
+ for merged_in in root_job_description.get_chain():
848
+ # Add the job itself and any other jobs that chained with it.
845
849
  # Keep merged-in jobs around themselves, but don't bother
846
850
  # exploring them, since we took their successors.
847
- reachable_from_root.add(merged_jobstore_id)
851
+ reachable_from_root.add(merged_in.job_store_id)
852
+ # add all of root's linked service jobs as well
853
+ for service_job_store_id in root_job_description.services:
854
+ if haveJob(service_job_store_id):
855
+ reachable_from_root.add(service_job_store_id)
856
+
848
857
 
849
858
  # Unprocessed means it might have successor jobs we need to add.
850
859
  unprocessed_job_descriptions = [root_job_description]
@@ -852,24 +861,21 @@ class AbstractJobStore(ABC):
852
861
  while unprocessed_job_descriptions:
853
862
  new_job_descriptions_to_process = [] # Reset.
854
863
  for job_description in unprocessed_job_descriptions:
855
- for successor_jobstore_id in job_description.allSuccessors():
856
- if successor_jobstore_id not in reachable_from_root and haveJob(successor_jobstore_id):
857
- successor_job_description = getJobDescription(successor_jobstore_id)
858
-
859
- # Add each successor job.
860
- reachable_from_root.add(
861
- str(successor_job_description.jobStoreID)
862
- )
864
+ for merged_in in job_description.get_chain():
865
+ # Add the job and anything chained with it.
866
+ # Keep merged-in jobs around themselves, but don't bother
867
+ # exploring them, since we took their successors.
868
+ reachable_from_root.add(merged_in.job_store_id)
869
+ for successor_job_store_id in job_description.allSuccessors():
870
+ if successor_job_store_id not in reachable_from_root and haveJob(successor_job_store_id):
871
+ successor_job_description = getJobDescription(successor_job_store_id)
872
+
863
873
  # Add all of the successor's linked service jobs as well.
864
- for service_jobstore_id in successor_job_description.services:
865
- if haveJob(service_jobstore_id):
866
- reachable_from_root.add(service_jobstore_id)
874
+ for service_job_store_id in successor_job_description.services:
875
+ if haveJob(service_job_store_id):
876
+ reachable_from_root.add(service_job_store_id)
867
877
 
868
878
  new_job_descriptions_to_process.append(successor_job_description)
869
- for merged_jobstore_id in job_description.merged_jobs:
870
- # Keep merged-in jobs around themselves, but don't bother
871
- # exploring them, since we took their successors.
872
- reachable_from_root.add(merged_jobstore_id)
873
879
  unprocessed_job_descriptions = new_job_descriptions_to_process
874
880
 
875
881
  logger.debug(f"{len(reachable_from_root)} jobs reachable from root.")
@@ -926,11 +932,11 @@ class AbstractJobStore(ABC):
926
932
  jobDescription.filesToDelete = []
927
933
  changed[0] = True
928
934
 
929
- # For a job whose command is already executed, remove jobs from the
935
+ # For a job whose body has already executed, remove jobs from the
930
936
  # stack that are already deleted. This cleans up the case that the
931
937
  # jobDescription had successors to run, but had not been updated to
932
938
  # reflect this.
933
- if jobDescription.command is None:
939
+ if not jobDescription.has_body():
934
940
 
935
941
  def stackSizeFn() -> int:
936
942
  return len(list(jobDescription.allSuccessors()))