@@ -516,9 +516,20 @@ async def execute_command(self, *args, **options):
516516 command_name = args [0 ]
517517 conn = self .connection or await pool .get_connection (command_name , ** options )
518518
519- return await asyncio .shield (
520- self ._try_send_command_parse_response (conn , * args , ** options )
521- )
519+ if self .single_connection_client :
520+ await self ._single_conn_lock .acquire ()
521+ try :
522+ return await conn .retry .call_with_retry (
523+ lambda : self ._send_command_parse_response (
524+ conn , command_name , * args , ** options
525+ ),
526+ lambda error : self ._disconnect_raise (conn , error ),
527+ )
528+ finally :
529+ if self .single_connection_client :
530+ self ._single_conn_lock .release ()
531+ if not self .connection :
532+ await pool .release (conn )
522533
523534 async def parse_response (
524535 self , connection : Connection , command_name : Union [str , bytes ], ** options
@@ -757,18 +768,10 @@ async def _disconnect_raise_connect(self, conn, error):
757768 is not a TimeoutError. Otherwise, try to reconnect
758769 """
759770 await conn .disconnect ()
760-
761771 if not (conn .retry_on_timeout and isinstance (error , TimeoutError )):
762772 raise error
763773 await conn .connect ()
764774
765- async def _try_execute (self , conn , command , * arg , ** kwargs ):
766- try :
767- return await command (* arg , ** kwargs )
768- except asyncio .CancelledError :
769- await conn .disconnect ()
770- raise
771-
772775 async def _execute (self , conn , command , * args , ** kwargs ):
773776 """
774777 Connect manually upon disconnection. If the Redis server is down,
@@ -777,11 +780,9 @@ async def _execute(self, conn, command, *args, **kwargs):
777780 called by the # connection to resubscribe us to any channels and
778781 patterns we were previously listening to
779782 """
780- return await asyncio .shield (
781- conn .retry .call_with_retry (
782- lambda : self ._try_execute (conn , command , * args , ** kwargs ),
783- lambda error : self ._disconnect_raise_connect (conn , error ),
784- )
783+ return await conn .retry .call_with_retry (
784+ lambda : command (* args , ** kwargs ),
785+ lambda error : self ._disconnect_raise_connect (conn , error ),
785786 )
786787
787788 async def parse_response (self , block : bool = True , timeout : float = 0 ):
@@ -799,7 +800,9 @@ async def parse_response(self, block: bool = True, timeout: float = 0):
799800 await conn .connect ()
800801
801802 read_timeout = None if block else timeout
802- response = await self ._execute (conn , conn .read_response , timeout = read_timeout )
803+ response = await self ._execute (
804+ conn , conn .read_response , timeout = read_timeout , disconnect_on_error = False
805+ )
803806
804807 if conn .health_check_interval and response == self .health_check_response :
805808 # ignore the health check message as user might not expect it
@@ -1183,18 +1186,6 @@ async def _disconnect_reset_raise(self, conn, error):
11831186 await self .reset ()
11841187 raise
11851188
1186- async def _try_send_command_parse_response (self , conn , * args , ** options ):
1187- try :
1188- return await conn .retry .call_with_retry (
1189- lambda : self ._send_command_parse_response (
1190- conn , args [0 ], * args , ** options
1191- ),
1192- lambda error : self ._disconnect_reset_raise (conn , error ),
1193- )
1194- except asyncio .CancelledError :
1195- await conn .disconnect ()
1196- raise
1197-
11981189 async def immediate_execute_command (self , * args , ** options ):
11991190 """
12001191 Execute a command immediately, but don't auto-retry on a
@@ -1210,8 +1201,12 @@ async def immediate_execute_command(self, *args, **options):
12101201 command_name , self .shard_hint
12111202 )
12121203 self .connection = conn
1213- return await asyncio .shield (
1214- self ._try_send_command_parse_response (conn , * args , ** options )
1204+
1205+ return await conn .retry .call_with_retry (
1206+ lambda : self ._send_command_parse_response (
1207+ conn , command_name , * args , ** options
1208+ ),
1209+ lambda error : self ._disconnect_reset_raise (conn , error ),
12151210 )
12161211
12171212 def pipeline_execute_command (self , * args , ** options ):
@@ -1379,19 +1374,6 @@ async def _disconnect_raise_reset(self, conn: Connection, error: Exception):
13791374 await self .reset ()
13801375 raise
13811376
1382- async def _try_execute (self , conn , execute , stack , raise_on_error ):
1383- try :
1384- return await conn .retry .call_with_retry (
1385- lambda : execute (conn , stack , raise_on_error ),
1386- lambda error : self ._disconnect_raise_reset (conn , error ),
1387- )
1388- except asyncio .CancelledError :
1389- # not supposed to be possible, yet here we are
1390- await conn .disconnect (nowait = True )
1391- raise
1392- finally :
1393- await self .reset ()
1394-
13951377 async def execute (self , raise_on_error : bool = True ):
13961378 """Execute all the commands in the current pipeline"""
13971379 stack = self .command_stack
@@ -1413,11 +1395,10 @@ async def execute(self, raise_on_error: bool = True):
14131395 conn = cast (Connection , conn )
14141396
14151397 try :
1416- return await asyncio .shield (
1417- self ._try_execute (conn , execute , stack , raise_on_error )
1398+ return await conn .retry .call_with_retry (
1399+ lambda : execute (conn , stack , raise_on_error ),
1400+ lambda error : self ._disconnect_raise_reset (conn , error ),
14181401 )
1419- except RuntimeError :
1420- await self .reset ()
14211402 finally :
14221403 await self .reset ()
14231404
0 commit comments