2323#include < Storages/KVStore/FFI/ProxyFFICommon.h>
2424#include < Storages/KVStore/KVStore.h>
2525#include < Storages/KVStore/TMTContext.h>
26+ #include < Storages/S3/FileCache.h>
2627#include < Storages/S3/S3GCManager.h>
2728#include < TiDB/OwnerManager.h>
2829#include < TiDB/Schema/SchemaSyncService.h>
3233
3334#include < boost/algorithm/string.hpp>
3435#include < magic_enum.hpp>
36+ #include < string>
3537
3638namespace DB
3739{
@@ -181,16 +183,19 @@ HttpRequestRes HandleHttpRequestStoreStatus(
181183
182184// Check whether the disaggregated mode is enabled.
183185// If not, return a HttpRequestRes with error message.
184- std::optional<HttpRequestRes> allowDisaggAPI (Context & global_ctx, std::string_view message)
186+ std::optional<HttpRequestRes> allowDisaggAPI (
187+ Context & global_ctx,
188+ DisaggregatedMode expect_mode,
189+ std::string_view message)
185190{
186- if (! global_ctx.getSharedContextDisagg ()->isDisaggregatedStorageMode () )
191+ if (global_ctx.getSharedContextDisagg ()->disaggregated_mode != expect_mode )
187192 {
188193 auto * body = RawCppString::New (fmt::format (
189194 R"json( {{"message":"{}, disagg_mode={}"}})json" ,
190195 message,
191196 magic_enum::enum_name (global_ctx.getSharedContextDisagg ()->disaggregated_mode )));
192197 return HttpRequestRes{
193- .status = HttpRequestStatus::ErrorParam ,
198+ .status = HttpRequestStatus::Ok ,
194199 .res = CppStrWithView{
195200 .inner = GenRawCppPtr (body, RawCppPtrTypeImpl::String),
196201 .view = BaseBuffView{body->data (), body->size ()},
@@ -209,7 +214,7 @@ HttpRequestRes HandleHttpRequestRemoteReUpload(
209214 std::string_view)
210215{
211216 auto & global_ctx = server->tmt ->getContext ();
212- if (auto err_resp = allowDisaggAPI (global_ctx, " can not sync remote store" ); err_resp)
217+ if (auto err_resp = allowDisaggAPI (global_ctx, DisaggregatedMode::Storage, " can not sync remote store" ); err_resp)
213218 {
214219 return err_resp.value ();
215220 }
@@ -234,7 +239,7 @@ HttpRequestRes HandleHttpRequestRemoteOwnerInfo(
234239 std::string_view)
235240{
236241 auto & global_ctx = server->tmt ->getContext ();
237- if (auto err_resp = allowDisaggAPI (global_ctx, " can not get gc owner" ); err_resp)
242+ if (auto err_resp = allowDisaggAPI (global_ctx, DisaggregatedMode::Storage, " can not get gc owner" ); err_resp)
238243 {
239244 return err_resp.value ();
240245 }
@@ -263,7 +268,7 @@ HttpRequestRes HandleHttpRequestRemoteOwnerResign(
263268 std::string_view)
264269{
265270 auto & global_ctx = server->tmt ->getContext ();
266- if (auto err_resp = allowDisaggAPI (global_ctx, " can not resign gc owner" ); err_resp)
271+ if (auto err_resp = allowDisaggAPI (global_ctx, DisaggregatedMode::Storage, " can not resign gc owner" ); err_resp)
267272 {
268273 return err_resp.value ();
269274 }
@@ -290,7 +295,7 @@ HttpRequestRes HandleHttpRequestRemoteGC(
290295 std::string_view)
291296{
292297 auto & global_ctx = server->tmt ->getContext ();
293- if (auto err_resp = allowDisaggAPI (global_ctx, " can not trigger gc" ); err_resp)
298+ if (auto err_resp = allowDisaggAPI (global_ctx, DisaggregatedMode::Storage, " can not trigger gc" ); err_resp)
294299 {
295300 return err_resp.value ();
296301 }
@@ -317,6 +322,79 @@ HttpRequestRes HandleHttpRequestRemoteGC(
317322 };
318323}
319324
325+ HttpRequestRes HandleHttpRequestRemoteCacheEvict (
326+ EngineStoreServerWrap * server,
327+ std::string_view path,
328+ const std::string & api_name,
329+ std::string_view,
330+ std::string_view)
331+ {
332+ auto & global_ctx = server->tmt ->getContext ();
333+ if (auto err_resp = allowDisaggAPI (global_ctx, DisaggregatedMode::Compute, " can not trigger remote cache evict" );
334+ err_resp)
335+ {
336+ return err_resp.value ();
337+ }
338+
339+ auto log = Logger::get (" HandleHttpRequestRemoteCacheEvict" );
340+ LOG_INFO (log, " handling remote cache evict request, path={} api_name={}" , path, api_name);
341+ FileSegment::FileType evict_until_type;
342+ {
343+ // schema: /tiflash/remote/cache/evict/{file_type_int}
344+ auto query = path.substr (api_name.size ());
345+ if (query.empty () || query[0 ] != ' /' )
346+ {
347+ auto * body = RawCppString::New (
348+ fmt::format (R"json( {{"message":"invalid remote cache evict request: {}"}})json" , path));
349+ return HttpRequestRes{
350+ .status = HttpRequestStatus::Ok,
351+ .res = CppStrWithView{
352+ .inner = GenRawCppPtr (body, RawCppPtrTypeImpl::String),
353+ .view = BaseBuffView{body->data (), body->size ()},
354+ },
355+ };
356+ }
357+ query.remove_prefix (1 );
358+ std::optional<FileSegment::FileType> opt_evict_until_type = std::nullopt ;
359+ try
360+ {
361+ auto itype = std::stoll (query.data ());
362+ opt_evict_until_type = magic_enum::enum_cast<FileSegment::FileType>(itype);
363+ }
364+ catch (...)
365+ {
366+ // ignore
367+ }
368+ if (!opt_evict_until_type.has_value ())
369+ {
370+ auto * body = RawCppString::New (
371+ fmt::format (R"json( {{"message":"invalid file_type in remote cache evict request: {}"}})json" , path));
372+ return HttpRequestRes{
373+ .status = HttpRequestStatus::Ok,
374+ .res = CppStrWithView{
375+ .inner = GenRawCppPtr (body, RawCppPtrTypeImpl::String),
376+ .view = BaseBuffView{body->data (), body->size ()},
377+ },
378+ };
379+ }
380+ // successfully parse the file type
381+ evict_until_type = opt_evict_until_type.value ();
382+ }
383+
384+ auto released_size = DB::FileCache::instance ()->evictUntil (evict_until_type);
385+ auto * body = RawCppString::New (fmt::format (
386+ R"json( {{"file_type":"{}","released_size":"{}"}})json" ,
387+ magic_enum::enum_name (evict_until_type),
388+ released_size));
389+ return HttpRequestRes{
390+ .status = HttpRequestStatus::Ok,
391+ .res = CppStrWithView{
392+ .inner = GenRawCppPtr (body, RawCppPtrTypeImpl::String),
393+ .view = BaseBuffView{body->data (), body->size ()},
394+ },
395+ };
396+ }
397+
320398// Acquiring the all the region ids created in this TiFlash node with given keyspace id.
321399HttpRequestRes HandleHttpRequestSyncRegion (
322400 EngineStoreServerWrap * server,
@@ -502,6 +580,7 @@ static const std::map<std::string, HANDLE_HTTP_URI_METHOD> AVAILABLE_HTTP_URI =
502580 {" /tiflash/remote/owner/resign" , HandleHttpRequestRemoteOwnerResign},
503581 {" /tiflash/remote/gc" , HandleHttpRequestRemoteGC},
504582 {" /tiflash/remote/upload" , HandleHttpRequestRemoteReUpload},
583+ {" /tiflash/remote/cache/evict" , HandleHttpRequestRemoteCacheEvict},
505584};
506585
507586uint8_t CheckHttpUriAvailable (BaseBuffView path_)
@@ -530,9 +609,9 @@ HttpRequestRes HandleHttpRequest(
530609 return method (
531610 server,
532611 path,
533- str,
534- std::string_view (query.data , query.len ),
535- std::string_view (body.data , body.len ));
612+ /* api_name= */ str,
613+ /* query= */ std::string_view (query.data , query.len ),
614+ /* body= */ std::string_view (body.data , body.len ));
536615 }
537616 }
538617 return HttpRequestRes{
0 commit comments