Cache loaded source signatures safely
This commit is contained in:
parent
02ed75fc85
commit
ada01e34f4
@ -3,14 +3,24 @@ set -euo pipefail
|
||||
cd "$(dirname "$0")/.."
|
||||
|
||||
test_name="dependency-cache-test-$$"
|
||||
source_dir="site/$test_name"
|
||||
cache_dir="${BIN_DIRECTORY:-/tmp/uce/work}$(pwd)/$source_dir"
|
||||
site_directory="${UCE_TEST_SITE_DIRECTORY:-site}"
|
||||
source_dir="$site_directory/$test_name"
|
||||
bin_directory="${BIN_DIRECTORY:-}"
|
||||
if [[ -z "$bin_directory" && -r /etc/uce/settings.cfg ]]; then
|
||||
bin_directory=$(awk -F= '/^[[:space:]]*BIN_DIRECTORY[[:space:]]*=/ {gsub(/^[[:space:]]+|[[:space:]]+$/, "", $2); print $2; exit}' /etc/uce/settings.cfg)
|
||||
fi
|
||||
bin_directory="${bin_directory:-/tmp/uce/work}"
|
||||
cache_dir=""
|
||||
|
||||
cleanup() {
|
||||
rm -rf "$source_dir" "$cache_dir"
|
||||
rm -rf "$source_dir"
|
||||
if [[ -n "$cache_dir" ]]; then
|
||||
rm -rf "$cache_dir"
|
||||
fi
|
||||
}
|
||||
trap cleanup EXIT
|
||||
mkdir -p "$source_dir"
|
||||
cache_dir="$bin_directory$(realpath "$source_dir")"
|
||||
|
||||
printf '%s\n' \
|
||||
'#ifndef UCE_DEPENDENCY_CACHE_CHILD' \
|
||||
|
||||
@ -6,7 +6,9 @@
|
||||
#include <cctype>
|
||||
#include <filesystem>
|
||||
#include <fcntl.h>
|
||||
#include <mutex>
|
||||
#include <sys/file.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
|
||||
namespace {
|
||||
@ -43,6 +45,19 @@ struct SharedUnitCompileCheck
|
||||
bool needs_compile = false;
|
||||
};
|
||||
|
||||
struct UnitSourceSignatureEntry
|
||||
{
|
||||
u64 modified_ns = 0;
|
||||
u64 changed_ns = 0;
|
||||
u64 size = 0;
|
||||
String content_hash;
|
||||
StringList loaded_paths;
|
||||
};
|
||||
|
||||
const u64 UCE_UNIT_SOURCE_SIGNATURE_CACHE_MAX = 4096;
|
||||
std::mutex unit_source_signature_cache_mutex;
|
||||
std::map<String, UnitSourceSignatureEntry> unit_source_signature_cache;
|
||||
|
||||
bool compiler_jit_compile_on_request_enabled(Request* context)
|
||||
{
|
||||
if(!context || !context->server)
|
||||
@ -113,6 +128,33 @@ StringList compiler_unit_load_paths(String file_name, String content)
|
||||
return(paths);
|
||||
}
|
||||
|
||||
UnitSourceSignatureEntry compiler_unit_source_entry(String file_name)
|
||||
{
|
||||
struct stat info;
|
||||
UnitSourceSignatureEntry entry;
|
||||
if(stat(file_name.c_str(), &info) != 0)
|
||||
return(entry);
|
||||
entry.modified_ns = (u64)info.st_mtim.tv_sec * 1000000000ull + (u64)info.st_mtim.tv_nsec;
|
||||
entry.changed_ns = (u64)info.st_ctim.tv_sec * 1000000000ull + (u64)info.st_ctim.tv_nsec;
|
||||
entry.size = (u64)info.st_size;
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(unit_source_signature_cache_mutex);
|
||||
auto cached = unit_source_signature_cache.find(file_name);
|
||||
if(cached != unit_source_signature_cache.end() && cached->second.modified_ns == entry.modified_ns && cached->second.changed_ns == entry.changed_ns && cached->second.size == entry.size)
|
||||
return(cached->second);
|
||||
}
|
||||
String content = file_get_contents(file_name);
|
||||
entry.content_hash = gen_sha1(content);
|
||||
entry.loaded_paths = compiler_unit_load_paths(file_name, content);
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(unit_source_signature_cache_mutex);
|
||||
if(unit_source_signature_cache.size() >= UCE_UNIT_SOURCE_SIGNATURE_CACHE_MAX)
|
||||
unit_source_signature_cache.clear();
|
||||
unit_source_signature_cache[file_name] = entry;
|
||||
}
|
||||
return(entry);
|
||||
}
|
||||
|
||||
void compiler_append_unit_source_signature(String file_name, std::set<String>& visited, String& signature)
|
||||
{
|
||||
String normalized = path_real(file_name);
|
||||
@ -122,9 +164,9 @@ void compiler_append_unit_source_signature(String file_name, std::set<String>& v
|
||||
return;
|
||||
visited.insert(normalized);
|
||||
|
||||
String content = file_get_contents(file_name);
|
||||
signature += normalized + ":" + gen_sha1(content) + "\n";
|
||||
for(String loaded : compiler_unit_load_paths(file_name, content))
|
||||
UnitSourceSignatureEntry entry = compiler_unit_source_entry(normalized);
|
||||
signature += normalized + ":" + entry.content_hash + "\n";
|
||||
for(String loaded : entry.loaded_paths)
|
||||
compiler_append_unit_source_signature(loaded, visited, signature);
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user