-
Notifications
You must be signed in to change notification settings - Fork 5.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
dylib library + changes made to the readme to address comments
- Loading branch information
soumyaduriseti
committed
Sep 24, 2024
1 parent
410d3ec
commit e8a8326
Showing
18 changed files
with
338 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
13 changes: 13 additions & 0 deletions
13
presto-native-execution/presto_cpp/main/functions/CMakeLists.txt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
add_library(presto_dynamic_function_loader OBJECT DynamicLibraryLoader.cpp) | ||
|
||
if(PRESTO_ENABLE_TESTING) | ||
add_subdirectory(tests) | ||
endif() | ||
|
||
if(PRESTO_ENABLE_REMOTE_FUNCTIONS) | ||
add_library(presto_server_remote_function RemoteFunctionRegisterer.cpp) | ||
|
||
target_link_libraries(presto_server_remote_function velox_expression | ||
velox_functions_remote ${FOLLY_WITH_DEPENDENCIES}) | ||
target_link_libraries(presto_server_lib presto_server_remote_function) | ||
endif() |
45 changes: 45 additions & 0 deletions
45
presto-native-execution/presto_cpp/main/functions/DynamicLibraryLoader.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
/* | ||
* Copyright (c) Facebook, Inc. and its affiliates. | ||
* | ||
* Licensed 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 "presto_cpp/main/functions/DynamicLibraryLoader.h" | ||
#include <dlfcn.h> | ||
#include <iostream> | ||
#include "velox/common/base/Exceptions.h" | ||
namespace facebook::presto { | ||
|
||
static constexpr const char* kSymbolName = "registry"; | ||
|
||
void loadDynamicLibraryFunctions(const char* fileName) { | ||
// Try to dynamically load the shared library. | ||
void* handler = dlopen(fileName, RTLD_NOW); | ||
|
||
if (handler == nullptr) { | ||
VELOX_USER_FAIL("Error while loading shared library: {}", dlerror()); | ||
} | ||
|
||
// Lookup the symbol. | ||
void* registrySymbol = dlsym(handler, kSymbolName); | ||
auto registryFunction = reinterpret_cast<void (*)()>(registrySymbol); | ||
char* error = dlerror(); | ||
|
||
if (error != nullptr) { | ||
VELOX_USER_FAIL("Couldn't find Velox registry symbol: {}", error); | ||
} | ||
registryFunction(); | ||
std::cout << "LOADED DYLLIB 1" << std::endl; | ||
} | ||
|
||
} // namespace facebook::presto |
37 changes: 37 additions & 0 deletions
37
presto-native-execution/presto_cpp/main/functions/DynamicLibraryLoader.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
/* | ||
* Copyright (c) Facebook, Inc. and its affiliates. | ||
* | ||
* Licensed 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. | ||
*/ | ||
|
||
#pragma once | ||
|
||
namespace facebook::presto { | ||
|
||
/// Dynamically opens and registers functions defined in a shared library (.so) | ||
/// | ||
/// Given a shared library name (.so), this function will open it using dlopen, | ||
/// search for a "void registry()" C function containing the registration code | ||
/// for the functions defined in library, and execute it. | ||
/// | ||
/// The library being linked needs to provide a function with the following | ||
/// signature: | ||
/// | ||
/// void registry(); | ||
/// | ||
/// The registration function needs to be defined in the top-level namespace, | ||
/// and be enclosed by a extern "C" directive to prevent the compiler from | ||
/// mangling the symbol name. | ||
void loadDynamicLibraryFunctions(const char* fileName); | ||
|
||
} // namespace facebook::presto |
23 changes: 23 additions & 0 deletions
23
presto-native-execution/presto_cpp/main/functions/README.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
# Prestissimo: Dynamically Loading Function Library | ||
|
||
This library adds the ability to load User Defined Functions (UDFs) without having to fork and build Prestissimo, through the use of shared libraries that a Prestissimo worker can access. The dynamic functions are to be loaded on launch of the Presto server. The Presto server searches for any .so or .dylib files and loads them using this library. | ||
|
||
## Getting started | ||
|
||
The Process can be roughly broken down into the steps below: | ||
### 1. Create a cpp file for your dynamic library | ||
For dynamically loaded function registration, the format followed is mirrored of that of built-in function registration with some noted differences. Using [MyDynamicTestFunction.cpp](tests/MyDynamicTestFunction.cpp) as an example, the function uses the extern "C" keyword to protect against name mangling. A registry() function call is also necessary here. | ||
|
||
### 2. Register functions dynamically by creating .dylib or .so shared libraries and dropping them in a plugin directory. | ||
These shared libraries may be made using CMakeLists like the following: | ||
``` | ||
add_library(name_of_dynamic_fn SHARED TestFunction.cpp) | ||
target_link_libraries(name_of_dynamic_fn PRIVATE xsimd fmt::fmt velox_expression) | ||
``` | ||
|
||
### 3. In the Prestissimo worker's config.properties file, set the plugin.dir property | ||
This is where you will be dropping your shared library. | ||
``` | ||
plugin.dir="User\Test\Path\plugin" | ||
``` | ||
### 4. When the worker or the sidecar process starts, it will scan the plugin directory and attempt to dynamically load all shared libraries. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
27 changes: 27 additions & 0 deletions
27
presto-native-execution/presto_cpp/main/functions/tests/CMakeLists.txt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
# To test functions being added by dynamically linked libraries, we compile | ||
# `MyDynamicTestFunction.cpp` as a small .so library, and use the | ||
# MY_DYNAMIC_FUNCTION_LIBRARY_PATH macro to locate the .so binary. | ||
add_compile_definitions( | ||
MY_DYNAMIC_FUNCTION_LIBRARY_PATH="${CMAKE_CURRENT_BINARY_DIR}") | ||
add_library(presto_function_my_dynamic SHARED MyDynamicTestFunction.cpp) | ||
target_link_libraries(presto_function_my_dynamic PRIVATE xsimd fmt::fmt | ||
velox_expression) | ||
|
||
# Here's the actual test which will dynamically load the library defined above. | ||
add_executable(presto_function_dynamic_link_test DynamicLinkTest.cpp) | ||
|
||
add_test(NAME presto_function_dynamic_link_test | ||
COMMAND presto_function_dynamic_link_test) | ||
|
||
target_link_libraries( | ||
presto_function_dynamic_link_test | ||
velox_functions_test_lib | ||
presto_dynamic_function_loader | ||
velox_function_registry | ||
xsimd | ||
gmock | ||
${GTEST_BOTH_LIBRARIES}) | ||
|
||
# these are the testing flags all in a dynamic library | ||
add_library(presto_flags SHARED FlagLibrary.cpp) | ||
target_link_libraries(presto_flags gflags::gflags) |
57 changes: 57 additions & 0 deletions
57
presto-native-execution/presto_cpp/main/functions/tests/DynamicLinkTest.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
/* | ||
* Copyright (c) Facebook, Inc. and its affiliates. | ||
* | ||
* Licensed 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 <gmock/gmock.h> | ||
#include <gtest/gtest.h> | ||
|
||
#include "presto_cpp/main/functions/DynamicLibraryLoader.h" | ||
#include "velox/common/base/Exceptions.h" | ||
#include "velox/functions/FunctionRegistry.h" | ||
#include "velox/functions/prestosql/tests/utils/FunctionBaseTest.h" | ||
|
||
using namespace facebook::velox::functions::test; | ||
using namespace facebook::velox; | ||
using namespace facebook::presto; | ||
namespace facebook::presto::functions::test { | ||
|
||
class DynamicLinkTest : public FunctionBaseTest {}; | ||
|
||
TEST_F(DynamicLinkTest, dynamicLoad) { | ||
const auto dynamicFunction = [&](std::optional<double> a) { | ||
return evaluateOnce<int64_t>("dynamic_123()", a); | ||
}; | ||
|
||
auto signaturesBefore = getFunctionSignatures().size(); | ||
|
||
// Function does not exist yet. | ||
EXPECT_THROW(dynamicFunction(0), VeloxUserError); | ||
|
||
// Dynamically load the library. | ||
std::string libraryPath = MY_DYNAMIC_FUNCTION_LIBRARY_PATH; | ||
libraryPath += | ||
"/libpresto_function_my_dynamic.dylib"; // building on MacOS leads to | ||
// .dylib file not .so file | ||
|
||
loadDynamicLibraryFunctions(libraryPath.data()); | ||
|
||
auto signaturesAfter = getFunctionSignatures().size(); | ||
EXPECT_EQ(signaturesAfter, signaturesBefore + 1); | ||
|
||
// Make sure the function exists now. | ||
EXPECT_EQ(123, dynamicFunction(0)); | ||
} | ||
|
||
} // namespace facebook::presto::functions::test |
Oops, something went wrong.