proxygen
ClientDispatcher.h
Go to the documentation of this file.
1 /*
2  * Copyright 2017-present Facebook, Inc.
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16 
17 #pragma once
18 
19 #include <wangle/channel/Handler.h>
20 #include <wangle/service/Service.h>
21 
22 namespace wangle {
23 
24 template <typename Pipeline, typename Req, typename Resp = Req>
25 class ClientDispatcherBase : public HandlerAdapter<Resp, Req>
26  , public Service<Req, Resp> {
27  public:
29 
30  ~ClientDispatcherBase() override {
31  if (pipeline_) {
32  try {
33  pipeline_->remove(this).finalize();
34  } catch (const std::invalid_argument& e) {
35  // not in pipeline; this is fine
36  }
37  }
38  }
39 
40  void setPipeline(Pipeline* pipeline) {
41  try {
42  pipeline->template remove<ClientDispatcherBase>();
43  } catch (const std::invalid_argument& e) {
44  // no existing dispatcher; this is fine
45  }
46  pipeline_ = pipeline;
47  pipeline_->addBack(this);
49  }
50 
53  }
54 
55  folly::Future<folly::Unit> close(Context* ctx) override {
57  }
58 
59  protected:
60  Pipeline* pipeline_{nullptr};
61 };
62 
68 template <typename Pipeline, typename Req, typename Resp = Req>
70  : public ClientDispatcherBase<Pipeline, Req, Resp> {
71  public:
73 
74  void read(Context*, Resp in) override {
75  DCHECK(p_);
76  p_->setValue(std::move(in));
77  p_ = folly::none;
78  }
79 
81  CHECK(!p_);
82  DCHECK(this->pipeline_);
83 
84  p_ = folly::Promise<Resp>();
85  auto f = p_->getFuture();
86  this->pipeline_->write(std::move(arg));
87  return f;
88  }
89 
90  private:
92 };
93 
99 template <typename Pipeline, typename Req, typename Resp = Req>
101  : public ClientDispatcherBase<Pipeline, Req, Resp> {
102  public:
103 
105 
106  void read(Context*, Resp in) override {
107  DCHECK(p_.size() >= 1);
108  auto p = std::move(p_.front());
109  p_.pop_front();
110  p.setValue(std::move(in));
111  }
112 
114  DCHECK(this->pipeline_);
115 
117  auto f = p.getFuture();
118  p_.push_back(std::move(p));
119  this->pipeline_->write(std::move(arg));
120  return f;
121  }
122 
123  private:
124  std::deque<folly::Promise<Resp>> p_;
125 };
126 
127 /*
128  * A full out-of-order request/response client would require some sort
129  * of sequence id on the wire. Currently this is left up to
130  * individual protocol writers to implement.
131  */
132 
133 } // namespace wangle
auto f
void read(Context *, Resp in) override
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
folly::Optional< folly::Promise< Resp > > p_
HandlerContext< Resp, Req > * getContext()
Definition: Handler.h:34
std::enable_if<!std::is_same< T, folly::Unit >::value, folly::Future< folly::Unit > >::type write(W msg)
Definition: Pipeline-inl.h:235
HandlerAdapter< Resp, Req >::Context Context
void setPipeline(Pipeline *pipeline)
HandlerAdapter< Resp, Req >::Context Context
PipelineBase & addBack(std::shared_ptr< H > handler)
Definition: Pipeline-inl.h:39
Future< T > getFuture()
Definition: Promise-inl.h:97
virtual folly::Future< folly::Unit > close(Context *ctx)
Definition: Handler.h:79
PipelineBase & remove(H *handler)
Definition: Pipeline-inl.h:103
folly::Future< folly::Unit > close() override
folly::Future< Resp > operator()(Req arg) override
folly::Future< folly::Unit > close(Context *ctx) override
folly::Future< Resp > operator()(Req arg) override
void read(Context *, Resp in) override
virtual void finalize()=0
void finalize() override
Definition: Pipeline-inl.h:267
std::deque< folly::Promise< Resp > > p_
constexpr None none
Definition: Optional.h:87
HandlerAdapter< Resp, Req >::Context Context