diff --git a/src/server/main_service.cc b/src/server/main_service.cc index c5664d1a2..6fa009ef0 100644 --- a/src/server/main_service.cc +++ b/src/server/main_service.cc @@ -1426,15 +1426,14 @@ size_t Service::DispatchManyCommands(absl::Span args_list, SinkReply // MULTI...EXEC commands need to be collected into a single context, so squashing is not // possible - const bool is_multi = - dfly_cntx->conn_state.exec_info.IsCollecting() || CO::IsTransKind(ArgS(args, 0)); + const bool is_multi = dfly_cntx->conn_state.exec_info.IsCollecting() || CO::IsTransKind(cmd); // Generally, executing any multi-transactions (including eval) is not possible because they // might request a stricter multi mode than non-atomic which is used for squashing. // TODO: By allowing promoting non-atomic multit transactions to lock-ahead for specific command // invocations, we can potentially execute multiple eval in parallel, which is very powerful // paired with shardlocal eval - const bool is_eval = CO::IsEvalKind(ArgS(args, 0)); + const bool is_eval = CO::IsEvalKind(cmd); const bool is_blocking = cid != nullptr && cid->IsBlocking(); diff --git a/tests/dragonfly/connection_test.py b/tests/dragonfly/connection_test.py index 1c3cc89ef..a59c4a39c 100755 --- a/tests/dragonfly/connection_test.py +++ b/tests/dragonfly/connection_test.py @@ -783,6 +783,16 @@ async def test_tls_reject( await client.ping() +@dfly_args({"proactor_threads": "4", "pipeline_squash": 1}) +async def test_squashed_pipeline_eval(async_client: aioredis.Redis): + p = async_client.pipeline(transaction=False) + for _ in range(5): + # Deliberately lowcase EVAL to test that it is not squashed + p.execute_command("eval", "return redis.call('set', KEYS[1], 'value')", 1, "key") + res = await p.execute() + assert res == ["OK"] * 5 + + @dfly_args({"proactor_threads": "4", "pipeline_squash": 10}) async def test_squashed_pipeline(async_client: aioredis.Redis): p = async_client.pipeline(transaction=False)