/* * Copyright (c) Meta Platforms, Inc. and 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 #include #include #include #include #include #include #include #include #include #include #include #include namespace thrift { namespace python { namespace client { using RequestChannelUnique = std::unique_ptr< apache::thrift::RequestChannel, folly::DelayedDestruction::Destructor>; using RequestChannelShared = std::shared_ptr; using IOBufClientBufferedStream = apache::thrift::ClientBufferedStream; struct OmniClientResponseWithHeaders { folly::Expected, folly::exception_wrapper> buf; apache::thrift::transport::THeader::StringToStringMap headers; std::unique_ptr stream; }; /** * The Omniclient class can send requests to any Thrift service given * a RequestChannel. */ class OmniClient : public apache::thrift::TClientBase { public: explicit OmniClient(RequestChannelUnique channel); explicit OmniClient(RequestChannelShared channel); explicit OmniClient(OmniClient&&) noexcept; ~OmniClient() override; OmniClientResponseWithHeaders sync_send( const std::string& serviceName, const std::string& functionName, std::unique_ptr args, apache::thrift::MethodMetadata::Data&& metadata, const std::unordered_map& headers, apache::thrift::RpcOptions&& rpcOptions); OmniClientResponseWithHeaders sync_send( const std::string& serviceName, const std::string& functionName, const std::string& args, apache::thrift::MethodMetadata::Data&& metadata, const std::unordered_map& headers, apache::thrift::RpcOptions&& rpcOptions); void oneway_send( const std::string& serviceName, const std::string& functionName, std::unique_ptr args, apache::thrift::MethodMetadata::Data&& metadata, const std::unordered_map& headers, apache::thrift::RpcOptions&& rpcOptions); void oneway_send( const std::string& serviceName, const std::string& functionName, const std::string& args, apache::thrift::MethodMetadata::Data&& metadata, const std::unordered_map& headers, apache::thrift::RpcOptions&& rpcOptions); /** * The semifuture_send function takes in a function name and its arguments * encoded in channel protocol, and sends back the raw response with headers, * wrapped in a folly::SemiFuture. */ folly::SemiFuture semifuture_send( const std::string& serviceName, const std::string& functionName, std::unique_ptr args, apache::thrift::MethodMetadata::Data&& metadata, const std::unordered_map& headers, apache::thrift::RpcOptions&& rpcOptions, folly::Executor* executor, const apache::thrift::RpcKind rpcKind = apache::thrift::RpcKind::SINGLE_REQUEST_SINGLE_RESPONSE); folly::SemiFuture semifuture_send( const std::string& serviceName, const std::string& functionName, const std::string& args, apache::thrift::MethodMetadata::Data&& metadata, const std::unordered_map& headers, apache::thrift::RpcOptions&& rpcOptions, folly::Executor* executor, const apache::thrift::RpcKind rpcKind = apache::thrift::RpcKind::SINGLE_REQUEST_SINGLE_RESPONSE); uint16_t getChannelProtocolId() const noexcept; RequestChannelShared getChannelShared() const noexcept; // TODO(ffrancet): get rid of in favour of calling setInteraction once we've // implemented client RPCOptions void set_interaction_factory(OmniClient* client); protected: // RpcOptions unused in base OmniClient since no interaction support virtual void setInteraction(apache::thrift::RpcOptions& rpcOptions); RequestChannelShared channel_ = nullptr; std::atomic factoryClient_ = nullptr; private: /** * Sends the request to the Thrift service through the RequestChannel. */ void sendImpl( apache::thrift::RpcOptions&& rpcOptions, std::unique_ptr args, const std::string& serviceName, const std::string& functionName, std::unique_ptr callback, const apache::thrift::RpcKind rpcKind, apache::thrift::MethodMetadata::Data&& metadata); }; inline uint16_t OmniClient::getChannelProtocolId() const noexcept { return channel_->getProtocolId(); } inline RequestChannelShared OmniClient::getChannelShared() const noexcept { return channel_; } inline void OmniClient::set_interaction_factory(OmniClient* client) { // What happens if its nullptr factoryClient_ = client; } class OmniInteractionClient : public OmniClient { public: OmniInteractionClient( std::shared_ptr channel, const std::string& methodName); OmniInteractionClient(OmniInteractionClient&&) noexcept = default; OmniInteractionClient& operator=(OmniInteractionClient&&); ~OmniInteractionClient() override; protected: void setInteraction(apache::thrift::RpcOptions& rpcOptions) override; private: void terminate(); std::string methodName_; apache::thrift::InteractionId interactionId_; friend class OmniClient; }; folly::Future> createOmniInteractionClient( std::shared_ptr channel, const std::string& methodName); } // namespace client } // namespace python } // namespace thrift