2017-04-28 09:16:10 +02:00

51 lines
1.7 KiB
Python

import asyncio
import functools
import json
import os
from uuid import uuid4
DEFAULT_JSON_SETTINGS = {
"indent": 4,
"sort_keys": True,
"separators": (',', ' : ')
}
class JSONAutosave:
def __init__(self, interval=5, **settings):
self.interval = interval
self._queue = {}
self._lock = asyncio.Lock()
self._json_settings = settings.pop("json_settings",
DEFAULT_JSON_SETTINGS)
self.loop = asyncio.get_event_loop()
self.task = self.loop.create_task(self._process_queue())
def add_to_queue(self, path, data):
self._queue[path] = data
async def _process_queue(self):
try:
while True:
print("looping")
queue = self._queue.copy()
self._queue = {}
for path, data in queue.items():
with await self._lock:
func = functools.partial(self._save_json, path, data)
try:
await self.loop.run_in_executor(None, func)
except Exception as e:
print(e) # Proper logging here
await asyncio.sleep(self.interval)
except asyncio.CancelledError:
pass
def _save_json(self, path, data):
print("Saving " + path)
path, _ = os.path.splitext(path)
tmp_file = "{}-{}.tmp".format(path, uuid4().fields[0])
with open(tmp_file, encoding="utf-8", mode="w") as f:
json.dump(data, f, **self._json_settings)
os.replace(tmp_file, path)