Skip to content
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

refator/process_utils from ovos_utils #90

Merged
merged 1 commit into from
Mar 17, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
153 changes: 4 additions & 149 deletions mycroft/util/process_utils.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,13 @@
from collections import namedtuple
from enum import IntEnum
import json
import logging
import signal as sig
import sys
from threading import Event, Thread
from time import sleep

from threading import Event
from mycroft.util.log import LOG

from ovos_utils import create_daemon, wait_for_exit_signal

# backwards compat imports, DO NOT DELETE, careful with autopep8
from ovos_utils.process_utils import ProcessState, ProcessStatus, StatusCallbackMap


def reset_sigint_handler():
"""Reset the sigint handler to the default.
Expand Down Expand Up @@ -141,145 +138,3 @@ def start_message_bus_client(service, bus=None, whitelist=None):
LOG.info('Connected to messagebus')

return bus


class ProcessState(IntEnum):
"""Oredered enum to make state checks easy.

For example Alive can be determined using >= ProcessState.ALIVE,
which will return True if the state is READY as well as ALIVE.
"""
NOT_STARTED = 0
STARTED = 1
ERROR = 2
STOPPING = 3
ALIVE = 4
READY = 5


# Process state change callback mappings.
_STATUS_CALLBACKS = [
'on_started',
'on_alive',
'on_ready',
'on_error',
'on_stopping',
]

# namedtuple defaults only available on 3.7 and later python versions
if sys.version_info < (3, 7):
StatusCallbackMap = namedtuple('CallbackMap', _STATUS_CALLBACKS)
StatusCallbackMap.__new__.__defaults__ = (None,) * 5
else:
StatusCallbackMap = namedtuple(
'CallbackMap',
_STATUS_CALLBACKS,
defaults=(None,) * len(_STATUS_CALLBACKS),
)


class ProcessStatus:
"""Process status tracker.

The class tracks process status and execute callback methods on
state changes as well as replies to messagebus queries of the
process status.

Args:
name (str): process name, will be used to create the messagebus
messagetype "mycroft.{name}...".
bus (MessageBusClient): Connection to the Mycroft messagebus.
callback_map (StatusCallbackMap): optionally, status callbacks for the
various status changes.
"""

def __init__(self, name, bus=None, callback_map=None):
self.name = name
self.callbacks = callback_map or StatusCallbackMap()
self.state = ProcessState.NOT_STARTED

# Messagebus connection
self.bus = None
if bus:
self.bind(bus)

def bind(self, bus):
self.bus = bus
self._register_handlers()

def _register_handlers(self):
"""Register messagebus handlers for status queries."""
self.bus.on('mycroft.{}.is_alive'.format(self.name), self.check_alive)
self.bus.on('mycroft.{}.is_ready'.format(self.name),
self.check_ready)
# The next one is for backwards compatibility
# TODO: remove in 21.02
self.bus.on(
'mycroft.{}.all_loaded'.format(self.name), self.check_ready
)

def check_alive(self, message=None):
"""Respond to is_alive status request.

Args:
message: Optional message to respond to, if omitted no message
is sent.

Returns:
bool, True if process is alive.
"""
is_alive = self.state >= ProcessState.ALIVE

if message:
status = {'status': is_alive}
self.bus.emit(message.response(data=status))

return is_alive

def check_ready(self, message=None):
"""Respond to all_loaded status request.

Args:
message: Optional message to respond to, if omitted no message
is sent.

Returns:
bool, True if process is ready.
"""
is_ready = self.state >= ProcessState.READY
if message:
status = {'status': is_ready}
self.bus.emit(message.response(data=status))

return is_ready

def set_started(self):
"""Process is started."""
self.state = ProcessState.STARTED
if self.callbacks.on_started:
self.callbacks.on_started()

def set_alive(self):
"""Basic loading is done."""
self.state = ProcessState.ALIVE
if self.callbacks.on_alive:
self.callbacks.on_alive()

def set_ready(self):
"""All loading is done."""
self.state = ProcessState.READY
if self.callbacks.on_ready:
self.callbacks.on_ready()

def set_stopping(self):
"""Process shutdown has started."""
self.state = ProcessState.STOPPING
if self.callbacks.on_stopping:
self.callbacks.on_stopping()

def set_error(self, err=''):
"""An error has occured and the process is non-functional."""
# Intentionally leave is_started True
self.state = ProcessState.ERROR
if self.callbacks.on_error:
self.callbacks.on_error(err)
2 changes: 1 addition & 1 deletion requirements/minimal.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@ pyee~=8.1
mycroft-messagebus-client~=0.9.1,!=0.9.2,!=0.9.3
psutil~=5.6.6
combo-lock~=0.2
ovos-utils~=0.0.18
ovos-utils~=0.0.20a2
ovos-plugin-manager~=0.0.11a1
2 changes: 1 addition & 1 deletion requirements/requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ python-dateutil~=2.6.0
combo-lock~=0.2
PyYAML~=5.4

ovos-utils~=0.0.18
ovos-utils~=0.0.20a2
ovos-plugin-manager~=0.0.11a1
ovos-tts-plugin-mimic>=0.2.6
ovos-tts-plugin-mimic2>=0.1.4
Expand Down