2929from pyrunner .core .engine import ExecutionEngine
3030from pyrunner .core .config import Config
3131from pyrunner .core .register import NodeRegister
32+ from pyrunner .core .signal import SignalHandler , SIG_ABORT , SIG_PAUSE , SIG_PULSE
3233from pyrunner .version import __version__
3334
3435from datetime import datetime as datetime
@@ -41,23 +42,25 @@ def __init__(self, **kwargs):
4142 self ._environ = os .environ .copy ()
4243 self .config = Config ()
4344 self .notification = notification .EmailNotification ()
45+ self .signal_handler = SignalHandler (self .config )
4446
4547 self .serde_obj = serde .ListSerDe ()
4648 self .register = NodeRegister ()
4749 self .engine = ExecutionEngine ()
4850
4951 self ._init_params = {
50- 'config_file' : kwargs .get ('config_file' ),
51- 'proc_file' : kwargs .get ('proc_file' ),
52- 'restart' : kwargs .get ('restart' , False ),
53- 'cvar_list' : [],
54- 'exec_proc_name' : None ,
55- 'exec_only_list' : [],
56- 'exec_disable_list' : [],
57- 'exec_from_id' : None ,
58- 'exec_to_id' : None
52+ 'config_file' : kwargs .get ('config_file' ),
53+ 'proc_file' : kwargs .get ('proc_file' ),
54+ 'restart' : kwargs .get ('restart' , False ),
55+ 'cvar_list' : [],
56+ 'exec_proc_name' : None ,
57+ 'exec_only_list' : [],
58+ 'exec_disable_list' : [],
59+ 'exec_from_id' : None ,
60+ 'exec_to_id' : None
5961 }
6062
63+ # Lifecycle hooks
6164 self ._on_create_func = None
6265 self ._on_start_func = None
6366 self ._on_restart_func = None
@@ -66,11 +69,23 @@ def __init__(self, **kwargs):
6669 self ._on_destroy_func = None
6770
6871 self .parse_args ()
72+
73+ if self .dup_proc_is_running ():
74+ raise OSError ('Another process for "{}" is already running!' .format (self .config ['app_name' ]))
6975
7076 def reset_env (self ):
7177 os .environ .clear ()
7278 os .environ .update (self ._environ )
7379
80+ def dup_proc_is_running (self ):
81+ self .signal_handler .emit (SIG_PULSE )
82+ time .sleep (1.1 )
83+ if SIG_PULSE not in self .signal_handler .peek ():
84+ print (self .signal_handler .peek ())
85+ return True
86+ else :
87+ return False
88+
7489 def load_proc_file (self , proc_file , restart = False ):
7590 if not proc_file or not os .path .isfile (proc_file ):
7691 return False
@@ -367,7 +382,7 @@ def parse_args(self):
367382 longopt_list = [
368383 'setup' , 'help' , 'nozip' , 'interactive' , 'abort' ,
369384 'restart' , 'version' , 'dryrun' , 'debug' ,
370- 'preserve-context' , 'dump-logs' , 'disable-exclusive -jobs' ,
385+ 'preserve-context' , 'dump-logs' , 'allow-duplicate -jobs' ,
371386 'email=' , 'email-on-fail=' , 'email-on-success=' , 'ef=' , 'es=' ,
372387 'env=' , 'cvar=' , 'context=' ,
373388 'to=' , 'from=' , 'descendants=' , 'ancestors=' ,
@@ -424,8 +439,8 @@ def parse_args(self):
424439 self .config ['tickrate' ] = int (arg )
425440 elif opt in ['--preserve-context' ]:
426441 self .preserve_context = True
427- elif opt in ['--disable-exclusive -jobs' ]:
428- self .disable_exclusive_jobs = True
442+ elif opt in ['--allow-duplicate -jobs' ]:
443+ self ._init_params [ 'allow_duplicate_jobs' ] = True
429444 elif opt in ['--exec-proc-name' ]:
430445 self ._init_params ['exec_proc_name' ] = arg
431446 elif opt == '--abort' :
@@ -452,7 +467,7 @@ def parse_args(self):
452467
453468 if abort :
454469 print ('Submitting ABORT signal to running job for: {}' .format (self .config ['app_name' ]))
455- open ( self .config . abort_sig_file , 'a' ). close ( )
470+ self .signal_handler . emit ( SIG_ABORT )
456471 sys .exit (0 )
457472
458473 # Check if restart is possible (ctllog/ctx files exist)
0 commit comments