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

Implement REST API for remote functions #23687

Merged
merged 2 commits into from
Jan 30, 2025

Conversation

abevk2023
Copy link
Contributor

Implements RFC-0007-remote-functions

  • Add new function namespace manager and execution module for REST-based remote functions.
  • Add OpenAPI specification which defines a REST API for remote function servers.
  • Add REST API reference implementation for the integration tests.
== NO RELEASE NOTE ==

@abevk2023 abevk2023 requested review from shrinidhijoshi and a team as code owners September 20, 2024 07:24
@abevk2023 abevk2023 changed the title Implement REST API for remote functions [WIP] Implement REST API for remote functions Sep 20, 2024
@abevk2023 abevk2023 marked this pull request as draft September 20, 2024 08:45
@abevk2023 abevk2023 force-pushed the reference_function_server branch from 5d88dbc to 6efefeb Compare September 23, 2024 06:15
@tdcmeehan tdcmeehan self-assigned this Sep 23, 2024
@abevk2023 abevk2023 force-pushed the reference_function_server branch 6 times, most recently from 7203526 to f05ea00 Compare October 1, 2024 09:35
@abevk2023 abevk2023 force-pushed the reference_function_server branch 2 times, most recently from 74cddc6 to cf23586 Compare October 8, 2024 15:35
@abevk2023 abevk2023 marked this pull request as ready for review October 8, 2024 15:46
@abevk2023 abevk2023 force-pushed the reference_function_server branch from cf23586 to 5e5abbe Compare October 9, 2024 10:27
@abevk2023 abevk2023 changed the title [WIP] Implement REST API for remote functions Implement REST API for remote functions Oct 9, 2024
@@ -436,7 +436,6 @@
<dependency>
<groupId>com.facebook.presto</groupId>
<artifactId>presto-thrift-api</artifactId>
<scope>test</scope>
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: lets move this above line 384 so it's out of the testing section

Copy link
Contributor Author

@abevk2023 abevk2023 Oct 10, 2024

Choose a reason for hiding this comment

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

Thank you Jacob. Moved

@@ -466,7 +465,6 @@
<dependency>
<groupId>com.facebook.presto</groupId>
<artifactId>presto-function-namespace-managers</artifactId>
<scope>test</scope>
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: lets move this above line 384 so it's out of the testing section

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Moved

Copy link
Contributor

@tdcmeehan tdcmeehan left a comment

Choose a reason for hiding this comment

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

Add namespace manager to retrieve REST function signatures.

.setUri(uri)
.build();

StatusResponseHandler.StatusResponse response = httpClient.execute(request, StatusResponseHandler.createStatusResponseHandler());
Copy link
Contributor

Choose a reason for hiding this comment

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

Please static import createStatusResponseHandler

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Corrected

}
return version;
}
catch (Exception e) {
Copy link
Contributor

Choose a reason for hiding this comment

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

If it's an IOException, let it bubble up.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It is not. Removed the exception for missing ETag.

latestFunctions.clear();
UdfFunctionSignatureMap udfFunctionSignatureMap = restApis.getAllFunctions();
if (udfFunctionSignatureMap == null || udfFunctionSignatureMap.isEmpty()) {
return Collections.emptyList();
Copy link
Contributor

Choose a reason for hiding this comment

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

ImmutableList.of()

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Corrected


public class RestBasedFunctionNamespaceManagerConfig
{
private String restUrl = "";
Copy link
Contributor

Choose a reason for hiding this comment

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

Let's make the default null, to indicate it's a mandatory config.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

private RestBasedFunctionNamespaceManager functionNamespaceManager;
public static final String TEST_CATALOG = "unittest";
public static final URI REST_SERVER_URI = URI.create("http://127.0.0.1:1122");
TestingFunctionResource resource;
Copy link
Contributor

Choose a reason for hiding this comment

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

Missing visibility.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Corrected.

@abevk2023 abevk2023 force-pushed the reference_function_server branch from bb11659 to eb021e3 Compare October 28, 2024 09:41
Copy link
Contributor

@tdcmeehan tdcmeehan left a comment

Choose a reason for hiding this comment

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

Introduce REST based Function Namespace Manager

Comment on lines 52 to 54
this.functionSignatureMapJsonCodec = nativeFunctionSignatureMapJsonCodec;
this.httpClient = httpClient;
this.managerConfig = managerConfig;
Copy link
Contributor

Choose a reason for hiding this comment

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

Please add requireNonNull for all inputs.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Added.

private static final Logger log = Logger.get(RestBasedFunctionNamespaceManager.class);
private final RestBasedFunctionApis restApis;
private final List<SqlInvokedFunction> latestFunctions = new ArrayList<>();
private Optional<String> cachedETag = Optional.empty();
Copy link
Contributor

Choose a reason for hiding this comment

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

I think this needs to be an AtomicReference, since it's updated concurrently.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Corrected. Used AtomicReference.


private URI getExecutionEndpoint(SqlFunctionId functionId, String functionVersion)
{
if (restBasedFunctionNamespaceManagerConfig.getRestUrl() == null) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Because the getter is annotated with @NotNull, I believe this is pre-validated and you can skip this.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Removed.

@Override
public SqlFunctionResult handle(Request request, Response response)
{
if (response.getStatusCode() == 404) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Search the codebase for constants representing these HTTP error codes

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Used HTTP error codes in java.net.

{
this.functionSignatureMapJsonCodec = requireNonNull(nativeFunctionSignatureMapJsonCodec, "nativeFunctionSignatureMapJsonCodec is null");
this.httpClient = requireNonNull(httpClient, "httpClient is null");
this.managerConfig = requireNonNull(managerConfig, "httpClient is null");
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.managerConfig = requireNonNull(managerConfig, "httpClient is null");
this.managerConfig = requireNonNull(managerConfig, "managerConfig is null");

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Removed managerConfig

return latestFunctions;
}

private void createSqlInvokedFunctions(UdfFunctionSignatureMap udfFunctionSignatureMap, List<SqlInvokedFunction> functionList)
Copy link
Contributor

Choose a reason for hiding this comment

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

Can you have this return the list of functions, and merge the output caller side? Rather than mutating the funcionList?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Corrected. Returned list of functions.

<configuration>
<finalName>presto-function-server-executable</finalName>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
Copy link
Contributor

Choose a reason for hiding this comment

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

Why is this needed?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Reference function server is package as presto-function-server-executable and executed in parallel to presto server launcher. Could you please refer the PR for e2e testing https://github.com/prestodb/presto/pull/23777/files#diff-4f5cabe26761257a4d685a6edc7a43e0fe0f78762f50eeb48530f2bd3b3ee7caR5

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Removed. We will add function server executable in subsequent PR.

@abevk2023 abevk2023 force-pushed the reference_function_server branch 3 times, most recently from 6b81999 to 23f69f4 Compare December 20, 2024 08:03
@abevk2023 abevk2023 force-pushed the reference_function_server branch 2 times, most recently from 007d089 to 9e96957 Compare January 6, 2025 05:32
@@ -265,7 +265,6 @@
<dependency>
<groupId>com.facebook.presto</groupId>
<artifactId>presto-function-namespace-managers</artifactId>
<scope>test</scope>
Copy link
Contributor

Choose a reason for hiding this comment

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

Is this intentionally removed?

Copy link
Contributor Author

@abevk2023 abevk2023 Jan 23, 2025

Choose a reason for hiding this comment

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

Reverted. No required now, as FunctionServer is moved to new maven module presto-function-server. This change was done to use presto-function-namespace-managers in thepresto-main for the FunctionServer.

<artifactId>jackson-datatype-jdk8</artifactId>
</dependency>

<dependency>
Copy link
Contributor

Choose a reason for hiding this comment

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

Do we need this dependency?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes. It is required for presto-function-namespace-managers. Throws undeclared dependency error if removed.

[INFO] --- maven-dependency-plugin:3.1.1:analyze-only (default) @ presto-function-namespace-managers ---
[WARNING] Used undeclared dependencies found:
[WARNING]    com.facebook.drift:drift-transport-netty:jar:1.40:compile

@abevk2023 abevk2023 force-pushed the reference_function_server branch 4 times, most recently from 63bdd7d to 1d3518b Compare January 27, 2025 15:58
<executions>
<execution>
<id>modernizer</id>
<phase>none</phase> <!-- This disables the plugin -->
Copy link
Contributor

Choose a reason for hiding this comment

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

Do we need to disable it?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Enabled and reused existing src/modernizer/violations.xml. Previously disabled due to missing file.

@@ -136,7 +136,39 @@ public SqlInvokedFunction(
throw new IllegalArgumentException("aggregationMetadata must be present for aggregation functions and absent otherwise");
}
}
public SqlInvokedFunction(
Copy link
Contributor

Choose a reason for hiding this comment

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

This looks mostly copied from the constructor above. Can they be consolidated?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Corrected. Refactored to consolidate shared logic.

@abevk2023 abevk2023 force-pushed the reference_function_server branch 2 times, most recently from 5efdedd to 44d6eb2 Compare January 28, 2025 13:09
tdcmeehan
tdcmeehan previously approved these changes Jan 28, 2025
@@ -1509,6 +1509,8 @@ struct JsonBasedUdfFunctionMetadata {
String schema = {};
RoutineCharacteristics routineCharacteristics = {};
std::shared_ptr<AggregationFunctionMetadata> aggregateMetadata = {};
std::shared_ptr<SqlFunctionId> functionId = {};
Copy link
Contributor

Choose a reason for hiding this comment

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

Quick question, did you create the h and cpp files by running the generator or did you manually add these lines?

Copy link
Contributor

Choose a reason for hiding this comment

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

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes. I have followed the same instructions to generate the code.

@tdcmeehan tdcmeehan force-pushed the reference_function_server branch from 36fde3a to 6ebe86c Compare January 29, 2025 20:36
@abevk2023 abevk2023 force-pushed the reference_function_server branch from 6ebe86c to 4a71933 Compare January 30, 2025 09:41
@tdcmeehan
Copy link
Contributor

It seems the [prestocpp-linux-build-engine (pull_request)](https://github.com/prestodb/presto/actions/runs/13049563626/job/36418195012?pr=23687) job has been very unlucky for this PR and consistently chooses a runner which has only 13GB of space. This causes it to run out of space.

Thanks to @czentgr who ran the same code in another branch and was able to run it on a runner which has the expected 15GB of space, proving this is not related to the code in this PR: https://github.com/prestodb/presto/actions/runs/13054091353/job/36420794542

@tdcmeehan tdcmeehan merged commit dd1893c into prestodb:master Jan 30, 2025
61 of 62 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants