prod/native/libcommon/code/DependencyAutoLoaderGuard.cpp (66 lines of code) (raw):

/* * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one * or more contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright * ownership. Elasticsearch B.V. licenses this file to you under * the Apache License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ #include "DependencyAutoLoaderGuard.h" #include "LoggerInterface.h" #include "PhpBridgeInterface.h" #include <functional> #include <filesystem> #include <format> #include <set> namespace elasticapm::php { using namespace std::string_view_literals; void DependencyAutoLoaderGuard::setBootstrapPath(std::string_view bootstrapFilePath) { auto [major, minor] = bridge_->getPhpVersionMajorMinor(); auto path = std::filesystem::path(bootstrapFilePath).parent_path(); path /= std::format("vendor_{}{}", major, minor); vendorPath_ = path.c_str(); ELOGF_DEBUG(logger_, DEPGUARD, "vendor path set to: " PRsv, PRsvArg(vendorPath_)); } bool DependencyAutoLoaderGuard::shouldDiscardFileCompilation(std::string_view fileName) { try { std::string compiledFilePath = std::filesystem::exists(fileName) ? std::filesystem::canonical(fileName) : fileName; if (compiledFilePath.starts_with(vendorPath_)) { return false; } auto [lastClass, lastFunction] = bridge_->getNewlyCompiledFiles( [this](std::string_view name) { // storing only dependencies delivered by EDOT if (name.starts_with(vendorPath_)) { if (name.substr(vendorPath_.length()).starts_with("/composer/")) { // skip compsoer files - they must be compiled ELOGF_TRACE(logger_, DEPGUARD, "Skipping storage of composer files: " PRsv, PRsvArg(name)); return; } compiledFiles_.insert(name); ELOGF_TRACE(logger_, DEPGUARD, "Storing file: " PRsv, PRsvArg(name)); } }, lastClass_, lastFunction_); lastClass_ = lastClass; lastFunction_ = lastFunction; if (wasDeliveredByEDOT(compiledFilePath)) { ELOGF_DEBUG(logger_, DEPGUARD, "Compilation of file '" PRsv "' will be discarded", PRsvArg(compiledFilePath)); return true; } } catch (std::exception const &e) { ELOGF_WARNING(logger_, DEPGUARD, "shouldDiscardFileCompilation of file '" PRsv "' throwed: %s", PRsvArg(fileName), e.what()); return false; } return false; } bool DependencyAutoLoaderGuard::wasDeliveredByEDOT(std::string_view fileName) const { constexpr std::string_view vendor = "/vendor/"sv; auto vendorPos = fileName.find(vendor); if (vendorPos == std::string_view::npos) { return false; } auto afterVendor = fileName.substr(vendorPos + vendor.size()); auto found = std::find_if(std::begin(compiledFiles_), std::end(compiledFiles_), [afterVendor, bootstrapLen = vendorPath_.length()](std::string_view storedFile) -> bool { std::string_view fileView = storedFile.substr(bootstrapLen + 1); // add 1 for slash if (fileView == afterVendor) { return true; } return false; }); if (found != std::end(compiledFiles_)) { return true; } return false; } } // namespace elasticapm::php