Skip to content

Commit 5a6ad77

Browse files
try out new state enum
1 parent f91e0b1 commit 5a6ad77

File tree

5 files changed

+51
-34
lines changed

5 files changed

+51
-34
lines changed

core/pioreactor/background_jobs/base.py

Lines changed: 31 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
from pioreactor.pubsub import Client
2525
from pioreactor.pubsub import create_client
2626
from pioreactor.pubsub import QOS
27+
from pioreactor.state import JobState as states
2728
from pioreactor.utils import append_signal_handlers
2829
from pioreactor.utils import get_running_pio_job_id
2930
from 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

core/pioreactor/calibrations/od_calibration_single_vial.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -308,7 +308,7 @@ def get_voltage_from_adc() -> pt.Voltage:
308308
x_min=minimum_od600,
309309
x_max=initial_od600,
310310
)
311-
st.set_state("sleeping")
311+
st.set_state(pt.JobState.SLEEPING)
312312
echo()
313313
echo(style("Stop❗", fg="red"))
314314
echo("Carefully remove vial.")
@@ -320,7 +320,7 @@ def get_voltage_from_adc() -> pt.Voltage:
320320
while not confirm(green("Continue?"), default=False):
321321
pass
322322
current_volume_in_vial = initial_volume_in_vial
323-
st.set_state("ready")
323+
st.set_state(pt.JobState.READY)
324324
st.block_until_rpm_is_close_to_target(abs_tolerance=120)
325325
sleep(1.0)
326326

core/pioreactor/calibrations/od_calibration_using_standards.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,7 @@ def get_voltage_from_adc() -> float:
218218
od600_values.append(standard_od)
219219
voltages.append(voltage)
220220

221-
st.set_state("sleeping")
221+
st.set_state(pt.JobState.SLEEPING)
222222

223223
for i in range(len(od600_values)):
224224
click.clear()
@@ -242,7 +242,7 @@ def get_voltage_from_adc() -> float:
242242
click.echo()
243243
while not click.confirm(green("Confirm vial is placed in Pioreactor?"), default=True):
244244
pass
245-
st.set_state("ready")
245+
st.set_state(pt.JobState.READY)
246246
click.echo("Starting stirring.")
247247
st.block_until_rpm_is_close_to_target(abs_tolerance=120)
248248
sleep(1.0)

core/pioreactor/state.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# -*- coding: utf-8 -*-
2+
from __future__ import annotations
3+
4+
from enum import Enum
5+
6+
7+
class JobState(str, Enum):
8+
INIT = "init"
9+
READY = "ready"
10+
SLEEPING = "sleeping"
11+
DISCONNECTED = "disconnected"
12+
LOST = "lost"
13+
14+
def __str__(self) -> str:
15+
return self.value

core/pioreactor/types.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import typing as t
66

77
from msgspec import Meta
8+
from pioreactor.state import JobState # noqa: F401
89

910
if t.TYPE_CHECKING:
1011
from pioreactor.pubsub import Client
@@ -96,9 +97,6 @@ class PublishableSetting(t.TypedDict, total=False):
9697
persist: t.NotRequired[bool]
9798

9899

99-
type JobState = t.Literal["init", "ready", "sleeping", "disconnected", "lost"]
100-
101-
102100
type LedChannel = t.Literal["A", "B", "C", "D"]
103101
# these are strings! Don't make them ints, since ints suggest we can perform math on them, that's meaningless.
104102
# str suggest symbols, which they are.

0 commit comments

Comments
 (0)