flash / core /lifecycle.py
NickNYU's picture
upload github well compiled files (#1)
b5d3f34
raw
history blame
5.38 kB
import enum
from abc import ABC, abstractmethod
from typing import TypeVar, Optional
from core import logger_factory
class Initializable(ABC):
@abstractmethod
def initialize(self) -> None:
pass
class Startable(ABC):
@abstractmethod
def start(self) -> None:
pass
class Stoppable(ABC):
@abstractmethod
def stop(self) -> None:
pass
class Disposable(ABC):
@abstractmethod
def dispose(self) -> None:
pass
class LifecycleAware(ABC):
def __init__(self, state: "LifecycleState") -> None:
"""
Args:
state(LifecycleState): lifecycle state
"""
self.state = state
@property
def get_lifecycle_state(self) -> "LifecycleState":
return self.state
class Lifecycle(Initializable, Startable, Stoppable, Disposable, LifecycleAware, ABC):
def __init__(self) -> None:
self.logger = logger_factory.get_logger(self.__class__.__name__)
self.lifecycle_state = LifecycleState(lifecycle=self)
def initialize(self) -> None:
if not self.lifecycle_state.can_initialize(self.lifecycle_state.get_phase()):
self.logger.warning("[{}]cannot initialize".format(self.__class__.__name__))
return
self.lifecycle_state.set_phase(LifecyclePhase.INITIALIZING)
self.do_init()
self.lifecycle_state.set_phase(LifecyclePhase.INITIALIZED)
def start(self) -> None:
if not self.lifecycle_state.can_start(self.lifecycle_state.get_phase()):
self.logger.warning("[{}]cannot start".format(self.__class__.__name__))
return
self.lifecycle_state.set_phase(LifecyclePhase.STARTING)
self.do_start()
self.lifecycle_state.set_phase(LifecyclePhase.STARTED)
def stop(self) -> None:
if not self.lifecycle_state.can_stop(self.lifecycle_state.get_phase()):
self.logger.warning("[{}]cannot stop".format(self.__class__.__name__))
return
self.lifecycle_state.set_phase(LifecyclePhase.STOPPING)
self.do_stop()
self.lifecycle_state.set_phase(LifecyclePhase.STOPPED)
def dispose(self) -> None:
if not self.lifecycle_state.can_dispose(self.lifecycle_state.get_phase()):
self.logger.warning("[{}]cannot dispose".format(self.__class__.__name__))
return
self.lifecycle_state.set_phase(LifecyclePhase.DISPOSING)
self.do_dispose()
self.lifecycle_state.set_phase(LifecyclePhase.DISPOSED)
@abstractmethod
def do_init(self) -> None:
pass
@abstractmethod
def do_start(self) -> None:
pass
@abstractmethod
def do_stop(self) -> None:
pass
@abstractmethod
def do_dispose(self) -> None:
pass
class LifecyclePhase(enum.Enum):
INITIALIZING = 1
INITIALIZED = 2
STARTING = 3
STARTED = 4
STOPPING = 5
STOPPED = 6
DISPOSING = 7
DISPOSED = 8
class LifecycleController(ABC):
def can_initialize(self, phase: Optional[LifecyclePhase]) -> bool:
return phase is None or phase == LifecyclePhase.DISPOSED
def can_start(self, phase: Optional[LifecyclePhase]) -> bool:
return phase is not None and (
phase == LifecyclePhase.INITIALIZED or phase == LifecyclePhase.STOPPED
)
def can_stop(self, phase: Optional[LifecyclePhase]) -> bool:
return phase is not None and phase == LifecyclePhase.STARTED
def can_dispose(self, phase: Optional[LifecyclePhase]) -> bool:
return phase is not None and (
phase == LifecyclePhase.INITIALIZED or phase == LifecyclePhase.STOPPED
)
LS = TypeVar("LS", bound=Lifecycle)
class LifecycleState(LifecycleController, ABC):
phase: Optional[LifecyclePhase]
def __init__(self, lifecycle: LS) -> None:
self.phase = None
self.prev_phase = None
self.lifecycle = lifecycle
self.logger = logger_factory.get_logger(__name__)
def is_initializing(self) -> bool:
return self.phase == LifecyclePhase.INITIALIZING
def is_initialized(self) -> bool:
return self.phase == LifecyclePhase.INITIALIZED
def is_starting(self) -> bool:
return self.phase == LifecyclePhase.STARTING
def is_started(self) -> bool:
return self.phase == LifecyclePhase.STARTED
def is_stopping(self) -> bool:
return self.phase == LifecyclePhase.STOPPING
def is_stopped(self) -> bool:
return self.phase == LifecyclePhase.STOPPED
def is_disposing(self) -> bool:
return self.phase == LifecyclePhase.DISPOSING
def is_disposed(self) -> bool:
return self.phase == LifecyclePhase.DISPOSED
def get_phase(self) -> Optional[LifecyclePhase]:
return self.phase
def set_phase(self, phase: Optional[LifecyclePhase]) -> None:
prev = "None"
if self.phase is not None:
prev = self.phase.name
current = "None"
if phase is not None:
current = phase.name
self.logger.info(
"[setPhaseName][{}]{} --> {}".format(
self.lifecycle.__class__.__name__,
prev,
current,
)
)
self.phase = phase
def rollback(self, err: Exception) -> None:
self.phase = self.prev_phase
self.prev_phase = None