@@ -208,18 +208,9 @@ public final class ValkeyClusterClient: Sendable {
208208 public func execute< each Command : ValkeyCommand > (
209209 _ commands: repeat each Command
210210 ) async -> sending ( repeat Result < ( each Command ) . Response, any Error > ) {
211- func convert< Response: RESPTokenDecodable > ( _ result: Result < RESPToken , any Error > , to: Response . Type ) -> Result < Response , any Error > {
212- result. flatMap {
213- do {
214- return try . success( Response ( fromRESP: $0) )
215- } catch {
216- return . failure( error)
217- }
218- }
219- }
220211 let results = await self . execute ( [ any ValkeyCommand ] ( commands: repeat each commands) )
221212 var index = AutoIncrementingInteger ( )
222- return ( repeat convert ( results [ index. next ( ) ] , to: ( each Command) . Response. self) )
213+ return ( repeat results[ index. next ( ) ] . convertFromRESP ( to: ( each Command) . Response. self) )
223214 }
224215
225216 /// Results from pipeline and index for each result
@@ -312,7 +303,32 @@ public final class ValkeyClusterClient: Sendable {
312303 /// of the EXEC command is transformed into an array of RESPToken Results, one for
313304 /// each command.
314305 ///
315- /// This is an alternative version of the transaction function ``ValkeyConnection/transaction(_:)->(_,_)``
306+ /// Transactions come only affect keys coming from the same HashSlot.
307+ ///
308+ /// - Parameter commands: Parameter pack of ValkeyCommands
309+ /// - Returns: Parameter pack holding the responses of all the commands
310+ /// - Throws: ValkeyTransactionError when EXEC aborts
311+ @inlinable
312+ public func transaction< each Command : ValkeyCommand > (
313+ _ commands: repeat each Command
314+ ) async throws -> sending ( repeat Result < ( each Command ) . Response, any Error > ) {
315+ let results = try await self . transaction ( [ any ValkeyCommand ] ( commands: repeat each commands) )
316+ var index = AutoIncrementingInteger ( )
317+ return ( repeat results[ index. next ( ) ] . convertFromRESP ( to: ( each Command) . Response. self) )
318+ }
319+
320+ /// Pipeline a series of commands as a transaction to Valkey connection
321+ ///
322+ /// Another client will never be served in the middle of the execution of these
323+ /// commands. See https://valkey.io/topics/transactions/ for more information.
324+ ///
325+ /// EXEC and MULTI commands are added to the pipelined commands and the output
326+ /// of the EXEC command is transformed into an array of RESPToken Results, one for
327+ /// each command.
328+ ///
329+ /// Transactions come only affect keys coming from the same HashSlot.
330+ ///
331+ /// This is an alternative version of the transaction function ``ValkeyCluster/transaction(_:)->(_,_)``
316332 /// that allows for a collection of ValkeyCommands. It provides more flexibility but the command
317333 /// responses are returned as ``RESPToken`` instead of the response type for the command.
318334 ///
@@ -627,6 +643,7 @@ public final class ValkeyClusterClient: Sendable {
627643 case let transactionError as ValkeyTransactionError :
628644 switch transactionError {
629645 case . transactionErrors( let results, let execError) :
646+ // check whether queued results include any errors that warrent a retry
630647 for result in results {
631648 if case . failure( let queuedError) = result {
632649 let queuedAction = self . getRetryAction ( from: queuedError)
@@ -635,6 +652,7 @@ public final class ValkeyClusterClient: Sendable {
635652 }
636653 }
637654 }
655+ // check whether EXEC error warrents a retry
638656 let execAction = self . getRetryAction ( from: execError)
639657 guard case . dontRetry = execAction else {
640658 return execAction
0 commit comments