Skip to content

Commit ce3d88d

Browse files
authored
feat: Make CacheData serializable (#613)
* feat: Make CacheData serializable Update the CacheData class with serialization methods so that clients can use it for persistence. This provides an API for Home Assistant to use for serialization so it doesn't need to make its own. * fix: set default arugments to store/load value functions * chore: remove unncessary logging * chore: remove unnecessary snapshot files * chore: remove unused import
1 parent b48121f commit ce3d88d

File tree

4 files changed

+93
-14
lines changed

4 files changed

+93
-14
lines changed

roborock/devices/cache.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,12 @@
88
from dataclasses import dataclass, field
99
from typing import Any, Protocol
1010

11-
from roborock.data import CombinedMapInfo, HomeData, NetworkInfo
11+
from roborock.data import CombinedMapInfo, HomeData, NetworkInfo, RoborockBase
1212
from roborock.device_features import DeviceFeatures
1313

1414

1515
@dataclass
16-
class CacheData:
16+
class CacheData(RoborockBase):
1717
"""Data structure for caching device information."""
1818

1919
home_data: HomeData | None = None

roborock/devices/file_cache.py

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,18 +17,25 @@
1717
class FileCache(Cache):
1818
"""File backed cache implementation."""
1919

20-
def __init__(self, file_path: pathlib.Path, init_fn: Callable[[], CacheData] = CacheData) -> None:
20+
def __init__(
21+
self,
22+
file_path: pathlib.Path,
23+
init_fn: Callable[[], CacheData] = CacheData,
24+
serialize_fn: Callable[[Any], bytes] = pickle.dumps,
25+
deserialize_fn: Callable[[bytes], Any] = pickle.loads,
26+
) -> None:
2127
"""Initialize the file cache with the given file path."""
2228
self._init_fn = init_fn
2329
self._file_path = file_path
2430
self._cache_data: CacheData | None = None
31+
self._serialize_fn = serialize_fn
32+
self._deserialize_fn = deserialize_fn
2533

2634
async def get(self) -> CacheData:
2735
"""Get cached value."""
2836
if self._cache_data is not None:
2937
return self._cache_data
30-
31-
data = await load_value(self._file_path)
38+
data = await load_value(self._file_path, self._deserialize_fn)
3239
if data is not None and not isinstance(data, CacheData):
3340
raise TypeError(f"Invalid cache data loaded from {self._file_path}")
3441

@@ -43,28 +50,28 @@ async def flush(self) -> None:
4350
"""Flush the cache to disk."""
4451
if self._cache_data is None:
4552
return
46-
await store_value(self._file_path, self._cache_data)
53+
await store_value(self._file_path, self._cache_data, self._serialize_fn)
4754

4855

49-
async def store_value(file_path: pathlib.Path, value: Any) -> None:
56+
async def store_value(file_path: pathlib.Path, value: Any, serialize_fn: Callable[[Any], bytes] = pickle.dumps) -> None:
5057
"""Store a value to the given file path."""
5158

5259
def _store_to_disk(file_path: pathlib.Path, value: Any) -> None:
5360
with open(file_path, "wb") as f:
54-
data = pickle.dumps(value)
61+
data = serialize_fn(value)
5562
f.write(data)
5663

5764
await asyncio.to_thread(_store_to_disk, file_path, value)
5865

5966

60-
async def load_value(file_path: pathlib.Path) -> Any | None:
67+
async def load_value(file_path: pathlib.Path, deserialize_fn: Callable[[bytes], Any] = pickle.loads) -> Any | None:
6168
"""Load a value from the given file path."""
6269

6370
def _load_from_disk(file_path: pathlib.Path) -> Any | None:
6471
if not file_path.exists():
6572
return None
6673
with open(file_path, "rb") as f:
6774
data = f.read()
68-
return pickle.loads(data)
75+
return deserialize_fn(data)
6976

7077
return await asyncio.to_thread(_load_from_disk, file_path)

0 commit comments

Comments
 (0)