Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dynamically Linked Library in Presto CPP #24330

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

soumiiow
Copy link

@soumiiow soumiiow commented Jan 7, 2025

Description

Depends on facebookincubator/velox#11439 in the Velox space
and based off of the following PR: https://github.com/facebookincubator/velox/pull/1005/files

Motivation and Context

Having these changes will enable users to register custom functions dynamically without requiring a fork of Prestissimo.

Impact

This extends Prestissimo functionality to include dynamic loading of functions, types, connectors, etc.

Test Plan

Unit tested. and Manually end to end tested the changes.

Contributor checklist

  • Please make sure your submission complies with our contributing guide, in particular code style and commit standards.
  • PR description addresses the issue accurately and concisely. If the change is non-trivial, a GitHub Issue is referenced.
  • Documented new properties (with its default value), SQL syntax, functions, or other functionality.
  • If release notes are required, they follow the release notes guidelines.
  • Adequate tests were added if applicable.
  • CI passed.

Release Notes

Please follow release notes guidelines and fill in the release notes below.

== RELEASE NOTES ==

General Changes
* ... :pr:`12345`
* ... :pr:`12345`

Hive Connector Changes
* ... :pr:`12345`
* ... :pr:`12345`

If release note is NOT required, use:

== NO RELEASE NOTE ==

@soumiiow soumiiow self-assigned this Jan 7, 2025
Copy link

linux-foundation-easycla bot commented Jan 7, 2025

CLA Signed

The committers listed above are authorized under a signed CLA.

  • ✅ login: soumiiow / name: Soumya Duriseti (9cde5a4)

@soumiiow soumiiow marked this pull request as ready for review January 7, 2025 18:04
@soumiiow soumiiow requested a review from a team as a code owner January 7, 2025 18:04
@tdcmeehan tdcmeehan self-assigned this Jan 8, 2025
@tdcmeehan tdcmeehan added the from:IBM PR from IBM label Jan 30, 2025
@prestodb-ci prestodb-ci requested review from a team, pdabre12 and psnv03 and removed request for a team January 30, 2025 18:47
Copy link
Contributor

@czentgr czentgr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please also rebase.

@@ -76,7 +76,8 @@ target_link_libraries(
${FOLLY_WITH_DEPENDENCIES}
${GLOG}
${GFLAGS_LIBRARIES}
pthread)
pthread
velox_dynamic_function_loader)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Move this before the velox_encode library.

@@ -89,6 +90,7 @@ set_property(TARGET presto_server_lib PROPERTY JOB_POOL_LINK
presto_link_job_pool)

add_executable(presto_server PrestoMain.cpp)
target_link_options(presto_server BEFORE PUBLIC "-Wl,-export-dynamic")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we add a comment here why we need these flags?

const fs::path path(systemConfig->pluginDir());
PRESTO_STARTUP_LOG(INFO) << path;
std::error_code
ec; // For using the non-throwing overloads of functions below.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don;t need this comment here and so can fix up the odd formatting.

void PrestoServer::registerDynamicFunctions() {
auto systemConfig = SystemConfig::instance();
if (!systemConfig->pluginDir().empty()) {
// if it is a valid directory, traverse and call dynamic function loader
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please make sure the comments are full sentences beginning with capitalization etc.

auto dirEntryPath = dirEntry.path();
if (!fs::is_directory(dirEntry, ec) &&
extensions.find(dirEntryPath.extension()) != extensions.end()) {
facebook::velox::loadDynamicLibrary(dirEntryPath.c_str());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

facebook is not needed here because we are already in the facebook namespace.

Copy link
Contributor

@steveburnett steveburnett left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the doc! A few minor formatting and phrasing suggestions.

@@ -0,0 +1,17 @@
# Dynamic Loading of Presto Cpp Extensions
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
# Dynamic Loading of Presto Cpp Extensions
# Dynamic Loading of Presto CPP Extensions

@@ -0,0 +1,17 @@
# Dynamic Loading of Presto Cpp Extensions
This library adds the ability to load User Defined Functions (UDFs), connectors, or types without having to fork and build Prestissimo, through the use of shared libraries that a Prestissimo worker can access. These 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.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
This library adds the ability to load User Defined Functions (UDFs), connectors, or types without having to fork and build Prestissimo, through the use of shared libraries that a Prestissimo worker can access. These 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.
This library adds the ability to load User Defined Functions (UDFs), connectors, or types without having to fork and build Prestissimo, through the use of shared libraries that a Prestissimo worker can access. These are loaded on launch of the Presto server. The Presto server searches for any .so or .dylib files and loads them using this library.

This library adds the ability to load User Defined Functions (UDFs), connectors, or types without having to fork and build Prestissimo, through the use of shared libraries that a Prestissimo worker can access. These 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
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 [MyDynamicFunction.cpp](examples/MyDynamicFunction.cpp) as an example, the function uses the extern "C" keyword to protect against name mangling. A registry() function call is also necessary here.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
For dynamically loaded function registration, the format followed is mirrored of that of built-in function registration with some noted differences. Using [MyDynamicFunction.cpp](examples/MyDynamicFunction.cpp) as an example, the function uses the extern "C" keyword to protect against name mangling. A registry() function call is also necessary here.
For dynamically loaded function registration, the format is similar to that of built-in function registration, with some noted differences. Using [MyDynamicFunction.cpp](examples/MyDynamicFunction.cpp) as an example, the function uses the extern "C" keyword to protect against name mangling. A registry() function call is also necessary here.

# Dynamic Loading of Presto Cpp Extensions
This library adds the ability to load User Defined Functions (UDFs), connectors, or types without having to fork and build Prestissimo, through the use of shared libraries that a Prestissimo worker can access. These 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
1. Create a cpp file for your dynamic library
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
1. Create a cpp file for your dynamic library
1. Create a cpp file for your dynamic library

Add a blank line after the first sentence in each step to avoid this line running into the next line. See screenshot of what the current formatting looks like.
Screenshot 2025-02-04 at 9 47 01 AM

## Getting started
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 [MyDynamicFunction.cpp](examples/MyDynamicFunction.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
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
2. Register functions dynamically by creating .dylib or .so shared libraries and dropping them in a plugin directory
2. Register functions dynamically by creating .dylib or .so shared libraries and dropping them in a plugin directory

add_library(name_of_dynamic_fn SHARED TestFunction.cpp)
target_link_libraries(name_of_dynamic_fn PRIVATE fmt::fmt Folly::folly gflags::gflags)
```
3. In the Prestissimo worker's config.properties file, set the plugin.dir property
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
3. In the Prestissimo worker's config.properties file, set the plugin.dir property
3. In the Prestissimo worker's config.properties file, set the plugin.dir property

```
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
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
4. When the worker or the sidecar process starts, it will scan the plugin directory and attempt to dynamically load all shared libraries
When the worker or the sidecar process starts, it scans the plugin directory and attempts to dynamically load all shared libraries.

I don't think of this as part of the steps to configure, it's what happens when things are run using the config in steps 1-3.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
from:IBM PR from IBM
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants