unified aioregion logic

This commit is contained in:
Devaev Maxim 2018-07-13 21:57:35 +00:00
parent 73ec9d853e
commit 0a7eafa256
4 changed files with 15 additions and 19 deletions

View File

@ -9,14 +9,15 @@ class RegionIsBusyError(Exception):
class AioExclusiveRegion: class AioExclusiveRegion:
def __init__(self) -> None: def __init__(self, exc_type: Type[RegionIsBusyError]) -> None:
self.__exc_type = exc_type
self.__busy = False self.__busy = False
def enter(self) -> None: def enter(self) -> None:
if not self.__busy: if not self.__busy:
self.__busy = True self.__busy = True
return return
raise RegionIsBusyError() raise self.__exc_type()
def exit(self) -> None: def exit(self) -> None:
self.__busy = False self.__busy = False

View File

@ -9,6 +9,11 @@ from . import gpio
# ===== # =====
class AtxIsBusy(aioregion.RegionIsBusyError):
def __init__(self) -> None:
super().__init__("Performing another operation, please try again later")
class Atx: class Atx:
def __init__( def __init__(
self, self,
@ -29,7 +34,7 @@ class Atx:
self.__click_delay = click_delay self.__click_delay = click_delay
self.__long_click_delay = long_click_delay self.__long_click_delay = long_click_delay
self.__region = aioregion.AioExclusiveRegion() self.__region = aioregion.AioExclusiveRegion(AtxIsBusy)
def get_state(self) -> Dict: def get_state(self) -> Dict:
return { return {

View File

@ -49,7 +49,7 @@ class IsNotConnectedToKvmError(MassStorageOperationError):
super().__init__("Mass-storage is not connected to KVM") super().__init__("Mass-storage is not connected to KVM")
class IsBusyError(MassStorageOperationError): class IsBusyError(MassStorageOperationError, aioregion.RegionIsBusyError):
def __init__(self) -> None: def __init__(self) -> None:
super().__init__("Mass-storage is busy (write in progress)") super().__init__("Mass-storage is busy (write in progress)")
@ -155,8 +155,6 @@ def _explore_device(device_path: str) -> Optional[_MassStorageDeviceInfo]:
def _msd_operated(method: Callable) -> Callable: def _msd_operated(method: Callable) -> Callable:
async def wrap(self: "MassStorageDevice", *args: Any, **kwargs: Any) -> Any: async def wrap(self: "MassStorageDevice", *args: Any, **kwargs: Any) -> Any:
if self._device_file: # pylint: disable=protected-access
raise IsBusyError()
if not self._device_path: # pylint: disable=protected-access if not self._device_path: # pylint: disable=protected-access
IsNotOperationalError() IsNotOperationalError()
return (await method(self, *args, **kwargs)) return (await method(self, *args, **kwargs))
@ -179,7 +177,7 @@ class MassStorageDevice: # pylint: disable=too-many-instance-attributes
self.__loop = loop self.__loop = loop
self.__device_info: Optional[_MassStorageDeviceInfo] = None self.__device_info: Optional[_MassStorageDeviceInfo] = None
self.__region = aioregion.AioExclusiveRegion() self.__region = aioregion.AioExclusiveRegion(IsBusyError)
self._device_file: Optional[aiofiles.base.AiofilesContextManager] = None self._device_file: Optional[aiofiles.base.AiofilesContextManager] = None
self.__written = 0 self.__written = 0
@ -238,11 +236,11 @@ class MassStorageDevice: # pylint: disable=too-many-instance-attributes
@_msd_operated @_msd_operated
async def __aenter__(self) -> "MassStorageDevice": async def __aenter__(self) -> "MassStorageDevice":
self.__region.enter()
if not self.__device_info: if not self.__device_info:
raise IsNotConnectedToKvmError() raise IsNotConnectedToKvmError()
self._device_file = await aiofiles.open(self.__device_info.path, mode="w+b", buffering=0) self._device_file = await aiofiles.open(self.__device_info.path, mode="w+b", buffering=0)
self.__written = 0 self.__written = 0
self.__region.enter()
return self return self
async def write_image_info(self, name: str, complete: bool) -> None: async def write_image_info(self, name: str, complete: bool) -> None:

View File

@ -58,23 +58,15 @@ class BadRequest(Exception):
pass pass
class PerformingAnotherOperation(Exception):
def __init__(self) -> None:
super().__init__("Performing another operation, please try again later")
def _wrap_exceptions_for_web(msg: str) -> Callable: def _wrap_exceptions_for_web(msg: str) -> Callable:
def make_wrapper(method: Callable) -> Callable: def make_wrapper(method: Callable) -> Callable:
async def wrap(self: "Server", request: aiohttp.web.Request) -> aiohttp.web.Response: async def wrap(self: "Server", request: aiohttp.web.Request) -> aiohttp.web.Response:
try: try:
try: return (await method(self, request))
return (await method(self, request)) except RegionIsBusyError as err:
except RegionIsBusyError: return _json_exception(msg, err, 409)
raise PerformingAnotherOperation()
except (BadRequest, MassStorageOperationError) as err: except (BadRequest, MassStorageOperationError) as err:
return _json_exception(msg, err, 400) return _json_exception(msg, err, 400)
except PerformingAnotherOperation as err:
return _json_exception(msg, err, 409)
return wrap return wrap
return make_wrapper return make_wrapper