Module: Valkey::Commands::TransactionCommands
- Included in:
- Valkey::Commands
- Defined in:
- lib/valkey/commands/transaction_commands.rb
Overview
This module contains commands related to transactions.
Constant Summary collapse
- BOOLEAN_REQUEST_TYPES =
Commands whose reply is boolean when run standalone (via native return-type coercion server-side), but arrives as a raw 0/1 integer inside an EXEC array, since that coercion is keyed by the single command actually being run - which, for a queued command, is EXEC itself, not the original command.
This list mirrors glide-core's own Boolean-coercion table in
value_conversion.rs::expected_type_for_cmd(HEXISTS, HSETNX, EXPIRE, EXPIREAT, PEXPIRE, PEXPIREAT, SISMEMBER, PERSIST, SMOVE, PFADD, RENAMENX, MOVE, COPY, MSETNX, XGROUP DESTROY, XGROUP CREATECONSUMER) MINUS the commands whose Ruby method already passes its own explicit conversion block (hexists/hsetnxuse&Utils::Boolify;xgroup_destroy/xgroup_createconsumeruse a custom bool->int block). Those are already handled correctly by theif blockbranch below, before this list is even consulted - listing them here too would be redundant, not wrong. Every RequestType below callssend_commandwith NO block at all, so this static list is the only place their boolean-ness is recorded.NOTE: SETNX is deliberately NOT in glide-core's coercion table (and so isn't here as a "no block" entry either) - it's
redis-rb-style boolean-ness only, not something the server/glide-coretreats as boolean, since coercion there is keyed by command name alone and can't distinguish this dedicated RequestType from a rawcustomCommand(["SETNX", ...])call, which other bindings' existing contracts expect to keep returning a plain integer.setnx's own Ruby method passes&Utils::Boolifydirectly instead - see string_commands.rb - so it's already covered by theif blockbranch, same as hexists/hsetnx. [ RequestType::EXPIRE, RequestType::EXPIRE_AT, RequestType::PEXPIRE, RequestType::PEXPIRE_AT, RequestType::PERSIST, RequestType::SISMEMBER, RequestType::S_MOVE, RequestType::PFADD, RequestType::RENAME_NX, RequestType::MOVE, RequestType::COPY, RequestType::MSET_NX ].freeze
Instance Method Summary collapse
-
#discard ⇒ String
Discard all commands issued after MULTI.
-
#exec ⇒ nil, Array<...>
Execute all commands issued after MULTI.
-
#multi {|multi| ... } ⇒ Array<...>
Mark the start of a transaction block.
-
#unwatch ⇒ String
Forget about all watched keys.
-
#watch(*keys) ⇒ Object, String
Watch the given keys to determine execution of the MULTI/EXEC block.
Instance Method Details
#discard ⇒ String
Discard all commands issued after MULTI.
167 168 169 170 171 172 173 174 175 176 |
# File 'lib/valkey/commands/transaction_commands.rb', line 167 def discard send_command(RequestType::DISCARD) rescue CommandError # DISCARD without MULTI is treated similarly to EXEC without MULTI: # ignore the server error and return nil. nil ensure @in_multi = false @queued_commands = [] end |
#exec ⇒ nil, Array<...>
Execute all commands issued after MULTI.
Only call this method when #multi was called without a block.
132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 |
# File 'lib/valkey/commands/transaction_commands.rb', line 132 def exec if @in_multi queued_commands = @queued_commands begin begin result = send_command(RequestType::EXEC) # If EXEC returns an error object (from array), it's already handled result.is_a?(Array) ? reconvert_queued_replies(result, queued_commands) : result rescue CommandError => e # If EXEC itself raises an error (like when transaction is aborted), # return an array with the error to match expected behavior in tests [e] end ensure @in_multi = false @queued_commands = [] end else # When EXEC is called without a preceding MULTI the server returns an # error. The lint tests allow clients to either raise or return nil; # we normalize this to simply return nil. begin send_command(RequestType::EXEC) rescue CommandError nil end end end |
#multi {|multi| ... } ⇒ Array<...>
Mark the start of a transaction block.
41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
# File 'lib/valkey/commands/transaction_commands.rb', line 41 def multi if block_given? pipeline = Pipeline.new begin yield pipeline return [] if pipeline.commands.empty? results = send_batch_commands(pipeline.commands, exception: true, is_atomic: true) pipeline.resolve_futures!(results) results rescue StandardError pipeline.abort_futures! raise end else start_multi self end end |
#unwatch ⇒ String
Forget about all watched keys.
118 119 120 |
# File 'lib/valkey/commands/transaction_commands.rb', line 118 def unwatch send_command(RequestType::UNWATCH) end |
#watch(*keys) ⇒ Object, String
Watch the given keys to determine execution of the MULTI/EXEC block.
Using a block is optional, but is recommended for automatic cleanup.
An #unwatch is automatically issued if an exception is raised within the
block that is a subclass of StandardError and is not a ConnectionError.
94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 |
# File 'lib/valkey/commands/transaction_commands.rb', line 94 def watch(*keys) keys.flatten!(1) res = send_command(RequestType::WATCH, keys) if block_given? begin yield(self) rescue ConnectionError raise rescue StandardError unwatch raise end else res end end |