44
55from asyncio import get_running_loop
66from contextlib import suppress
7+ from secrets import token_hex as secrets_token_hex
78import logging
8- from os import getenv as os_getenv , getpid as os_getpid , name as os_name
9+ from os import fsync as os_fsync , getenv as os_getenv , getpid as os_getpid , name as os_name
910from os .path import expanduser as os_path_expand_user , join as os_path_join
1011from pathlib import Path
1112
@@ -56,7 +57,7 @@ async def initialize_cache(self, create_root_folder: bool = False) -> None:
5657 if self ._root_dir != "" :
5758 if not create_root_folder and not await ospath .exists (self ._root_dir ):
5859 raise CacheError (
59- f"Unable to initialize caching. Cache folder '{ self ._root_dir } ' does not exists ."
60+ f"Unable to initialize caching. Cache folder '{ self ._root_dir } ' does not exist ."
6061 )
6162 cache_dir = self ._root_dir
6263 else :
@@ -114,7 +115,7 @@ async def write_cache(self, data: dict[str, str], rewrite: bool = False) -> None
114115
115116 cache_file_path = Path (self ._cache_file )
116117 temp_path = cache_file_path .with_name (
117- f".{ cache_file_path .name } .tmp.{ os_getpid ()} "
118+ f".{ cache_file_path .name } .tmp.{ os_getpid ()} . { secrets_token_hex ( 8 ) } "
118119 )
119120
120121 try :
@@ -126,11 +127,11 @@ async def write_cache(self, data: dict[str, str], rewrite: bool = False) -> None
126127 ) as temp_file :
127128 await temp_file .writelines (data_to_write )
128129 await temp_file .flush ()
130+ # Ensure data reaches disk before rename
131+ loop = get_running_loop ()
132+ await loop .run_in_executor (None , os_fsync , temp_file .fileno ())
129133
130- # Atomic rename
131- if os_name == "nt" and cache_file_path .exists ():
132- cache_file_path .unlink ()
133-
134+ # Atomic rename (overwrites atomically on all platforms)
134135 temp_path .replace (cache_file_path )
135136 temp_path = None # Successfully renamed
136137
@@ -139,7 +140,7 @@ async def write_cache(self, data: dict[str, str], rewrite: bool = False) -> None
139140
140141 _LOGGER .debug (
141142 "Saved %s lines to cache file %s (aiofiles atomic write)" ,
142- str ( len (data ) ),
143+ len (data_to_write ),
143144 self ._cache_file ,
144145 )
145146
@@ -168,7 +169,7 @@ async def read_cache(self) -> dict[str, str]:
168169
169170 if not self ._cache_file_exists :
170171 _LOGGER .debug (
171- "Cache file '%s' does not exists , return empty cache data" ,
172+ "Cache file '%s' does not exist , return empty cache data" ,
172173 self ._cache_file ,
173174 )
174175 return current_data
@@ -195,7 +196,8 @@ async def read_cache(self) -> dict[str, str]:
195196 data ,
196197 str (self ._cache_file ),
197198 )
198- break
199+ continue
200+
199201 current_data [data [:index_separator ]] = data [index_separator + 1 :]
200202
201203 return current_data
0 commit comments