2 * Copyright 2015 Facebook, Inc.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
18 #include <folly/futures/Future.h>
19 #include <folly/Memory.h>
21 #include <folly/wangle/bootstrap/ServerBootstrap.h>
22 #include <folly/wangle/bootstrap/ClientBootstrap.h>
23 #include <folly/wangle/channel/Pipeline.h>
24 #include <folly/wangle/channel/AsyncSocketHandler.h>
29 * A Service is an asynchronous function from Request to
30 * Future<Response>. It is the basic unit of the RPC interface.
32 template <typename Req, typename Resp = Req>
35 virtual Future<Resp> operator()(Req request) = 0;
37 virtual Future<void> close() {
40 virtual bool isAvailable() {
46 * A Filter acts as a decorator/transformer of a service. It may apply
47 * transformations to the input and output of that service:
56 * For example, you may have a service that takes Strings and parses
57 * them as Ints. If you want to expose this as a Network Service via
58 * Thrift, it is nice to isolate the protocol handling from the
59 * business rules. Hence you might have a Filter that converts back
60 * and forth between Thrift structs:
62 * [ThriftIn -> (String -> Int) -> ThriftOut]
64 template <typename ReqA, typename RespA,
65 typename ReqB = ReqA, typename RespB = RespA>
66 class ServiceFilter : public Service<ReqA, RespA> {
68 explicit ServiceFilter(std::shared_ptr<Service<ReqB, RespB>> service)
69 : service_(service) {}
70 virtual ~ServiceFilter() {}
72 virtual Future<void> close() override {
73 return service_->close();
76 virtual bool isAvailable() override {
77 return service_->isAvailable();
81 std::shared_ptr<Service<ReqB, RespB>> service_;
85 * A factory that creates services, given a client. This lets you
86 * make RPC calls on the Service interface over a client's pipeline.
88 * Clients can be reused after you are done using the service.
90 template <typename Pipeline, typename Req, typename Resp>
91 class ServiceFactory {
93 virtual Future<std::shared_ptr<Service<Req, Resp>>> operator()(
94 std::shared_ptr<ClientBootstrap<Pipeline>> client) = 0;
96 virtual ~ServiceFactory() = default;
101 template <typename Pipeline, typename Req, typename Resp>
102 class ConstFactory : public ServiceFactory<Pipeline, Req, Resp> {
104 explicit ConstFactory(std::shared_ptr<Service<Req, Resp>> service)
105 : service_(service) {}
107 virtual Future<std::shared_ptr<Service<Req, Resp>>> operator()(
108 std::shared_ptr<ClientBootstrap<Pipeline>> client) {
112 std::shared_ptr<Service<Req, Resp>> service_;
115 template <typename Pipeline, typename ReqA, typename RespA,
116 typename ReqB = ReqA, typename RespB = RespA>
117 class ServiceFactoryFilter : public ServiceFactory<Pipeline, ReqA, RespA> {
119 explicit ServiceFactoryFilter(
120 std::shared_ptr<ServiceFactory<Pipeline, ReqB, RespB>> serviceFactory)
121 : serviceFactory_(std::move(serviceFactory)) {}
123 virtual ~ServiceFactoryFilter() = default;
126 std::shared_ptr<ServiceFactory<Pipeline, ReqB, RespB>> serviceFactory_;
129 template <typename Pipeline, typename Req, typename Resp = Req>
130 class FactoryToService : public Service<Req, Resp> {
132 explicit FactoryToService(
133 std::shared_ptr<ServiceFactory<Pipeline, Req, Resp>> factory)
134 : factory_(factory) {}
135 virtual ~FactoryToService() {}
137 virtual Future<Resp> operator()(Req request) override {
139 return ((*factory_)(nullptr)).then(
140 [=](std::shared_ptr<Service<Req, Resp>> service)
142 return (*service)(std::move(request)).ensure(
150 std::shared_ptr<ServiceFactory<Pipeline, Req, Resp>> factory_;