2424from pioreactor .pubsub import Client
2525from pioreactor .pubsub import create_client
2626from pioreactor .pubsub import QOS
27+ from pioreactor .state import JobState as states
2728from pioreactor .utils import append_signal_handlers
2829from pioreactor .utils import get_running_pio_job_id
2930from pioreactor .utils import is_pio_job_running
@@ -235,11 +236,11 @@ class _BackgroundJob(metaclass=PostInitCaller):
235236 """
236237
237238 # Homie lifecycle (normally per device (i.e. an rpi) but we are using it for "nodes", in Homie parlance)
238- INIT : pt .JobState = "init"
239- READY : pt .JobState = "ready"
240- DISCONNECTED : pt .JobState = "disconnected"
241- SLEEPING : pt .JobState = "sleeping"
242- LOST : pt .JobState = "lost"
239+ INIT : pt .JobState = states . INIT
240+ READY : pt .JobState = states . READY
241+ DISCONNECTED : pt .JobState = states . DISCONNECTED
242+ SLEEPING : pt .JobState = states . SLEEPING
243+ LOST : pt .JobState = states . LOST
243244
244245 # initial state is disconnected, set other metadata
245246 state = DISCONNECTED
@@ -317,7 +318,7 @@ def __init__(self, unit: pt.Unit, experiment: pt.Experiment, source: str = "app"
317318 }
318319
319320 # this comes _after_ adding state to published settings
320- self .set_state (self .INIT )
321+ self .set_state (states .INIT )
321322
322323 self ._set_up_exit_protocol ()
323324 self ._blocking_event = threading .Event ()
@@ -357,7 +358,7 @@ def __post__init__(self) -> None:
357358 """
358359 # setting READY should happen after we write to the job manager, since a job might do a long-running
359360 # task in on_ready, which delays writing to the db, which means `pio kill` might not see it.
360- self .set_state (self .READY )
361+ self .set_state (states .READY )
361362
362363 @property
363364 def job_key (self ):
@@ -494,23 +495,27 @@ def set_state(self, new_state: pt.JobState) -> None:
494495
495496 """
496497
497- if new_state not in {self .INIT , self .READY , self .DISCONNECTED , self .SLEEPING , self .LOST }:
498+ try :
499+ new_state_enum = pt .JobState (new_state )
500+ except ValueError :
498501 self .logger .error (f"saw { new_state } : not a valid state" )
499502 return
500503
501- if new_state == self .state :
504+ current_state = pt .JobState (self .state )
505+
506+ if new_state_enum == current_state :
502507 return
503508
504- if hasattr (self , f"on_{ self . state } _to_{ new_state } " ):
509+ if hasattr (self , f"on_{ current_state } _to_{ new_state_enum } " ):
505510 try :
506- getattr (self , f"on_{ self . state } _to_{ new_state } " )()
511+ getattr (self , f"on_{ current_state } _to_{ new_state_enum } " )()
507512 except Exception as e :
508- self .logger .debug (f"Error in on_{ self . state } _to_{ new_state } " )
513+ self .logger .debug (f"Error in on_{ current_state } _to_{ new_state_enum } " )
509514 self .logger .debug (e , exc_info = True )
510515 self .logger .error (e )
511516 return
512517
513- getattr (self , new_state )()
518+ getattr (self , new_state_enum )()
514519
515520 def block_until_disconnected (self ) -> None :
516521 """
@@ -546,8 +551,8 @@ def clean_up(self) -> None:
546551 """
547552 Disconnect from brokers, set state to "disconnected", stop any activity.
548553 """
549- if self .state != self .DISCONNECTED :
550- self .set_state (self .DISCONNECTED )
554+ if self .state is not states .DISCONNECTED :
555+ self .set_state (states .DISCONNECTED )
551556 self ._clean_up_resources ()
552557
553558 def add_to_published_settings (self , setting : str , props : pt .PublishableSetting ) -> None :
@@ -740,7 +745,7 @@ def exit_gracefully(reason: int | str, *args) -> None:
740745 pass
741746
742747 def init (self ) -> None :
743- self .state = self .INIT
748+ self .state = states .INIT
744749
745750 try :
746751 # we delay the specific on_init until after we have done our important protocols.
@@ -754,7 +759,7 @@ def init(self) -> None:
754759 self ._log_state (self .state )
755760
756761 def ready (self ) -> None :
757- self .state = self .READY
762+ self .state = states .READY
758763
759764 try :
760765 self .on_ready ()
@@ -766,7 +771,7 @@ def ready(self) -> None:
766771 self ._log_state (self .state )
767772
768773 def sleeping (self ) -> None :
769- self .state = self .SLEEPING
774+ self .state = states .SLEEPING
770775
771776 try :
772777 self .on_sleeping ()
@@ -783,7 +788,7 @@ def lost(self) -> None:
783788 # 1. Monitor can send a lost signal if `check_against_processes_running` triggers.
784789 # I think it makes sense to ignore it?
785790
786- self .state = self .LOST
791+ self .state = states .LOST
787792 self ._log_state (self .state )
788793
789794 def disconnected (self ) -> None :
@@ -800,7 +805,7 @@ def disconnected(self) -> None:
800805 self .logger .debug ("Error in on_disconnected:" )
801806 self .logger .debug (e , exc_info = True )
802807
803- self .state = self .DISCONNECTED
808+ self .state = states .DISCONNECTED
804809 self ._log_state (self .state )
805810
806811 # we "set" the internal event, which will cause any event.waits to end blocking. This should happen last.
@@ -858,7 +863,7 @@ def _publish_defined_settings_to_broker(
858863 self ._publish_setting (name )
859864
860865 def _log_state (self , state : pt .JobState ) -> None :
861- if state in ( self .READY , self .DISCONNECTED , self .LOST ) :
866+ if state in { states .READY , states .DISCONNECTED , states .LOST } :
862867 self .logger .info (state .capitalize () + "." )
863868 else :
864869 self .logger .debug (state .capitalize () + "." )
@@ -1155,16 +1160,16 @@ def __post__init__(self):
11551160 )
11561161 super ().__post__init__ () # set ready
11571162
1158- def _desired_dodging_mode (self , enable_dodging_od : bool , od_state : str | None ) -> bool :
1163+ def _desired_dodging_mode (self , enable_dodging_od : bool , od_state : pt . JobState | None ) -> bool :
11591164 """Return True if we should dodge based on enable flag and OD state."""
11601165 if not enable_dodging_od :
11611166 return False
11621167 # enable_dodging_od is true - user wants it on
11631168 if od_state is None :
11641169 return False
1165- if od_state in {self .READY , self .SLEEPING , self .INIT }:
1170+ if od_state in {states .READY , states .SLEEPING , states .INIT }:
11661171 return True
1167- if od_state in {self .LOST , self .DISCONNECTED }:
1172+ if od_state in {states .LOST , states .DISCONNECTED }:
11681173 return False
11691174 return False
11701175
@@ -1202,8 +1207,7 @@ def set_currently_dodging_od(self, value: bool):
12021207 def set_enable_dodging_od (self , value : bool ):
12031208 """Turn dodging on/off based on user intent, then align mode with current OD state."""
12041209 self .enable_dodging_od = value
1205- od_running = is_pio_job_running ("od_reading" )
1206- od_state = self .READY if od_running else self .DISCONNECTED
1210+ od_state = states .READY if is_pio_job_running ("od_reading" ) else states .DISCONNECTED
12071211
12081212 desired = self ._desired_dodging_mode (self .enable_dodging_od , od_state )
12091213 self .set_currently_dodging_od (desired )
@@ -1213,7 +1217,7 @@ def _od_reading_changed_status(self, state_msg: pt.MQTTMessage) -> None:
12131217 if not self .enable_dodging_od :
12141218 return
12151219
1216- new_state = state_msg .payload .decode ()
1220+ new_state = pt . JobState ( state_msg .payload .decode () )
12171221 desired = self ._desired_dodging_mode (self .enable_dodging_od , new_state )
12181222 self .set_currently_dodging_od (desired )
12191223
0 commit comments