Rate-limit config files writing

This commit is contained in:
miruka 2019-12-10 17:59:04 -04:00
parent 3c4c92dbc0
commit d56b590edc

View File

@ -3,7 +3,7 @@ import json
import logging as log import logging as log
from dataclasses import dataclass, field from dataclasses import dataclass, field
from pathlib import Path from pathlib import Path
from typing import Any, Dict from typing import Any, Dict, Optional
import aiofiles import aiofiles
@ -21,6 +21,13 @@ class ConfigFile:
backend: Backend = field(repr=False) backend: Backend = field(repr=False)
filename: str = field() filename: str = field()
_to_write: Optional[str] = field(init=False, default=None)
def __post_init__(self) -> None:
asyncio.ensure_future(self._write_loop())
@property @property
def path(self) -> Path: def path(self) -> Path:
return Path(self.backend.app.appdirs.user_config_dir) / self.filename return Path(self.backend.app.appdirs.user_config_dir) / self.filename
@ -36,11 +43,20 @@ class ConfigFile:
async def write(self, data) -> None: async def write(self, data) -> None:
async with WRITE_LOCK: self._to_write = data
self.path.parent.mkdir(parents=True, exist_ok=True)
async with aiofiles.open(self.path, "w") as new:
await new.write(data) async def _write_loop(self) -> None:
self.path.parent.mkdir(parents=True, exist_ok=True)
while True:
if self._to_write is not None:
async with aiofiles.open(self.path, "w") as new:
await new.write(self._to_write)
self._to_write = None
await asyncio.sleep(1)
@dataclass @dataclass
@ -73,6 +89,7 @@ class JSONConfigFile(ConfigFile):
class Accounts(JSONConfigFile): class Accounts(JSONConfigFile):
filename: str = "accounts.json" filename: str = "accounts.json"
async def any_saved(self) -> bool: async def any_saved(self) -> bool:
return bool(await self.read()) return bool(await self.read())
@ -101,6 +118,7 @@ class Accounts(JSONConfigFile):
class UISettings(JSONConfigFile): class UISettings(JSONConfigFile):
filename: str = "settings.json" filename: str = "settings.json"
async def default_data(self) -> JsonData: async def default_data(self) -> JsonData:
return { return {
"alertOnMessageForMsec": 4000, "alertOnMessageForMsec": 4000,
@ -159,6 +177,7 @@ class UISettings(JSONConfigFile):
class UIState(JSONConfigFile): class UIState(JSONConfigFile):
filename: str = "state.json" filename: str = "state.json"
@property @property
def path(self) -> Path: def path(self) -> Path:
return Path(self.backend.app.appdirs.user_data_dir) / self.filename return Path(self.backend.app.appdirs.user_data_dir) / self.filename
@ -176,6 +195,7 @@ class UIState(JSONConfigFile):
class History(JSONConfigFile): class History(JSONConfigFile):
filename: str = "history.json" filename: str = "history.json"
@property @property
def path(self) -> Path: def path(self) -> Path:
return Path(self.backend.app.appdirs.user_data_dir) / self.filename return Path(self.backend.app.appdirs.user_data_dir) / self.filename