// 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 "rsocket/RSocket.h" namespace rsocket { folly::Future> RSocket::createConnectedClient( std::shared_ptr connectionFactory, SetupParameters setupParameters, std::shared_ptr responder, std::chrono::milliseconds keepaliveInterval, std::shared_ptr stats, std::shared_ptr connectionEvents, std::shared_ptr resumeManager, std::shared_ptr coldResumeHandler, folly::EventBase* stateMachineEvb) { CHECK(resumeManager) << "provide ResumeManager::makeEmpty() instead of nullptr"; auto protocolVersion = setupParameters.protocolVersion; auto createRSC = [connectionFactory, setupParameters = std::move(setupParameters), responder = std::move(responder), keepaliveInterval, stats = std::move(stats), connectionEvents = std::move(connectionEvents), resumeManager = std::move(resumeManager), coldResumeHandler = std::move(coldResumeHandler), stateMachineEvb]( ConnectionFactory::ConnectedDuplexConnection connection) mutable { VLOG(3) << "createConnectedClient received DuplexConnection"; return RSocket::createClientFromConnection( std::move(connection.connection), connection.eventBase, std::move(setupParameters), std::move(connectionFactory), std::move(responder), keepaliveInterval, std::move(stats), std::move(connectionEvents), std::move(resumeManager), std::move(coldResumeHandler), stateMachineEvb); }; return connectionFactory->connect(protocolVersion, ResumeStatus::NEW_SESSION) .thenValue( [createRSC = std::move(createRSC)]( ConnectionFactory::ConnectedDuplexConnection connection) mutable { // fromConnection method must be called from the transport eventBase // and since there is no guarantee that the Future returned from the // connectionFactory::connect method is executed on the event base, // we have to ensure it by using folly::via auto transportEvb = &connection.eventBase; return folly::via( transportEvb, [connection = std::move(connection), createRSC = std::move(createRSC)]() mutable { return createRSC(std::move(connection)); }); }); } folly::Future> RSocket::createResumedClient( std::shared_ptr connectionFactory, ResumeIdentificationToken token, std::shared_ptr resumeManager, std::shared_ptr coldResumeHandler, std::shared_ptr responder, std::chrono::milliseconds keepaliveInterval, std::shared_ptr stats, std::shared_ptr connectionEvents, ProtocolVersion protocolVersion, folly::EventBase* stateMachineEvb) { auto* c = new RSocketClient( std::move(connectionFactory), std::move(protocolVersion), std::move(token), std::move(responder), keepaliveInterval, std::move(stats), std::move(connectionEvents), std::move(resumeManager), std::move(coldResumeHandler), stateMachineEvb); return c->resume().thenValue( [client = std::unique_ptr(c)](auto&&) mutable { return std::move(client); }); } std::unique_ptr RSocket::createClientFromConnection( std::unique_ptr connection, folly::EventBase& transportEvb, SetupParameters params, std::shared_ptr connectionFactory, std::shared_ptr responder, std::chrono::milliseconds keepaliveInterval, std::shared_ptr stats, std::shared_ptr connectionEvents, std::shared_ptr resumeManager, std::shared_ptr coldResumeHandler, folly::EventBase* stateMachineEvb) { auto client = std::unique_ptr(new RSocketClient( std::move(connectionFactory), params.protocolVersion, params.token, std::move(responder), keepaliveInterval, std::move(stats), std::move(connectionEvents), std::move(resumeManager), std::move(coldResumeHandler), stateMachineEvb)); client->fromConnection( std::move(connection), transportEvb, std::move(params)); return client; } std::unique_ptr RSocket::createServer( std::unique_ptr connectionAcceptor, std::shared_ptr stats) { return std::make_unique( std::move(connectionAcceptor), std::move(stats)); } } // namespace rsocket