@@ -846,6 +846,73 @@ TEST_P(DBWriteBufferManagerTest, StopSwitchingMemTablesOnceFlushing) {
846
846
delete shared_wbm_db;
847
847
}
848
848
849
+ TEST_F (DBWriteBufferManagerTest, RuntimeChangeableAllowStall) {
850
+ constexpr int kBigValue = 10000 ;
851
+
852
+ Options options = CurrentOptions ();
853
+ options.write_buffer_manager .reset (
854
+ new WriteBufferManager (1 , nullptr /* cache */ , true /* allow_stall */ ));
855
+ DestroyAndReopen (options);
856
+
857
+ // Pause flush thread so that
858
+ // (a) the only way to exist write stall below is to change the `allow_stall`
859
+ // (b) the write stall is "stable" without being interfered by flushes so that
860
+ // we can check it without flakiness
861
+ std::unique_ptr<test::SleepingBackgroundTask> sleeping_task (
862
+ new test::SleepingBackgroundTask ());
863
+ env_->SetBackgroundThreads (1 , Env::HIGH);
864
+ env_->Schedule (&test::SleepingBackgroundTask::DoSleepTask,
865
+ sleeping_task.get (), Env::Priority::HIGH);
866
+ sleeping_task->WaitUntilSleeping ();
867
+
868
+ // Test 1: test setting `allow_stall` from true to false
869
+ //
870
+ // Assert existence of a write stall
871
+ WriteOptions wo_no_slowdown;
872
+ wo_no_slowdown.no_slowdown = true ;
873
+ Status s = Put (Key (0 ), DummyString (kBigValue ), wo_no_slowdown);
874
+ ASSERT_TRUE (s.IsIncomplete ());
875
+ ASSERT_TRUE (s.ToString ().find (" Write stall" ) != std::string::npos);
876
+
877
+ ROCKSDB_NAMESPACE::SyncPoint::GetInstance ()->LoadDependency (
878
+ {{" WBMStallInterface::BlockDB" ,
879
+ " DBWriteBufferManagerTest::RuntimeChangeableThreadSafeParameters::"
880
+ " ChangeParameter" }});
881
+ ROCKSDB_NAMESPACE::SyncPoint::GetInstance ()->EnableProcessing ();
882
+
883
+ // Test `SetAllowStall()`
884
+ port::Thread thread1 ([&] { ASSERT_OK (Put (Key (0 ), DummyString (kBigValue ))); });
885
+ port::Thread thread2 ([&] {
886
+ TEST_SYNC_POINT (
887
+ " DBWriteBufferManagerTest::RuntimeChangeableThreadSafeParameters::"
888
+ " ChangeParameter" );
889
+ options.write_buffer_manager ->SetAllowStall (false );
890
+ });
891
+
892
+ // Verify `allow_stall` is successfully set to false in thread2.
893
+ // Othwerwise, thread1's write will be stalled and this test will hang
894
+ // forever.
895
+ thread1.join ();
896
+ thread2.join ();
897
+
898
+ ROCKSDB_NAMESPACE::SyncPoint::GetInstance ()->ClearAllCallBacks ();
899
+ ROCKSDB_NAMESPACE::SyncPoint::GetInstance ()->DisableProcessing ();
900
+
901
+ // Test 2: test setting `allow_stall` from false to true
902
+ //
903
+ // Assert no write stall
904
+ ASSERT_OK (Put (Key (0 ), DummyString (kBigValue ), wo_no_slowdown));
905
+
906
+ // Test `SetAllowStall()`
907
+ options.write_buffer_manager ->SetAllowStall (true );
908
+
909
+ // Verify `allow_stall` is successfully set to true.
910
+ // Otherwise the following write will not be stalled and therefore succeed.
911
+ s = Put (Key (0 ), DummyString (kBigValue ), wo_no_slowdown);
912
+ ASSERT_TRUE (s.IsIncomplete ());
913
+ ASSERT_TRUE (s.ToString ().find (" Write stall" ) != std::string::npos);
914
+ sleeping_task->WakeUp ();
915
+ }
849
916
850
917
INSTANTIATE_TEST_CASE_P (DBWriteBufferManagerTest, DBWriteBufferManagerTest,
851
918
testing::Bool ());
0 commit comments