From ea673153c9ab316a2bcc42c97ace14aa66222e75 Mon Sep 17 00:00:00 2001 From: zqq Date: Tue, 11 Oct 2022 14:59:56 +0800 Subject: [PATCH] 1.begin notify before get machine lock 2.send notify packet before get machine lock Signed-off-by: zqq --- .../src/single_ver_sync_state_machine.cpp | 8 +-- .../syncer/src/sync_state_machine.cpp | 19 +++---- ...buteddb_single_ver_p2p_sync_check_test.cpp | 53 +++++++++++++++++++ 3 files changed, 67 insertions(+), 13 deletions(-) diff --git a/frameworks/libs/distributeddb/syncer/src/single_ver_sync_state_machine.cpp b/frameworks/libs/distributeddb/syncer/src/single_ver_sync_state_machine.cpp index 1ad51ce9f52..3c19347ed3a 100644 --- a/frameworks/libs/distributeddb/syncer/src/single_ver_sync_state_machine.cpp +++ b/frameworks/libs/distributeddb/syncer/src/single_ver_sync_state_machine.cpp @@ -645,16 +645,16 @@ int SingleVerSyncStateMachine::HandleDataRequestRecv(const Message *inMsg) performance->StepTimeRecordStart(PT_TEST_RECORDS::RECORD_DATA_REQUEST_RECV_TO_SEND_ACK); } DecRefCountOfFeedDogTimer(SyncDirectionFlag::RECEIVE); + + // RequestRecv will save data, it may cost a long time. + // So we need to send save data notify to keep remote alive. + bool isNeedStop = StartSaveDataNotify(inMsg->GetSessionId(), inMsg->GetSequenceId(), inMsg->GetMessageId()); { std::lock_guard lockWatchDog(stateMachineLock_); if (IsNeedResetWatchdog(inMsg)) { (void)ResetWatchDog(); } } - - // RequestRecv will save data, it may cost a long time. - // So we need to send save data notify to keep remote alive. - bool isNeedStop = StartSaveDataNotify(inMsg->GetSessionId(), inMsg->GetSequenceId(), inMsg->GetMessageId()); WaterMark pullEndWaterkark = 0; errCode = dataSync_->DataRequestRecv(context_, inMsg, pullEndWaterkark); if (performance != nullptr) { diff --git a/frameworks/libs/distributeddb/syncer/src/sync_state_machine.cpp b/frameworks/libs/distributeddb/syncer/src/sync_state_machine.cpp index a8d1a649d74..52e8da2e2bf 100644 --- a/frameworks/libs/distributeddb/syncer/src/sync_state_machine.cpp +++ b/frameworks/libs/distributeddb/syncer/src/sync_state_machine.cpp @@ -375,17 +375,18 @@ void SyncStateMachine::DecRefCountOfFeedDogTimer(SyncDirectionFlag flag) void SyncStateMachine::DoSaveDataNotify(uint32_t sessionId, uint32_t sequenceId, uint32_t inMsgId) { + // we send notify packet at first, because it will cost a lot of time to get machine lock { - std::lock_guard lock(stateMachineLock_); - (void)ResetWatchDog(); - } - std::lock_guard innerLock(saveDataNotifyLock_); - if (saveDataNotifyCount_ >= MAX_DATA_NOTIFY_COUNT) { - StopSaveDataNotifyNoLock(); - return; + std::lock_guard innerLock(saveDataNotifyLock_); + if (saveDataNotifyCount_ >= MAX_DATA_NOTIFY_COUNT) { + StopSaveDataNotifyNoLock(); + return; + } + SendNotifyPacket(sessionId, sequenceId, inMsgId); + saveDataNotifyCount_++; } - SendNotifyPacket(sessionId, sequenceId, inMsgId); - saveDataNotifyCount_++; + std::lock_guard lock(stateMachineLock_); + (void)ResetWatchDog(); } void SyncStateMachine::DoFeedDogForSync(SyncDirectionFlag flag) diff --git a/frameworks/libs/distributeddb/test/unittest/common/syncer/distributeddb_single_ver_p2p_sync_check_test.cpp b/frameworks/libs/distributeddb/test/unittest/common/syncer/distributeddb_single_ver_p2p_sync_check_test.cpp index 44a5353779d..e5ef87fbea8 100644 --- a/frameworks/libs/distributeddb/test/unittest/common/syncer/distributeddb_single_ver_p2p_sync_check_test.cpp +++ b/frameworks/libs/distributeddb/test/unittest/common/syncer/distributeddb_single_ver_p2p_sync_check_test.cpp @@ -40,6 +40,7 @@ namespace { const int SLEEP_MILLISECONDS = 500; const int TEN_SECONDS = 10; const int THREE_HUNDRED = 300; + const int WAIT_10_SECONDS = 10000; const int WAIT_30_SECONDS = 30000; const int WAIT_40_SECONDS = 40000; @@ -1372,4 +1373,56 @@ HWTEST_F(DistributedDBSingleVerP2PSyncCheckTest, GetDataNotify001, TestSize.Leve EXPECT_EQ(virtualRes.size(), devices.size()); EXPECT_EQ(virtualRes[DEVICE_A], static_cast(SyncOperation::OP_FINISHED_ALL)); g_deviceB->DelayGetSyncData(0); +} + +/** + * @tc.name: GetDataNotify002 + * @tc.desc: Test GetDataNotify function, two device sync each other at same time + * @tc.type: FUNC + * @tc.require: AR000D4876 + * @tc.author: zhangqiquan + */ +HWTEST_F(DistributedDBSingleVerP2PSyncCheckTest, GetDataNotify002, TestSize.Level3) +{ + ASSERT_NE(g_kvDelegatePtr, nullptr); + DBStatus status = OK; + std::vector devices; + devices.push_back(g_deviceB->GetDeviceId()); + const std::string DEVICE_A = "real_device"; + + /** + * @tc.steps: step1. deviceA sync first to finish time sync and ability sync + */ + std::map result; + status = g_tool.SyncTest(g_kvDelegatePtr, devices, SYNC_MODE_PUSH_ONLY, result, true); + EXPECT_EQ(status, OK); + EXPECT_EQ(result.size(), devices.size()); + EXPECT_EQ(result[DEVICE_B], OK); + /** + * @tc.steps: step2. deviceB set get data delay 10s + */ + g_deviceB->DelayGetSyncData(WAIT_10_SECONDS); + + /** + * @tc.steps: step3. deviceB call sync and wait + */ + std::thread asyncThread([]() { + std::map virtualRes; + Query query = Query::Select(); + g_deviceB->Sync(SYNC_MODE_PUSH_ONLY, query, [&virtualRes](std::map resMap) { + virtualRes = std::move(resMap); + }, true); + }); + + /** + * @tc.steps: step4. deviceA call sync and wait + * @tc.expected: step4. sync should return OK. because notify timer trigger (10s - 1s)/2s => 4times + */ + std::this_thread::sleep_for(std::chrono::seconds(1)); + status = g_tool.SyncTest(g_kvDelegatePtr, devices, SYNC_MODE_PUSH_ONLY, result, true); + EXPECT_EQ(status, OK); + EXPECT_EQ(result.size(), devices.size()); + EXPECT_EQ(result[DEVICE_B], OK); + asyncThread.join(); + std::this_thread::sleep_for(std::chrono::seconds(TEN_SECONDS)); } \ No newline at end of file -- Gitee