mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-12-07 21:59:54 +00:00
LibRequests+RequestServer: Add a method to estimate disk cache size
This allows estimating the cache size stored on disk since a provided time stamp, and in total.
This commit is contained in:
parent
d5c00a493c
commit
ba49942b6d
Notes:
github-actions[bot]
2025-11-12 14:09:00 +00:00
Author: https://github.com/trflynn89
Commit: ba49942b6d
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/6675
Reviewed-by: https://github.com/gmta
Reviewed-by: https://github.com/konradekk
14 changed files with 138 additions and 3 deletions
|
|
@ -1,4 +1,5 @@
|
|||
set(SOURCES
|
||||
CacheSizes.cpp
|
||||
NetworkError.h
|
||||
Request.cpp
|
||||
RequestClient.cpp
|
||||
|
|
|
|||
31
Libraries/LibRequests/CacheSizes.cpp
Normal file
31
Libraries/LibRequests/CacheSizes.cpp
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* Copyright (c) 2025, Tim Flynn <trflynn89@ladybird.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <LibIPC/Decoder.h>
|
||||
#include <LibIPC/Encoder.h>
|
||||
#include <LibRequests/CacheSizes.h>
|
||||
|
||||
namespace IPC {
|
||||
|
||||
template<>
|
||||
ErrorOr<void> encode(Encoder& encoder, Requests::CacheSizes const& sizes)
|
||||
{
|
||||
TRY(encoder.encode(sizes.since_requested_time));
|
||||
TRY(encoder.encode(sizes.total));
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
template<>
|
||||
ErrorOr<Requests::CacheSizes> decode(Decoder& decoder)
|
||||
{
|
||||
auto since_requested_time = TRY(decoder.decode<u64>());
|
||||
auto total = TRY(decoder.decode<u64>());
|
||||
|
||||
return Requests::CacheSizes { since_requested_time, total };
|
||||
}
|
||||
|
||||
}
|
||||
29
Libraries/LibRequests/CacheSizes.h
Normal file
29
Libraries/LibRequests/CacheSizes.h
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* Copyright (c) 2025, Tim Flynn <trflynn89@ladybird.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AK/Types.h>
|
||||
#include <LibIPC/Forward.h>
|
||||
|
||||
namespace Requests {
|
||||
|
||||
struct CacheSizes {
|
||||
u64 since_requested_time { 0 };
|
||||
u64 total { 0 };
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
namespace IPC {
|
||||
|
||||
template<>
|
||||
ErrorOr<void> encode(Encoder&, Requests::CacheSizes const&);
|
||||
|
||||
template<>
|
||||
ErrorOr<Requests::CacheSizes> decode(Decoder&);
|
||||
|
||||
}
|
||||
|
|
@ -4,6 +4,7 @@
|
|||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <LibCore/Promise.h>
|
||||
#include <LibCore/System.h>
|
||||
#include <LibRequests/Request.h>
|
||||
#include <LibRequests/RequestClient.h>
|
||||
|
|
@ -24,7 +25,11 @@ void RequestClient::die()
|
|||
request->did_finish({}, {}, {}, NetworkError::RequestServerDied);
|
||||
}
|
||||
|
||||
for (auto& [id, promise] : m_pending_cache_size_estimations)
|
||||
promise->reject(Error::from_string_literal("RequestServer process died"));
|
||||
|
||||
m_requests.clear();
|
||||
m_pending_cache_size_estimations.clear();
|
||||
}
|
||||
|
||||
void RequestClient::ensure_connection(URL::URL const& url, ::RequestServer::CacheLevel cache_level)
|
||||
|
|
@ -73,6 +78,24 @@ bool RequestClient::set_certificate(Badge<Request>, Request& request, ByteString
|
|||
return IPCProxy::set_certificate(request.id(), move(certificate), move(key));
|
||||
}
|
||||
|
||||
NonnullRefPtr<Core::Promise<CacheSizes>> RequestClient::estimate_cache_size_accessed_since(UnixDateTime since)
|
||||
{
|
||||
auto promise = Core::Promise<CacheSizes>::construct();
|
||||
|
||||
auto cache_size_estimation_id = m_next_cache_size_estimation_id++;
|
||||
m_pending_cache_size_estimations.set(cache_size_estimation_id, promise);
|
||||
|
||||
async_estimate_cache_size_accessed_since(cache_size_estimation_id, since);
|
||||
|
||||
return promise;
|
||||
}
|
||||
|
||||
void RequestClient::estimated_cache_size(u64 cache_size_estimation_id, CacheSizes sizes)
|
||||
{
|
||||
if (auto promise = m_pending_cache_size_estimations.take(cache_size_estimation_id); promise.has_value())
|
||||
(*promise)->resolve(sizes);
|
||||
}
|
||||
|
||||
void RequestClient::request_finished(i32 request_id, u64 total_size, RequestTimingInfo timing_info, Optional<NetworkError> network_error)
|
||||
{
|
||||
RefPtr<Request> request;
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
#include <AK/HashMap.h>
|
||||
#include <LibHTTP/HeaderMap.h>
|
||||
#include <LibIPC/ConnectionToServer.h>
|
||||
#include <LibRequests/CacheSizes.h>
|
||||
#include <LibRequests/RequestTimingInfo.h>
|
||||
#include <LibRequests/WebSocket.h>
|
||||
#include <LibWebSocket/WebSocket.h>
|
||||
|
|
@ -39,6 +40,8 @@ public:
|
|||
bool stop_request(Badge<Request>, Request&);
|
||||
bool set_certificate(Badge<Request>, Request&, ByteString, ByteString);
|
||||
|
||||
NonnullRefPtr<Core::Promise<CacheSizes>> estimate_cache_size_accessed_since(UnixDateTime since);
|
||||
|
||||
Function<void()> on_request_server_died;
|
||||
|
||||
private:
|
||||
|
|
@ -57,10 +60,15 @@ private:
|
|||
virtual void websocket_subprotocol(i64 websocket_id, ByteString subprotocol) override;
|
||||
virtual void websocket_certificate_requested(i64 websocket_id) override;
|
||||
|
||||
HashMap<i32, RefPtr<Request>> m_requests;
|
||||
HashMap<i64, NonnullRefPtr<WebSocket>> m_websockets;
|
||||
virtual void estimated_cache_size(u64 cache_size_estimation_id, CacheSizes sizes) override;
|
||||
|
||||
HashMap<i32, RefPtr<Request>> m_requests;
|
||||
|
||||
HashMap<i64, NonnullRefPtr<WebSocket>> m_websockets;
|
||||
i64 m_next_websocket_id { 0 };
|
||||
|
||||
HashMap<u64, NonnullRefPtr<Core::Promise<CacheSizes>>> m_pending_cache_size_estimations;
|
||||
u64 m_next_cache_size_estimation_id { 0 };
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ target_include_directories(requestserverservice PRIVATE ${CMAKE_CURRENT_BINARY_D
|
|||
target_include_directories(requestserverservice PRIVATE ${LADYBIRD_SOURCE_DIR}/Services/)
|
||||
|
||||
target_link_libraries(RequestServer PRIVATE requestserverservice)
|
||||
target_link_libraries(requestserverservice PUBLIC LibCore LibDatabase LibDNS LibCrypto LibFileSystem LibIPC LibMain LibTLS LibWebSocket LibURL LibTextCodec LibThreading CURL::libcurl)
|
||||
target_link_libraries(requestserverservice PUBLIC LibCore LibDatabase LibDNS LibCrypto LibFileSystem LibIPC LibMain LibRequests LibTLS LibWebSocket LibURL LibTextCodec LibThreading CURL::libcurl)
|
||||
target_link_libraries(requestserverservice PRIVATE OpenSSL::Crypto OpenSSL::SSL)
|
||||
|
||||
if (WIN32)
|
||||
|
|
|
|||
|
|
@ -101,6 +101,7 @@ ErrorOr<CacheIndex> CacheIndex::create(Database::Database& database)
|
|||
statements.select_entry = TRY(database.prepare_statement("SELECT * FROM CacheIndex WHERE cache_key = ?;"sv));
|
||||
statements.update_response_headers = TRY(database.prepare_statement("UPDATE CacheIndex SET response_headers = ? WHERE cache_key = ?;"sv));
|
||||
statements.update_last_access_time = TRY(database.prepare_statement("UPDATE CacheIndex SET last_access_time = ? WHERE cache_key = ?;"sv));
|
||||
statements.estimate_cache_size_accessed_since = TRY(database.prepare_statement("SELECT SUM(data_size) + SUM(OCTET_LENGTH(response_headers)) FROM CacheIndex WHERE last_access_time >= ?;"sv));
|
||||
|
||||
return CacheIndex { database, statements };
|
||||
}
|
||||
|
|
@ -188,4 +189,21 @@ Optional<CacheIndex::Entry&> CacheIndex::find_entry(u64 cache_key)
|
|||
return m_entries.get(cache_key);
|
||||
}
|
||||
|
||||
Requests::CacheSizes CacheIndex::estimate_cache_size_accessed_since(UnixDateTime since) const
|
||||
{
|
||||
Requests::CacheSizes sizes;
|
||||
|
||||
m_database.execute_statement(
|
||||
m_statements.estimate_cache_size_accessed_since,
|
||||
[&](auto statement_id) { sizes.since_requested_time = m_database.result_column<u64>(statement_id, 0); },
|
||||
since);
|
||||
|
||||
m_database.execute_statement(
|
||||
m_statements.estimate_cache_size_accessed_since,
|
||||
[&](auto statement_id) { sizes.total = m_database.result_column<u64>(statement_id, 0); },
|
||||
UnixDateTime::earliest());
|
||||
|
||||
return sizes;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@
|
|||
#include <AK/Types.h>
|
||||
#include <LibDatabase/Database.h>
|
||||
#include <LibHTTP/HeaderMap.h>
|
||||
#include <LibRequests/CacheSizes.h>
|
||||
|
||||
namespace RequestServer {
|
||||
|
||||
|
|
@ -42,6 +43,8 @@ public:
|
|||
void update_response_headers(u64 cache_key, HTTP::HeaderMap);
|
||||
void update_last_access_time(u64 cache_key);
|
||||
|
||||
Requests::CacheSizes estimate_cache_size_accessed_since(UnixDateTime since) const;
|
||||
|
||||
private:
|
||||
struct Statements {
|
||||
Database::StatementID insert_entry { 0 };
|
||||
|
|
@ -50,6 +53,7 @@ private:
|
|||
Database::StatementID select_entry { 0 };
|
||||
Database::StatementID update_response_headers { 0 };
|
||||
Database::StatementID update_last_access_time { 0 };
|
||||
Database::StatementID estimate_cache_size_accessed_since { 0 };
|
||||
};
|
||||
|
||||
CacheIndex(Database::Database&, Statements);
|
||||
|
|
|
|||
|
|
@ -139,6 +139,11 @@ bool DiskCache::check_if_cache_has_open_entry(Request& request, u64 cache_key, C
|
|||
return false;
|
||||
}
|
||||
|
||||
Requests::CacheSizes DiskCache::estimate_cache_size_accessed_since(UnixDateTime since) const
|
||||
{
|
||||
return m_index.estimate_cache_size_accessed_since(since);
|
||||
}
|
||||
|
||||
void DiskCache::clear_cache()
|
||||
{
|
||||
for (auto const& [_, open_entries] : m_open_cache_entries) {
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ public:
|
|||
Variant<Optional<CacheEntryWriter&>, CacheHasOpenEntry> create_entry(Request&);
|
||||
Variant<Optional<CacheEntryReader&>, CacheHasOpenEntry> open_entry(Request&);
|
||||
|
||||
Requests::CacheSizes estimate_cache_size_accessed_since(UnixDateTime since) const;
|
||||
void clear_cache();
|
||||
|
||||
LexicalPath const& cache_directory() { return m_cache_directory; }
|
||||
|
|
|
|||
|
|
@ -302,6 +302,16 @@ void ConnectionFromClient::ensure_connection(URL::URL url, ::RequestServer::Cach
|
|||
m_active_requests.set(connect_only_request_id, move(request));
|
||||
}
|
||||
|
||||
void ConnectionFromClient::estimate_cache_size_accessed_since(u64 cache_size_estimation_id, UnixDateTime since)
|
||||
{
|
||||
Requests::CacheSizes sizes;
|
||||
|
||||
if (g_disk_cache.has_value())
|
||||
sizes = g_disk_cache->estimate_cache_size_accessed_since(since);
|
||||
|
||||
async_estimated_cache_size(cache_size_estimation_id, sizes);
|
||||
}
|
||||
|
||||
void ConnectionFromClient::clear_cache()
|
||||
{
|
||||
if (g_disk_cache.has_value())
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@ private:
|
|||
virtual Messages::RequestServer::SetCertificateResponse set_certificate(i32, ByteString, ByteString) override;
|
||||
virtual void ensure_connection(URL::URL url, ::RequestServer::CacheLevel cache_level) override;
|
||||
|
||||
virtual void estimate_cache_size_accessed_since(u64 cache_size_estimation_id, UnixDateTime since) override;
|
||||
virtual void clear_cache() override;
|
||||
|
||||
virtual void websocket_connect(i64 websocket_id, URL::URL, ByteString, Vector<ByteString>, Vector<ByteString>, HTTP::HeaderMap) override;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
#include <LibHTTP/HeaderMap.h>
|
||||
#include <LibRequests/CacheSizes.h>
|
||||
#include <LibRequests/NetworkError.h>
|
||||
#include <LibRequests/RequestTimingInfo.h>
|
||||
#include <LibURL/URL.h>
|
||||
|
|
@ -21,4 +22,6 @@ endpoint RequestClient
|
|||
|
||||
// Certificate requests
|
||||
certificate_requested(i32 request_id) =|
|
||||
|
||||
estimated_cache_size(u64 cache_size_estimation_id, Requests::CacheSizes sizes) =|
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ endpoint RequestServer
|
|||
|
||||
ensure_connection(URL::URL url, ::RequestServer::CacheLevel cache_level) =|
|
||||
|
||||
estimate_cache_size_accessed_since(u64 cache_size_estimation_id, UnixDateTime since) =|
|
||||
clear_cache() =|
|
||||
|
||||
// Websocket Connection API
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue