Repository navigation
GH-50282: [C++][FlightRPC] Refactor gRPC server and transport classes - #50407
Conversation
|
Thanks for opening a pull request! If this is not a minor PR. Could you open an issue for this pull request on GitHub? https://github.com/apache/arrow/issues/new/choose Opening GitHub issues ahead of time contributes to the Openness of the Apache Arrow project. Then could you also rename the pull request title in the following format? or See also: |
|
|
|
@raulcd Can you launch the CI please |
|
@raulcd Can you run the CI again please? |
|
@raulcd Can you launch the CI please |
|
@raulcd Can you launch the CI please (I hope it will be the last time) |
Sorry @Alex-PLACET , I missed this comment. Just kicked it |
560bd8d to
20c2325
Compare
There was a problem hiding this comment.
Most of the code was moved from transport_server.cc
| std::vector<std::shared_ptr<ServerMiddleware>> middleware_; | ||
| std::unordered_map<std::string, std::shared_ptr<ServerMiddleware>> middleware_map_; | ||
| CallHeaders incoming_headers_; | ||
| }; |
There was a problem hiding this comment.
| // Allow uploading messages of any length | ||
| builder.SetMaxReceiveMessageSize(-1); | ||
|
|
||
| const std::string scheme = uri.scheme(); | ||
| int port = 0; | ||
| if (scheme == kSchemeGrpc || scheme == kSchemeGrpcTcp || scheme == kSchemeGrpcTls) { | ||
| std::stringstream address; | ||
| address << arrow::util::UriEncodeHost(uri.host()) << ':' << uri.port_text(); | ||
|
|
||
| std::shared_ptr<::grpc::ServerCredentials> creds; | ||
| if (scheme == kSchemeGrpcTls) { | ||
| ::grpc::SslServerCredentialsOptions ssl_options; | ||
| for (const auto& pair : options.tls_certificates) { | ||
| ssl_options.pem_key_cert_pairs.push_back({pair.pem_key, pair.pem_cert}); | ||
| } | ||
| if (options.verify_client) { | ||
| ssl_options.client_certificate_request = | ||
| GRPC_SSL_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY; | ||
| } | ||
| if (!options.root_certificates.empty()) { | ||
| ssl_options.pem_root_certs = options.root_certificates; | ||
| } | ||
| creds = ::grpc::SslServerCredentials(ssl_options); | ||
| } else { | ||
| creds = ::grpc::InsecureServerCredentials(); | ||
| } | ||
|
|
||
| builder.AddListeningPort(address.str(), creds, &port); | ||
| } else if (scheme == kSchemeGrpcUnix) { | ||
| std::stringstream address; | ||
| address << "unix:" << uri.path(); | ||
| builder.AddListeningPort(address.str(), ::grpc::InsecureServerCredentials()); | ||
| location_ = options.location; | ||
| } else { | ||
| return Status::NotImplemented("Scheme is not supported: " + scheme); | ||
| } |
There was a problem hiding this comment.
Moved to a dedicated function: AddServerListeningPort
| Status AddServerListeningPort(const FlightServerOptions& options, | ||
| const arrow::util::Uri& uri, ::grpc::ServerBuilder* builder, | ||
| Location* location, int* port) { | ||
| const std::string scheme = uri.scheme(); | ||
| if (scheme == kSchemeGrpc || scheme == kSchemeGrpcTcp || scheme == kSchemeGrpcTls) { | ||
| std::stringstream address; | ||
| address << arrow::util::UriEncodeHost(uri.host()) << ':' << uri.port_text(); | ||
|
|
||
| std::shared_ptr<::grpc::ServerCredentials> creds; | ||
| if (scheme == kSchemeGrpcTls) { | ||
| ::grpc::SslServerCredentialsOptions ssl_options; | ||
| for (const auto& pair : options.tls_certificates) { | ||
| ssl_options.pem_key_cert_pairs.push_back({pair.pem_key, pair.pem_cert}); | ||
| } | ||
| if (options.verify_client) { | ||
| ssl_options.client_certificate_request = | ||
| GRPC_SSL_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY; | ||
| } | ||
| if (!options.root_certificates.empty()) { | ||
| ssl_options.pem_root_certs = options.root_certificates; | ||
| } | ||
| creds = ::grpc::SslServerCredentials(ssl_options); | ||
| } else { | ||
| creds = ::grpc::InsecureServerCredentials(); | ||
| } | ||
| builder->AddListeningPort(address.str(), creds, port); | ||
| return Status::OK(); | ||
| } | ||
| if (scheme == kSchemeGrpcUnix) { | ||
| std::stringstream address; | ||
| address << "unix:" << uri.path(); | ||
| builder->AddListeningPort(address.str(), ::grpc::InsecureServerCredentials()); | ||
| *location = options.location; | ||
| return Status::OK(); | ||
| } | ||
| return Status::NotImplemented("Scheme is not supported: " + scheme); | ||
| } |
There was a problem hiding this comment.
Moved from grpc_server.cc
| } | ||
|
|
||
| namespace { | ||
| class TransportIpcMessageReader : public ipc::MessageReader { |
There was a problem hiding this comment.
Moved to transport_server_internal.cc
There was a problem hiding this comment.
Most of the code comes from server.cc
There was a problem hiding this comment.
Most of the code moved to grpc_server_internal cpp and h
6bafb10 to
6c2c010
Compare
raulcd
left a comment
There was a problem hiding this comment.
CI failures are unrelated. I have reviewed changes and validated the parts that have been moved around.
Thanks @Alex-PLACET for the PR LGTM.
@lidavidm can you take a look again?
@kou maybe you are interested in a quick look
kou
left a comment
There was a problem hiding this comment.
+1
Could you use "gRPC" not "GRPC" in PR title?
Is the current PR description updated? If not, could you update the PR description for the latest changes?
| /// \param[in] not_started_message Logged if shutdown is called before the server | ||
| /// starts. \param[in] shutdown_warning Logged if shutdown itself fails. | ||
| template <typename WaitFn, typename ShutdownFn> | ||
| Status Serve(WaitFn&& wait, ShutdownFn&& shutdown, const char* not_started_message, |
There was a problem hiding this comment.
It seems that not_started_message isn't used. Can we remove it?
lidavidm
left a comment
There was a problem hiding this comment.
LGTM. Thanks for working through this!
|
@kou The description is up to date now and I replaced the GRPC->gRPC in both the issue and this PR. |
raulcd
left a comment
There was a problem hiding this comment.
None of the failures are related. The two comments have been tackled. I am going to merge and if there's any follow up I am happy to tackle it.


Rationale for this change
The goal of the pullrequest is to refactor the FligtRPC code to prepare the async implementation.
What changes are included in this PR
server.cc/transport_server.ccinternals intotransport_server_internal.{h,cc}and the gRPC-specific call context, auth/middleware helper, and endpoint/builder setup intotransport/grpc/grpc_server_internal.{h,cc}, templated on the gRPC context type soServerContextandCallbackServerContextcan share one implementation.internal::ServerSignalState, fixing teardown ordering so handlers are restored even whenServe()fails early, a SIGPIPE race when waking the signal thread, and shutdown of an uninitialized server clearing another serving instance's signal target. (Github Copilot issue report)Location::uri()andLocation::port(), and includesarrow/util/uri.hfrom types.h so theResult<util::Uri>return type is instantiable by consumers of the installed header. (Github Copilot issue report in the PR)Wait()on an uninitialized server now returnsStatus::Invalidinstead of dereferencing null. No other public behavior change.ServerTransport,TransportMessageReader/Writer,WriteDataStreamand friends stay internal. (Github Copilot issue report in the PR)Are these changes tested?
Are there any user-facing changes?
Location::uri()→Result<util::Uri>,Location::port()→int(-1 when absent)types.hnow includesarrow/util/uri.h. Before,Result<util::Uri>was uninstantiable for anyone including only the installed header.Wait()on an uninitialized server returnsStatus::Invalid(was a null deref).Serve()restores prior signal handlers on failure.Shutdown()on an uninitialized server no longer disables signal shutdown for another serving instance, signal thread wake no longer risks SIGPIPE-killing the process. (Github Copilot issue report in the PR)Was AI used for this PR?
In accordance to the AI generation guidelines, please disclose below whether and how AI was used in this PR.
PR code and description written by:
Reviewed before submission by: