1+ #include < atomic>
2+ #include < future>
3+ #include < mutex>
14#include < thread>
25
36#include " kv_cache_manager/common/redis_client.h"
@@ -319,7 +322,20 @@ TEST_F(MetaRedisBackendTest, TestRedisError) {
319322}
320323
321324TEST_F (MetaRedisBackendTest, TestMultiThreadSimple) {
322- auto make_mock_client = []() {
325+ std::atomic<int > client_index{0 };
326+ std::once_flag first_pipeline_call;
327+ std::promise<void > first_client_entered_promise;
328+ auto first_client_entered = first_client_entered_promise.get_future ();
329+ std::promise<void > release_first_client_promise;
330+ auto release_first_client = release_first_client_promise.get_future ().share ();
331+ std::promise<void > second_client_created_promise;
332+ auto second_client_created = second_client_created_promise.get_future ();
333+
334+ auto make_mock_client = [&]() {
335+ const int current_client_index = client_index.fetch_add (1 );
336+ if (current_client_index == 1 ) {
337+ second_client_created_promise.set_value ();
338+ }
323339 StandardUri empty_storage_uri;
324340 auto mock_redis_client = std::make_unique<MockRedisClient>(empty_storage_uri);
325341 EXPECT_CALL (*mock_redis_client, Reconnect ()).WillRepeatedly (Return (true ));
@@ -329,8 +345,11 @@ TEST_F(MetaRedisBackendTest, TestMultiThreadSimple) {
329345 TryExecPipeline (ElementsAre (
330346 ElementsAre (StrEq (" HMGET" ), StrEq (" kvcache:instance_instance_0:cache_1" ), StrEq (" f1" ), StrEq (" f2" )),
331347 ElementsAre (StrEq (" HMGET" ), StrEq (" kvcache:instance_instance_0:cache_2" ), StrEq (" f1" ), StrEq (" f2" )))))
332- .WillRepeatedly (Invoke ([]() {
333- usleep (5 * 1000 ); // assume network use 5ms
348+ .WillRepeatedly (Invoke ([&, current_client_index]() {
349+ if (current_client_index == 0 ) {
350+ std::call_once (first_pipeline_call, [&] { first_client_entered_promise.set_value (); });
351+ release_first_client.wait ();
352+ }
334353 std::vector<ReplyUPtr> get_replies_2;
335354 get_replies_2.emplace_back (MakeFakeReplyArrayString ({" v1-1" , " v1-2" }));
336355 get_replies_2.emplace_back (MakeFakeReplyArrayString ({" v2-1" , " v2-2" }));
@@ -353,14 +372,24 @@ TEST_F(MetaRedisBackendTest, TestMultiThreadSimple) {
353372 {EC_OK , EC_OK },
354373 {{{" f1" , " v1-1" }, {" f2" , " v1-2" }}, {{" f1" , " v2-1" }, {" f2" , " v2-2" }}});
355374 };
356- std::vector<std::thread> threads;
357- for (int i = 0 ; i < 10 ; ++i) {
358- threads.emplace_back (get_task);
359- usleep (2 * 1000 );
375+ std::thread first_thread (get_task);
376+ const auto first_entered_status = first_client_entered.wait_for (std::chrono::seconds (1 ));
377+
378+ std::thread second_thread;
379+ std::future_status second_created_status = std::future_status::timeout;
380+ if (first_entered_status == std::future_status::ready) {
381+ second_thread = std::thread (get_task);
382+ second_created_status = second_client_created.wait_for (std::chrono::seconds (1 ));
360383 }
361- for (auto &thread : threads) {
362- thread.join ();
384+
385+ release_first_client_promise.set_value ();
386+ first_thread.join ();
387+ if (second_thread.joinable ()) {
388+ second_thread.join ();
363389 }
390+
391+ ASSERT_EQ (std::future_status::ready, first_entered_status);
392+ ASSERT_EQ (std::future_status::ready, second_created_status);
364393 ASSERT_EQ (EC_OK , meta_redis_backend_->Close ());
365394}
366395
0 commit comments