@@ -81,9 +81,20 @@ namespace stellar
81
81
ApplicationImpl::ApplicationImpl (VirtualClock& clock, Config const & cfg)
82
82
: mVirtualClock (clock)
83
83
, mConfig (cfg)
84
- , mWorkerIOContext (mConfig .WORKER_THREADS)
84
+ // Allocate one worker to eviction when background eviction enabled
85
+ , mWorkerIOContext (mConfig .EXPERIMENTAL_BACKGROUND_EVICTION_SCAN
86
+ ? mConfig .WORKER_THREADS - 1
87
+ : mConfig .WORKER_THREADS)
88
+ , mEvictionIOContext (mConfig .EXPERIMENTAL_BACKGROUND_EVICTION_SCAN
89
+ ? std::make_optional<asio::io_context>(1 )
90
+ : std::nullopt)
85
91
, mWork (std::make_unique<asio::io_context::work>(mWorkerIOContext ))
92
+ , mEvictionWork (
93
+ mEvictionIOContext
94
+ ? std::make_unique<asio::io_context::work>(*mEvictionIOContext )
95
+ : nullptr )
86
96
, mWorkerThreads ()
97
+ , mEvictionThread ()
87
98
, mStopSignals (clock.getIOContext(), SIGINT)
88
99
, mStarted (false )
89
100
, mStopping (false )
@@ -135,6 +146,21 @@ ApplicationImpl::ApplicationImpl(VirtualClock& clock, Config const& cfg)
135
146
136
147
auto t = mConfig .WORKER_THREADS ;
137
148
LOG_DEBUG (DEFAULT_LOG, " Application constructing (worker threads: {})" , t);
149
+
150
+ if (mConfig .EXPERIMENTAL_BACKGROUND_EVICTION_SCAN )
151
+ {
152
+ releaseAssert (mConfig .WORKER_THREADS > 0 );
153
+ releaseAssert (mEvictionIOContext );
154
+
155
+ // Allocate one thread for Eviction scan
156
+ mEvictionThread = std::thread{[this ]() {
157
+ runCurrentThreadWithMediumPriority ();
158
+ mEvictionIOContext ->run ();
159
+ }};
160
+
161
+ --t;
162
+ }
163
+
138
164
while (t--)
139
165
{
140
166
auto thread = std::thread{[this ]() {
@@ -760,12 +786,21 @@ ApplicationImpl::validateAndLogConfig()
760
786
" stellar-core new-db." );
761
787
}
762
788
763
- if (mConfig .EXPERIMENTAL_BACKGROUND_EVICTION_SCAN &&
764
- !mConfig .isUsingBucketListDB ())
789
+ if (mConfig .EXPERIMENTAL_BACKGROUND_EVICTION_SCAN )
765
790
{
766
- throw std::invalid_argument (
767
- " EXPERIMENTAL_BUCKETLIST_DB must be enabled to use "
768
- " EXPERIMENTAL_BACKGROUND_EVICTION_SCAN" );
791
+ if (!mConfig .isUsingBucketListDB ())
792
+ {
793
+ throw std::invalid_argument (
794
+ " EXPERIMENTAL_BUCKETLIST_DB must be enabled to use "
795
+ " EXPERIMENTAL_BACKGROUND_EVICTION_SCAN" );
796
+ }
797
+
798
+ if (mConfig .WORKER_THREADS < 2 )
799
+ {
800
+ throw std::invalid_argument (
801
+ " EXPERIMENTAL_BACKGROUND_EVICTION_SCAN requires "
802
+ " WORKER_THREADS > 1" );
803
+ }
769
804
}
770
805
771
806
if (isNetworkedValidator && mConfig .isInMemoryMode ())
@@ -917,6 +952,18 @@ ApplicationImpl::joinAllThreads()
917
952
{
918
953
w.join ();
919
954
}
955
+
956
+ if (mEvictionWork )
957
+ {
958
+ mEvictionWork .reset ();
959
+ }
960
+
961
+ if (mEvictionThread )
962
+ {
963
+ LOG_DEBUG (DEFAULT_LOG, " Joining eviction thread" );
964
+ mEvictionThread ->join ();
965
+ }
966
+
920
967
LOG_DEBUG (DEFAULT_LOG, " Joined all {} threads" , mWorkerThreads .size ());
921
968
}
922
969
@@ -1386,6 +1433,13 @@ ApplicationImpl::getWorkerIOContext()
1386
1433
return mWorkerIOContext ;
1387
1434
}
1388
1435
1436
+ asio::io_context&
1437
+ ApplicationImpl::getEvictionIOContext ()
1438
+ {
1439
+ releaseAssert (mEvictionIOContext );
1440
+ return *mEvictionIOContext ;
1441
+ }
1442
+
1389
1443
void
1390
1444
ApplicationImpl::postOnMainThread (std::function<void ()>&& f, std::string&& name,
1391
1445
Scheduler::ActionType type)
@@ -1418,6 +1472,18 @@ ApplicationImpl::postOnBackgroundThread(std::function<void()>&& f,
1418
1472
});
1419
1473
}
1420
1474
1475
+ void
1476
+ ApplicationImpl::postOnEvictionBackgroundThread (std::function<void ()>&& f,
1477
+ std::string jobName)
1478
+ {
1479
+ LogSlowExecution isSlow{std::move (jobName), LogSlowExecution::Mode::MANUAL,
1480
+ " executed after" };
1481
+ asio::post (getEvictionIOContext (), [this , f = std::move (f), isSlow]() {
1482
+ mPostOnBackgroundThreadDelay .Update (isSlow.checkElapsedTime ());
1483
+ f ();
1484
+ });
1485
+ }
1486
+
1421
1487
void
1422
1488
ApplicationImpl::enableInvariantsFromConfig ()
1423
1489
{
0 commit comments