6
6
import os
7
7
from pathlib import Path
8
8
import typing as ty
9
- from copy import deepcopy , copy
9
+ from copy import deepcopy
10
+ from uuid import uuid4
10
11
11
12
import cloudpickle as cp
12
13
from filelock import SoftFileLock
@@ -163,7 +164,6 @@ def __init__(
163
164
164
165
# checking if metadata is set properly
165
166
self .inputs .check_metadata ()
166
- self .state_inputs = inputs
167
167
# dictionary to save the connections with lazy fields
168
168
self .inp_lf = {}
169
169
self .state = None
@@ -184,6 +184,7 @@ def __init__(
184
184
self .cache_locations = cache_locations
185
185
self .allow_cache_override = True
186
186
self ._checksum = None
187
+ self ._uid = uuid4 ().hex
187
188
# if True the results are not checked (does not propagate to nodes)
188
189
self .task_rerun = rerun
189
190
@@ -262,6 +263,9 @@ def checksum_states(self, state_index=None):
262
263
TODO
263
264
264
265
"""
266
+ if is_workflow (self ) and self .inputs ._graph_checksums is attr .NOTHING :
267
+ self .inputs ._graph_checksums = [nd .checksum for nd in self .graph_sorted ]
268
+
265
269
if state_index is not None :
266
270
inputs_copy = deepcopy (self .inputs )
267
271
for key , ind in self .state .inputs_ind [state_index ].items ():
@@ -289,6 +293,14 @@ def checksum_states(self, state_index=None):
289
293
checksum_list .append (self .checksum_states (state_index = ind ))
290
294
return checksum_list
291
295
296
+ @property
297
+ def uid (self ):
298
+ """ the unique id number for the task
299
+ It will be used to create unique names for slurm scripts etc.
300
+ without a need to run checksum
301
+ """
302
+ return self ._uid
303
+
292
304
def set_state (self , splitter , combiner = None ):
293
305
"""
294
306
Set a particular state on this task.
@@ -410,7 +422,10 @@ def _run(self, rerun=False, **kwargs):
410
422
lockfile = self .cache_dir / (checksum + ".lock" )
411
423
# Eagerly retrieve cached - see scenarios in __init__()
412
424
self .hooks .pre_run (self )
413
- # TODO add signal handler for processes killed after lock acquisition
425
+ # adding info file with the checksum in case the task was cancelled
426
+ # and the lockfile has to be removed
427
+ with open (self .cache_dir / f"{ self .uid } _info.json" , "w" ) as jsonfile :
428
+ json .dump ({"checksum" : self .checksum }, jsonfile )
414
429
with SoftFileLock (lockfile ):
415
430
if not (rerun or self .task_rerun ):
416
431
result = self .result ()
@@ -444,6 +459,8 @@ def _run(self, rerun=False, **kwargs):
444
459
self .hooks .post_run_task (self , result )
445
460
self .audit .finalize_audit (result )
446
461
save (odir , result = result , task = self )
462
+ # removing the additional file with the chcksum
463
+ (self .cache_dir / f"{ self .uid } _info.json" ).unlink ()
447
464
# # function etc. shouldn't change anyway, so removing
448
465
orig_inputs = dict (
449
466
(k , v ) for (k , v ) in orig_inputs .items () if not k .startswith ("_" )
@@ -481,7 +498,6 @@ def split(self, splitter, overwrite=False, **kwargs):
481
498
)
482
499
if kwargs :
483
500
self .inputs = attr .evolve (self .inputs , ** kwargs )
484
- self .state_inputs = kwargs
485
501
if not self .state or splitter != self .state .splitter :
486
502
self .set_state (splitter )
487
503
return self
@@ -548,8 +564,8 @@ def pickle_task(self):
548
564
""" Pickling the tasks with full inputs"""
549
565
pkl_files = self .cache_dir / "pkl_files"
550
566
pkl_files .mkdir (exist_ok = True , parents = True )
551
- task_main_path = pkl_files / f"{ self .name } _{ self .checksum } _task.pklz"
552
- save (task_path = pkl_files , task = self , name_prefix = f"{ self .name } _{ self .checksum } " )
567
+ task_main_path = pkl_files / f"{ self .name } _{ self .uid } _task.pklz"
568
+ save (task_path = pkl_files , task = self , name_prefix = f"{ self .name } _{ self .uid } " )
553
569
return task_main_path
554
570
555
571
@property
@@ -935,7 +951,6 @@ async def _run(self, submitter=None, rerun=False, **kwargs):
935
951
"Workflow output cannot be None, use set_output to define output(s)"
936
952
)
937
953
checksum = self .checksum
938
- lockfile = self .cache_dir / (checksum + ".lock" )
939
954
# Eagerly retrieve cached
940
955
if not (rerun or self .task_rerun ):
941
956
result = self .result ()
@@ -953,6 +968,11 @@ async def _run(self, submitter=None, rerun=False, **kwargs):
953
968
task .cache_locations = task ._cache_locations + self .cache_locations
954
969
self .create_connections (task )
955
970
# TODO add signal handler for processes killed after lock acquisition
971
+ # adding info file with the checksum in case the task was cancelled
972
+ # and the lockfile has to be removed
973
+ with open (self .cache_dir / f"{ self .uid } _info.json" , "w" ) as jsonfile :
974
+ json .dump ({"checksum" : checksum }, jsonfile )
975
+ lockfile = self .cache_dir / (checksum + ".lock" )
956
976
self .hooks .pre_run (self )
957
977
with SoftFileLock (lockfile ):
958
978
# # Let only one equivalent process run
@@ -977,6 +997,8 @@ async def _run(self, submitter=None, rerun=False, **kwargs):
977
997
self .hooks .post_run_task (self , result )
978
998
self .audit .finalize_audit (result = result )
979
999
save (odir , result = result , task = self )
1000
+ # removing the additional file with the chcksum
1001
+ (self .cache_dir / f"{ self .uid } _info.json" ).unlink ()
980
1002
os .chdir (cwd )
981
1003
self .hooks .post_run (self , result )
982
1004
return result
0 commit comments