44from logging import getLogger
55from typing import TYPE_CHECKING , Any
66
7+ from redis .exceptions import RedisError
78from typing_extensions import override
89
910from crawlee ._utils .file import infer_mime_type
11+ from crawlee ._utils .retry import retry_on_error
1012from crawlee .storage_clients ._base import KeyValueStoreClient
1113from crawlee .storage_clients .models import KeyValueStoreMetadata , KeyValueStoreRecord , KeyValueStoreRecordMetadata
1214
@@ -100,21 +102,25 @@ async def open(
100102 instance_kwargs = {},
101103 )
102104
105+ @retry_on_error (RedisError )
103106 @override
104107 async def get_metadata (self ) -> KeyValueStoreMetadata :
105108 return await self ._get_metadata (KeyValueStoreMetadata )
106109
110+ @retry_on_error (RedisError )
107111 @override
108112 async def drop (self ) -> None :
109113 await self ._drop (extra_keys = [self ._items_key , self ._metadata_items_key ])
110114
115+ @retry_on_error (RedisError )
111116 @override
112117 async def purge (self ) -> None :
113118 await self ._purge (
114119 extra_keys = [self ._items_key , self ._metadata_items_key ],
115120 metadata_kwargs = MetadataUpdateParams (update_accessed_at = True , update_modified_at = True ),
116121 )
117122
123+ @retry_on_error (RedisError )
118124 @override
119125 async def set_value (self , * , key : str , value : Any , content_type : str | None = None ) -> None :
120126 # Special handling for None values
@@ -141,7 +147,6 @@ async def set_value(self, *, key: str, value: Any, content_type: str | None = No
141147 content_type = content_type ,
142148 size = size ,
143149 )
144-
145150 async with self ._get_pipeline () as pipe :
146151 # redis-py typing issue
147152 await await_redis_response (pipe .hset (self ._items_key , key , value_bytes )) # ty: ignore[invalid-argument-type]
@@ -155,6 +160,7 @@ async def set_value(self, *, key: str, value: Any, content_type: str | None = No
155160 )
156161 await self ._update_metadata (pipe , ** MetadataUpdateParams (update_accessed_at = True , update_modified_at = True ))
157162
163+ @retry_on_error (RedisError )
158164 @override
159165 async def get_value (self , * , key : str ) -> KeyValueStoreRecord | None :
160166 serialized_metadata_item = await await_redis_response (self ._redis .hget (self ._metadata_items_key , key ))
@@ -200,6 +206,7 @@ async def get_value(self, *, key: str) -> KeyValueStoreRecord | None:
200206
201207 return KeyValueStoreRecord (value = value , ** metadata_item .model_dump ())
202208
209+ @retry_on_error (RedisError )
203210 @override
204211 async def delete_value (self , * , key : str ) -> None :
205212 async with self ._get_pipeline () as pipe :
@@ -251,6 +258,7 @@ async def iterate_keys(
251258 async def get_public_url (self , * , key : str ) -> str :
252259 raise NotImplementedError ('Public URLs are not supported for memory key-value stores.' )
253260
261+ @retry_on_error (RedisError )
254262 @override
255263 async def record_exists (self , * , key : str ) -> bool :
256264 async with self ._get_pipeline (with_execute = False ) as pipe :
0 commit comments