@@ -634,9 +634,8 @@ Transaction::MultiMode DeduceExecMode(ExecScriptUse state,
634
634
// We can only tell if eval is transactional based on they keycount
635
635
if (absl::StartsWith (scmd.Cid ()->name (), " EVAL" )) {
636
636
CmdArgVec arg_vec{};
637
- StoredCmd cmd = scmd;
638
- cmd.Fill (&arg_vec);
639
- auto keys = DetermineKeys (scmd.Cid (), absl::MakeSpan (arg_vec));
637
+ auto args = scmd.ArgList (&arg_vec);
638
+ auto keys = DetermineKeys (scmd.Cid (), args);
640
639
transactional |= (keys && keys.value ().NumArgs () > 0 );
641
640
} else {
642
641
transactional |= scmd.Cid ()->IsTransactional ();
@@ -1200,9 +1199,8 @@ void Service::DispatchCommand(ArgSlice args, SinkReplyBuilder* builder,
1200
1199
bool is_trans_cmd = CO::IsTransKind (cid->name ());
1201
1200
if (dfly_cntx->conn_state .exec_info .IsCollecting () && !is_trans_cmd) {
1202
1201
// TODO: protect against aggregating huge transactions.
1203
- StoredCmd stored_cmd{cid, args_no_cmd};
1204
- dfly_cntx->conn_state .exec_info .body .push_back (std::move (stored_cmd));
1205
- if (stored_cmd.Cid ()->IsWriteOnly ()) {
1202
+ dfly_cntx->conn_state .exec_info .body .emplace_back (cid, true , args_no_cmd);
1203
+ if (cid->IsWriteOnly ()) {
1206
1204
dfly_cntx->conn_state .exec_info .is_write = true ;
1207
1205
}
1208
1206
return builder->SendSimpleString (" QUEUED" );
@@ -1412,11 +1410,14 @@ size_t Service::DispatchManyCommands(absl::Span<CmdArgList> args_list, SinkReply
1412
1410
DCHECK (!dfly_cntx->conn_state .exec_info .IsRunning ());
1413
1411
DCHECK_EQ (builder->GetProtocol (), Protocol::REDIS);
1414
1412
1413
+ auto * ss = dfly::ServerState::tlocal ();
1414
+ // Don't even start when paused. We can only continue if DispatchTracker is aware of us running.
1415
+ if (ss->IsPaused ())
1416
+ return 0 ;
1417
+
1415
1418
vector<StoredCmd> stored_cmds;
1416
1419
intrusive_ptr<Transaction> dist_trans;
1417
-
1418
1420
size_t dispatched = 0 ;
1419
- auto * ss = dfly::ServerState::tlocal ();
1420
1421
1421
1422
auto perform_squash = [&] {
1422
1423
if (stored_cmds.empty ())
@@ -1445,10 +1446,6 @@ size_t Service::DispatchManyCommands(absl::Span<CmdArgList> args_list, SinkReply
1445
1446
stored_cmds.clear ();
1446
1447
};
1447
1448
1448
- // Don't even start when paused. We can only continue if DispatchTracker is aware of us running.
1449
- if (ss->IsPaused ())
1450
- return 0 ;
1451
-
1452
1449
for (auto args : args_list) {
1453
1450
string cmd = absl::AsciiStrToUpper (ArgS (args, 0 ));
1454
1451
const auto [cid, tail_args] = registry_.FindExtended (cmd, args.subspan (1 ));
@@ -1468,7 +1465,7 @@ size_t Service::DispatchManyCommands(absl::Span<CmdArgList> args_list, SinkReply
1468
1465
1469
1466
if (!is_multi && !is_eval && !is_blocking && cid != nullptr ) {
1470
1467
stored_cmds.reserve (args_list.size ());
1471
- stored_cmds.emplace_back (cid, tail_args);
1468
+ stored_cmds.emplace_back (cid, false /* do not deep-copy commands */ , tail_args);
1472
1469
continue ;
1473
1470
}
1474
1471
@@ -2103,19 +2100,18 @@ bool IsWatchingOtherDbs(DbIndex db_indx, const ConnectionState::ExecInfo& exec_i
2103
2100
[db_indx](const auto & pair) { return pair.first != db_indx; });
2104
2101
}
2105
2102
2106
- template <typename F> void IterateAllKeys (ConnectionState::ExecInfo* exec_info, F&& f) {
2103
+ template <typename F> void IterateAllKeys (const ConnectionState::ExecInfo* exec_info, F&& f) {
2107
2104
for (auto & [dbid, key] : exec_info->watched_keys )
2108
2105
f (MutableSlice{key.data (), key.size ()});
2109
2106
2110
2107
CmdArgVec arg_vec{};
2111
2108
2112
- for (auto & scmd : exec_info->body ) {
2109
+ for (const auto & scmd : exec_info->body ) {
2113
2110
if (!scmd.Cid ()->IsTransactional ())
2114
2111
continue ;
2115
2112
2116
- scmd.Fill (&arg_vec);
2117
-
2118
- auto key_res = DetermineKeys (scmd.Cid (), absl::MakeSpan (arg_vec));
2113
+ auto args = scmd.ArgList (&arg_vec);
2114
+ auto key_res = DetermineKeys (scmd.Cid (), args);
2119
2115
if (!key_res.ok ())
2120
2116
continue ;
2121
2117
@@ -2217,15 +2213,12 @@ void Service::Exec(CmdArgList args, const CommandContext& cmd_cntx) {
2217
2213
MultiCommandSquasher::Execute (absl::MakeSpan (exec_info.body ), rb, cntx, this , opts);
2218
2214
} else {
2219
2215
CmdArgVec arg_vec;
2220
- for (auto & scmd : exec_info.body ) {
2216
+ for (const auto & scmd : exec_info.body ) {
2221
2217
VLOG (2 ) << " TX CMD " << scmd.Cid ()->name () << " " << scmd.NumArgs ();
2222
2218
2223
2219
cntx->SwitchTxCmd (scmd.Cid ());
2224
2220
2225
- arg_vec.resize (scmd.NumArgs ());
2226
- scmd.Fill (&arg_vec);
2227
-
2228
- CmdArgList args = absl::MakeSpan (arg_vec);
2221
+ CmdArgList args = scmd.ArgList (&arg_vec);
2229
2222
2230
2223
if (scmd.Cid ()->IsTransactional ()) {
2231
2224
OpStatus st = cmd_cntx.tx ->InitByArgs (cntx->ns , cntx->conn_state .db_index , args);
0 commit comments