toil 5.12.0__py3-none-any.whl → 6.1.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.
- toil/__init__.py +18 -13
- toil/batchSystems/abstractBatchSystem.py +39 -13
- toil/batchSystems/abstractGridEngineBatchSystem.py +24 -24
- toil/batchSystems/awsBatch.py +14 -14
- toil/batchSystems/cleanup_support.py +7 -3
- toil/batchSystems/contained_executor.py +3 -3
- toil/batchSystems/htcondor.py +0 -1
- toil/batchSystems/kubernetes.py +34 -31
- toil/batchSystems/local_support.py +3 -1
- toil/batchSystems/lsf.py +7 -7
- toil/batchSystems/mesos/batchSystem.py +7 -7
- toil/batchSystems/options.py +32 -83
- toil/batchSystems/registry.py +104 -23
- toil/batchSystems/singleMachine.py +16 -13
- toil/batchSystems/slurm.py +87 -16
- toil/batchSystems/torque.py +0 -1
- toil/bus.py +44 -8
- toil/common.py +544 -753
- toil/cwl/__init__.py +28 -32
- toil/cwl/cwltoil.py +595 -574
- toil/cwl/utils.py +55 -10
- toil/exceptions.py +1 -1
- toil/fileStores/__init__.py +2 -2
- toil/fileStores/abstractFileStore.py +88 -14
- toil/fileStores/cachingFileStore.py +610 -549
- toil/fileStores/nonCachingFileStore.py +46 -22
- toil/job.py +182 -101
- toil/jobStores/abstractJobStore.py +161 -95
- toil/jobStores/aws/jobStore.py +23 -9
- toil/jobStores/aws/utils.py +6 -6
- toil/jobStores/fileJobStore.py +116 -18
- toil/jobStores/googleJobStore.py +16 -7
- toil/jobStores/utils.py +5 -6
- toil/leader.py +87 -56
- toil/lib/accelerators.py +10 -5
- toil/lib/aws/__init__.py +3 -14
- toil/lib/aws/ami.py +22 -9
- toil/lib/aws/iam.py +21 -13
- toil/lib/aws/session.py +2 -16
- toil/lib/aws/utils.py +4 -5
- toil/lib/compatibility.py +1 -1
- toil/lib/conversions.py +26 -3
- toil/lib/docker.py +22 -23
- toil/lib/ec2.py +10 -6
- toil/lib/ec2nodes.py +106 -100
- toil/lib/encryption/_nacl.py +2 -1
- toil/lib/generatedEC2Lists.py +325 -18
- toil/lib/io.py +49 -2
- toil/lib/misc.py +1 -1
- toil/lib/resources.py +9 -2
- toil/lib/threading.py +101 -38
- toil/options/common.py +736 -0
- toil/options/cwl.py +336 -0
- toil/options/wdl.py +37 -0
- toil/provisioners/abstractProvisioner.py +9 -4
- toil/provisioners/aws/__init__.py +3 -6
- toil/provisioners/aws/awsProvisioner.py +6 -0
- toil/provisioners/clusterScaler.py +3 -2
- toil/provisioners/gceProvisioner.py +2 -2
- toil/realtimeLogger.py +2 -1
- toil/resource.py +24 -18
- toil/server/app.py +2 -3
- toil/server/cli/wes_cwl_runner.py +4 -4
- toil/server/utils.py +1 -1
- toil/server/wes/abstract_backend.py +3 -2
- toil/server/wes/amazon_wes_utils.py +5 -4
- toil/server/wes/tasks.py +2 -3
- toil/server/wes/toil_backend.py +2 -10
- toil/server/wsgi_app.py +2 -0
- toil/serviceManager.py +12 -10
- toil/statsAndLogging.py +41 -9
- toil/test/__init__.py +29 -54
- toil/test/batchSystems/batchSystemTest.py +11 -111
- toil/test/batchSystems/test_slurm.py +24 -8
- toil/test/cactus/__init__.py +0 -0
- toil/test/cactus/test_cactus_integration.py +58 -0
- toil/test/cwl/cwlTest.py +438 -223
- toil/test/cwl/glob_dir.cwl +15 -0
- toil/test/cwl/preemptible.cwl +21 -0
- toil/test/cwl/preemptible_expression.cwl +28 -0
- toil/test/cwl/revsort.cwl +1 -1
- toil/test/cwl/revsort2.cwl +1 -1
- toil/test/docs/scriptsTest.py +2 -3
- toil/test/jobStores/jobStoreTest.py +34 -21
- toil/test/lib/aws/test_iam.py +4 -14
- toil/test/lib/aws/test_utils.py +0 -3
- toil/test/lib/dockerTest.py +4 -4
- toil/test/lib/test_ec2.py +12 -17
- toil/test/mesos/helloWorld.py +4 -5
- toil/test/mesos/stress.py +1 -1
- toil/test/{wdl/conftest.py → options/__init__.py} +0 -10
- toil/test/options/options.py +37 -0
- toil/test/provisioners/aws/awsProvisionerTest.py +9 -5
- toil/test/provisioners/clusterScalerTest.py +6 -4
- toil/test/provisioners/clusterTest.py +23 -11
- toil/test/provisioners/gceProvisionerTest.py +0 -6
- toil/test/provisioners/restartScript.py +3 -2
- toil/test/server/serverTest.py +1 -1
- toil/test/sort/restart_sort.py +2 -1
- toil/test/sort/sort.py +2 -1
- toil/test/sort/sortTest.py +2 -13
- toil/test/src/autoDeploymentTest.py +45 -45
- toil/test/src/busTest.py +5 -5
- toil/test/src/checkpointTest.py +2 -2
- toil/test/src/deferredFunctionTest.py +1 -1
- toil/test/src/fileStoreTest.py +32 -16
- toil/test/src/helloWorldTest.py +1 -1
- toil/test/src/importExportFileTest.py +1 -1
- toil/test/src/jobDescriptionTest.py +2 -1
- toil/test/src/jobServiceTest.py +1 -1
- toil/test/src/jobTest.py +18 -18
- toil/test/src/miscTests.py +5 -3
- toil/test/src/promisedRequirementTest.py +3 -3
- toil/test/src/realtimeLoggerTest.py +1 -1
- toil/test/src/resourceTest.py +2 -2
- toil/test/src/restartDAGTest.py +1 -1
- toil/test/src/resumabilityTest.py +36 -2
- toil/test/src/retainTempDirTest.py +1 -1
- toil/test/src/systemTest.py +2 -2
- toil/test/src/toilContextManagerTest.py +2 -2
- toil/test/src/userDefinedJobArgTypeTest.py +1 -1
- toil/test/utils/toilDebugTest.py +98 -32
- toil/test/utils/toilKillTest.py +2 -2
- toil/test/utils/utilsTest.py +23 -3
- toil/test/wdl/wdltoil_test.py +223 -45
- toil/toilState.py +7 -6
- toil/utils/toilClean.py +1 -1
- toil/utils/toilConfig.py +36 -0
- toil/utils/toilDebugFile.py +60 -33
- toil/utils/toilDebugJob.py +39 -12
- toil/utils/toilDestroyCluster.py +1 -1
- toil/utils/toilKill.py +1 -1
- toil/utils/toilLaunchCluster.py +13 -2
- toil/utils/toilMain.py +3 -2
- toil/utils/toilRsyncCluster.py +1 -1
- toil/utils/toilSshCluster.py +1 -1
- toil/utils/toilStats.py +445 -305
- toil/utils/toilStatus.py +2 -5
- toil/version.py +10 -10
- toil/wdl/utils.py +2 -122
- toil/wdl/wdltoil.py +1257 -492
- toil/worker.py +55 -46
- toil-6.1.0.dist-info/METADATA +124 -0
- toil-6.1.0.dist-info/RECORD +241 -0
- {toil-5.12.0.dist-info → toil-6.1.0.dist-info}/WHEEL +1 -1
- {toil-5.12.0.dist-info → toil-6.1.0.dist-info}/entry_points.txt +0 -1
- toil/batchSystems/parasol.py +0 -379
- toil/batchSystems/tes.py +0 -459
- toil/test/batchSystems/parasolTestSupport.py +0 -117
- toil/test/wdl/builtinTest.py +0 -506
- toil/test/wdl/toilwdlTest.py +0 -522
- toil/wdl/toilwdl.py +0 -141
- toil/wdl/versions/dev.py +0 -107
- toil/wdl/versions/draft2.py +0 -980
- toil/wdl/versions/v1.py +0 -794
- toil/wdl/wdl_analysis.py +0 -116
- toil/wdl/wdl_functions.py +0 -997
- toil/wdl/wdl_synthesis.py +0 -1011
- toil/wdl/wdl_types.py +0 -243
- toil-5.12.0.dist-info/METADATA +0 -118
- toil-5.12.0.dist-info/RECORD +0 -244
- /toil/{wdl/versions → options}/__init__.py +0 -0
- {toil-5.12.0.dist-info → toil-6.1.0.dist-info}/LICENSE +0 -0
- {toil-5.12.0.dist-info → toil-6.1.0.dist-info}/top_level.txt +0 -0
|
@@ -21,26 +21,28 @@ from contextlib import contextmanager
|
|
|
21
21
|
from typing import (IO,
|
|
22
22
|
Any,
|
|
23
23
|
Callable,
|
|
24
|
+
ContextManager,
|
|
24
25
|
DefaultDict,
|
|
25
26
|
Dict,
|
|
26
27
|
Generator,
|
|
27
28
|
Iterator,
|
|
28
29
|
List,
|
|
30
|
+
Literal,
|
|
29
31
|
Optional,
|
|
30
32
|
Union,
|
|
31
|
-
cast
|
|
33
|
+
cast,
|
|
34
|
+
overload)
|
|
32
35
|
|
|
33
36
|
import dill
|
|
34
37
|
|
|
35
|
-
from toil.common import
|
|
38
|
+
from toil.common import getFileSystemSize
|
|
36
39
|
from toil.fileStores import FileID
|
|
37
40
|
from toil.fileStores.abstractFileStore import AbstractFileStore
|
|
38
41
|
from toil.job import Job, JobDescription
|
|
39
42
|
from toil.jobStores.abstractJobStore import AbstractJobStore
|
|
40
43
|
from toil.lib.compatibility import deprecated
|
|
41
|
-
from toil.lib.conversions import bytes2human
|
|
42
44
|
from toil.lib.io import make_public_dir, robust_rmtree
|
|
43
|
-
from toil.lib.retry import
|
|
45
|
+
from toil.lib.retry import ErrorCondition, retry
|
|
44
46
|
from toil.lib.threading import get_process_name, process_name_exists
|
|
45
47
|
|
|
46
48
|
logger: logging.Logger = logging.getLogger(__name__)
|
|
@@ -99,7 +101,6 @@ class NonCachingFileStore(AbstractFileStore):
|
|
|
99
101
|
|
|
100
102
|
@contextmanager
|
|
101
103
|
def open(self, job: Job) -> Generator[None, None, None]:
|
|
102
|
-
jobReqs = job.disk
|
|
103
104
|
startingDir = os.getcwd()
|
|
104
105
|
self.localTempDir: str = make_public_dir(in_directory=self.localTempDir)
|
|
105
106
|
self._removeDeadJobs(self.coordination_dir)
|
|
@@ -113,20 +114,14 @@ class NonCachingFileStore(AbstractFileStore):
|
|
|
113
114
|
with super().open(job):
|
|
114
115
|
yield
|
|
115
116
|
finally:
|
|
116
|
-
disk = getDirSizeRecursively(self.localTempDir)
|
|
117
|
-
percent = float(disk) / jobReqs * 100 if jobReqs > 0 else 0.0
|
|
118
|
-
disk_usage = (f"Job {self.jobName} used {percent:.2f}% disk ({bytes2human(disk)}B [{disk}B] used, "
|
|
119
|
-
f"{bytes2human(jobReqs)}B [{jobReqs}B] requested).")
|
|
120
|
-
if disk > jobReqs:
|
|
121
|
-
self.logToMaster("Job used more disk than requested. For CWL, consider increasing the outdirMin "
|
|
122
|
-
f"requirement, otherwise, consider increasing the disk requirement. {disk_usage}",
|
|
123
|
-
level=logging.WARNING)
|
|
124
|
-
else:
|
|
125
|
-
self.logToMaster(disk_usage, level=logging.DEBUG)
|
|
126
117
|
os.chdir(startingDir)
|
|
127
118
|
# Finally delete the job from the worker
|
|
128
119
|
self.check_for_state_corruption()
|
|
129
|
-
|
|
120
|
+
try:
|
|
121
|
+
os.remove(self.jobStateFile)
|
|
122
|
+
except FileNotFoundError:
|
|
123
|
+
logger.exception('Job state file %s has gone missing unexpectedly; some cleanup for failed jobs may be getting skipped!', self.jobStateFile)
|
|
124
|
+
pass
|
|
130
125
|
|
|
131
126
|
def writeGlobalFile(self, localFileName: str, cleanup: bool=False) -> FileID:
|
|
132
127
|
absLocalFileName = self._resolveAbsoluteLocalPath(localFileName)
|
|
@@ -152,7 +147,25 @@ class NonCachingFileStore(AbstractFileStore):
|
|
|
152
147
|
self.logAccess(fileStoreID, localFilePath)
|
|
153
148
|
return localFilePath
|
|
154
149
|
|
|
155
|
-
@
|
|
150
|
+
@overload
|
|
151
|
+
def readGlobalFileStream(
|
|
152
|
+
self,
|
|
153
|
+
fileStoreID: str,
|
|
154
|
+
encoding: Literal[None] = None,
|
|
155
|
+
errors: Optional[str] = None,
|
|
156
|
+
) -> ContextManager[IO[bytes]]:
|
|
157
|
+
...
|
|
158
|
+
|
|
159
|
+
@overload
|
|
160
|
+
def readGlobalFileStream(
|
|
161
|
+
self, fileStoreID: str, encoding: str, errors: Optional[str] = None
|
|
162
|
+
) -> ContextManager[IO[str]]:
|
|
163
|
+
...
|
|
164
|
+
|
|
165
|
+
# TODO: This seems to hit https://github.com/python/mypy/issues/11373
|
|
166
|
+
# But that is supposedly fixed.
|
|
167
|
+
|
|
168
|
+
@contextmanager # type: ignore
|
|
156
169
|
def readGlobalFileStream(self, fileStoreID: str, encoding: Optional[str] = None, errors: Optional[str] = None) -> Iterator[Union[IO[bytes], IO[str]]]:
|
|
157
170
|
with self.jobStore.read_file_stream(fileStoreID, encoding=encoding, errors=errors) as f:
|
|
158
171
|
self.logAccess(fileStoreID)
|
|
@@ -194,18 +207,21 @@ class NonCachingFileStore(AbstractFileStore):
|
|
|
194
207
|
if self.waitForPreviousCommit is not None:
|
|
195
208
|
self.waitForPreviousCommit()
|
|
196
209
|
|
|
210
|
+
# We are going to commit synchronously, so no need to clone a snapshot
|
|
211
|
+
# of the job description or mess with its version numbering.
|
|
212
|
+
|
|
197
213
|
if not jobState:
|
|
198
214
|
# All our operations that need committing are job state related
|
|
199
215
|
return
|
|
200
216
|
|
|
201
217
|
try:
|
|
202
|
-
# Indicate any files that should be deleted once the
|
|
203
|
-
# the job
|
|
218
|
+
# Indicate any files that should be seen as deleted once the
|
|
219
|
+
# update of the job description is visible.
|
|
220
|
+
if len(self.jobDesc.filesToDelete) > 0:
|
|
221
|
+
raise RuntimeError("Job is already in the process of being committed!")
|
|
204
222
|
self.jobDesc.filesToDelete = list(self.filesToDelete)
|
|
205
223
|
# Complete the job
|
|
206
224
|
self.jobStore.update_job(self.jobDesc)
|
|
207
|
-
# Delete any remnant jobs
|
|
208
|
-
list(map(self.jobStore.delete_job, self.jobsToDelete))
|
|
209
225
|
# Delete any remnant files
|
|
210
226
|
list(map(self.jobStore.delete_file, self.filesToDelete))
|
|
211
227
|
# Remove the files to delete list, having successfully removed the files
|
|
@@ -217,6 +233,7 @@ class NonCachingFileStore(AbstractFileStore):
|
|
|
217
233
|
self._terminateEvent.set()
|
|
218
234
|
raise
|
|
219
235
|
|
|
236
|
+
|
|
220
237
|
def __del__(self) -> None:
|
|
221
238
|
"""
|
|
222
239
|
Cleanup function that is run when destroying the class instance. Nothing to do since there
|
|
@@ -299,6 +316,10 @@ class NonCachingFileStore(AbstractFileStore):
|
|
|
299
316
|
# This is a FileNotFoundError.
|
|
300
317
|
# job finished & deleted its jobState file since the jobState files were discovered
|
|
301
318
|
continue
|
|
319
|
+
elif e.errno == 5:
|
|
320
|
+
# This is a OSError: [Errno 5] Input/output error (jobStatefile seems to disappear
|
|
321
|
+
# on network file system sometimes)
|
|
322
|
+
continue
|
|
302
323
|
else:
|
|
303
324
|
raise
|
|
304
325
|
|
|
@@ -329,7 +350,10 @@ class NonCachingFileStore(AbstractFileStore):
|
|
|
329
350
|
jobState = {'jobProcessName': get_process_name(self.coordination_dir),
|
|
330
351
|
'jobName': self.jobName,
|
|
331
352
|
'jobDir': self.localTempDir}
|
|
332
|
-
|
|
353
|
+
try:
|
|
354
|
+
(fd, jobStateFile) = tempfile.mkstemp(suffix='.jobState.tmp', dir=self.coordination_dir)
|
|
355
|
+
except Exception as e:
|
|
356
|
+
raise RuntimeError("Could not make state file in " + self.coordination_dir) from e
|
|
333
357
|
with open(fd, 'wb') as fH:
|
|
334
358
|
# Write data
|
|
335
359
|
dill.dump(jobState, fH)
|