TensorFlow Serving C++ API Documentation
httpserver_interface.h
1 /* Copyright 2018 Google Inc. All Rights Reserved.
2 
3 Licensed under the Apache License, Version 2.0 (the "License");
4 you may not use this file except in compliance with the License.
5 You may obtain a copy of the License at
6 
7  http://www.apache.org/licenses/LICENSE-2.0
8 
9 Unless required by applicable law or agreed to in writing, software
10 distributed under the License is distributed on an "AS IS" BASIS,
11 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 See the License for the specific language governing permissions and
13 limitations under the License.
14 ==============================================================================*/
15 
16 // APIs for the HTTP server.
17 
18 #ifndef TENSORFLOW_SERVING_UTIL_NET_HTTP_SERVER_PUBLIC_HTTPSERVER_INTERFACE_H_
19 #define TENSORFLOW_SERVING_UTIL_NET_HTTP_SERVER_PUBLIC_HTTPSERVER_INTERFACE_H_
20 
21 #include <cassert>
22 
23 #include <functional>
24 #include <memory>
25 #include <vector>
26 
27 #include "absl/strings/string_view.h"
28 #include "absl/time/time.h"
29 
30 #include "tensorflow_serving/util/net_http/server/public/server_request_interface.h"
31 
32 namespace tensorflow {
33 namespace serving {
34 namespace net_http {
35 
36 // A non-blocking executor for processing I/O polling or callback events.
37 // TODO: move EventExecutor into ServerOptions
39  public:
40  virtual ~EventExecutor() = default;
41 
42  EventExecutor(const EventExecutor& other) = delete;
43  EventExecutor& operator=(const EventExecutor& other) = delete;
44 
45  // Schedule the specified 'fn' for execution in this executor.
46  // Must be non-blocking
47  virtual void Schedule(std::function<void()> fn) = 0;
48 
49  protected:
50  EventExecutor() = default;
51 };
52 
53 // Options to specify when a server instance is created.
55  public:
56  ServerOptions() = default;
57 
58  // At least one port has to be configured.
59  // Port 0 will start the server using an ephemeral port.
60  void AddPort(int port) {
61  assert(port >= 0);
62  ports_.emplace_back(port);
63  }
64 
65  // The default executor for running I/O event polling.
66  // This is a mandatory option.
67  void SetExecutor(std::unique_ptr<EventExecutor> executor) {
68  executor_ = std::move(executor);
69  }
70 
71  const std::vector<int>& ports() const { return ports_; }
72 
73  EventExecutor* executor() const { return executor_.get(); }
74 
75  private:
76  std::vector<int> ports_;
77  std::unique_ptr<EventExecutor> executor_;
78 };
79 
80 // Options to specify when registering a handler (given a uri pattern).
81 // This should be a value type.
83  public:
84  RequestHandlerOptions() = default;
85 
87  RequestHandlerOptions& operator=(const RequestHandlerOptions&) = default;
88 
89  // Sets the max length of uncompressed data when uncompressing a request body
90  inline RequestHandlerOptions& set_auto_uncompress_max_size(int64_t size) {
91  auto_uncompress_max_size_ = size;
92  return *this;
93  }
94 
95  // The max length of uncompressed data when doing uncompress. Returns 0 if
96  // not set. See Zlib::kMaxUncompressedBytes for the default config.
97  inline int64_t auto_uncompress_max_size() const {
98  return auto_uncompress_max_size_;
99  }
100 
101  // The auto_uncompress_input option specifies whether the request
102  // input data should be uncompressed if the request has the
103  // Content-Encoding: .*gzip.* header. The option defaults to true.
104  inline RequestHandlerOptions& set_auto_uncompress_input(
105  bool should_uncompress) {
106  auto_uncompress_input_ = should_uncompress;
107  return *this;
108  }
109 
110  inline bool auto_uncompress_input() const { return auto_uncompress_input_; }
111 
112  private:
113  // To be added: compression, CORS rules, streaming control
114  // thread executor, admission control, limits ...
115 
116  bool auto_uncompress_input_ = true;
117 
118  int64_t auto_uncompress_max_size_ = 0;
119 };
120 
121 // A request handler is registered by the application to handle a request
122 // based on the request Uri path, available via ServerRequestInterface.
123 //
124 // Request handlers need be completely non-blocking. And handlers may add
125 // callbacks to a thread-pool that is managed by the application itself.
126 typedef std::function<void(ServerRequestInterface*)> RequestHandler;
127 
128 // Returns a nullptr if the request is not handled by this dispatcher.
129 typedef std::function<RequestHandler(ServerRequestInterface*)>
130  RequestDispatcher;
131 
132 // This interface class specifies the API contract for the HTTP server.
133 //
134 // Requirements for implementations:
135 // - must be thread-safe
136 // - multiple HTTP server instances need be supported in a single process
137 // - for a basic implementation, the application needs provide a dedicated
138 // thread to handle all I/O events, i.e. the thread that calls
139 // StartAcceptingRequests().
140 // - the arrival order of concurrent requests is insignificant because the
141 // server runtime and I/O are completely event-driven.
143  public:
144  virtual ~HTTPServerInterface() = default;
145 
146  HTTPServerInterface(const HTTPServerInterface& other) = delete;
147  HTTPServerInterface& operator=(const HTTPServerInterface& other) = delete;
148 
149  // Starts to accept requests arrived on the network.
150  // Returns false if the server runtime fails to initialize properly.
151  virtual bool StartAcceptingRequests() = 0;
152 
153  // Returns true if StartAcceptingRequests() has been called.
154  virtual bool is_accepting_requests() const = 0;
155 
156  // Returns the server listener port if any, or else returns 0.
157  virtual int listen_port() const = 0;
158 
159  // Starts the server termination, and returns immediately.
160  virtual void Terminate() = 0;
161 
162  // Returns true if Terminate() has been called.
163  virtual bool is_terminating() const = 0;
164 
165  // Blocks the calling thread until the server is terminated and safe
166  // to destroy.
167  virtual void WaitForTermination() = 0;
168 
169  // Blocks the calling thread until the server is terminated and safe
170  // to destroy, or until the specified timeout elapses. Returns true
171  // if safe termination completed within the timeout, and false otherwise.
172  virtual bool WaitForTerminationWithTimeout(absl::Duration timeout) = 0;
173 
174  // To be specified: lameduck
175 
176  // Registers a request handler with exact URI path matching.
177  // Any existing handler under the same uri will be overwritten.
178  // The server owns the handler after registration.
179  // Handlers may be registered after the server has been started.
180  virtual void RegisterRequestHandler(absl::string_view uri,
181  RequestHandler handler,
182  const RequestHandlerOptions& options) = 0;
183 
184  // Registers a request dispatcher, i.e. application-provided URI dispatching
185  // logic, e.g. a regexp based one.
186  //
187  // For a given request, dispatchers are only invoked if there is no exact URI
188  // path matching to any registered request handler.
189  //
190  // Dispatchers are invoked in order of registration, i.e. first registered
191  // gets first pick. The server owns the dispatcher after registration.
192  // Dispatchers may be registered after the server has been started.
193  virtual void RegisterRequestDispatcher(
194  RequestDispatcher dispatcher, const RequestHandlerOptions& options) = 0;
195 
196  // To be added: unregister (if needed)
197 
198  protected:
199  HTTPServerInterface() = default;
200 };
201 
202 } // namespace net_http
203 } // namespace serving
204 } // namespace tensorflow
205 
206 #endif // TENSORFLOW_SERVING_UTIL_NET_HTTP_SERVER_PUBLIC_HTTPSERVER_INTERFACE_H_