-
Notifications
You must be signed in to change notification settings - Fork 17
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Message passing with more information #291
base: master
Are you sure you want to change the base?
Message passing with more information #291
Conversation
A lot of single quotes to double quotes changes came from my IDE linter, should be reduced if #289 get merged and this PR will contains much less line changes. |
ed2a043
to
96c5842
Compare
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #291 +/- ##
==========================================
+ Coverage 90.77% 90.90% +0.13%
==========================================
Files 22 22
Lines 2990 2999 +9
==========================================
+ Hits 2714 2726 +12
+ Misses 276 273 -3 ☔ View full report in Codecov by Sentry. |
43e1520
to
737adf3
Compare
737adf3
to
1b2864c
Compare
2ffdab2
to
d0e4e73
Compare
b218122
to
e3c2ae8
Compare
def _create_state_instance(self, state_cls: type[State], **kwargs: Any) -> State: | ||
if state_cls.LABEL not in self.get_states_map(): | ||
raise ValueError(f'{state_cls.LABEL} is not a valid state') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is one of the major changes in this PR. I made this function only create the instance as name indicated. If it is already a state instance the logic is moved directly to transition_to
method of state machine.
class PlayMessage: | ||
@classmethod | ||
def build(cls, message: str | None = None) -> MessageType: | ||
return { | ||
INTENT_KEY: Intent.PLAY, | ||
MESSAGE_KEY: message, | ||
} | ||
|
||
|
||
class PauseMessage: | ||
@classmethod | ||
def build(cls, message: str | None = None) -> MessageType: | ||
return { | ||
INTENT_KEY: Intent.PAUSE, | ||
MESSAGE_KEY: message, | ||
} | ||
|
||
|
||
class KillMessage: | ||
@classmethod | ||
def build(cls, message: str | None = None, force: bool = False) -> MessageType: | ||
return { | ||
INTENT_KEY: Intent.KILL, | ||
MESSAGE_KEY: message, | ||
FORCE_KILL_KEY: force, | ||
} | ||
|
||
|
||
class StatusMessage: | ||
@classmethod | ||
def build(cls, message: str | None = None) -> MessageType: | ||
return { | ||
INTENT_KEY: Intent.STATUS, | ||
MESSAGE_KEY: message, | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of using global variable for message and using copy.copy
to create message for different embedded message content, I use the class with build method for message build.
src/plumpy/base/state_machine.py
Outdated
@@ -300,16 +314,28 @@ def _fire_state_event(self, hook: Hashable, state: Optional[State]) -> None: | |||
def on_terminated(self) -> None: | |||
"""Called when a terminal state is entered""" | |||
|
|||
def transition_to(self, new_state: Union[Hashable, State, Type[State]], *args: Any, **kwargs: Any) -> None: | |||
def transition_to(self, new_state: State | type[State] | None, **kwargs: Any) -> None: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Build new_state with Hashable and from State class are the same, I made the use of transition_to more consistent by allow only passing the State class or an existed state.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was wrong about this, using Hashable key to get the state type is more generic, it allows to redefine the state class dynamically for the specific state machine by overriding the STATES_MAP
. I'll revert changes back.
if new_state is None: | ||
return None | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is to cover the case in Process.step
when the state.execute
lead to the next state is none from terminal state.
b1d9159
to
e5c74ad
Compare
7c105bd
to
17a541a
Compare
state_class = self.get_states_map()[process_states.ProcessState.KILLED] | ||
new_state = self._create_state_instance(state_class, msg=msg) | ||
self.transition_to(new_state) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Compare to the one liner of original implementation, the new one seems more verbose. The state object needs to be created from the state tag with the parameters directly and passed to the transition_to
. But, in my opinion, this API is a bit readable. The transition_to
now only need to deal with the case where the passed in state is an object, instead of decide whether needs to create the state instance case by case.
_create_state_instance
so it only need to do real object creation.