blob: 9cca2d6002e7ffc0d4689c87e7a1c854e49d7203 [file] [log] [blame]
Roger Meier2be7f242012-05-10 09:01:45 +00001/*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19#ifndef _THRIFT_TEST_SERVERTHREAD_H_
20#define _THRIFT_TEST_SERVERTHREAD_H_ 1
21
Roger Meier2b1a5282012-05-11 10:12:39 +000022#include <thrift/TProcessor.h>
23#include <thrift/protocol/TProtocol.h>
24#include <thrift/server/TServer.h>
25#include <thrift/transport/TTransport.h>
Roger Meier2be7f242012-05-10 09:01:45 +000026
Roger Meier2b1a5282012-05-11 10:12:39 +000027#include "EventLog.h"
Roger Meier2be7f242012-05-10 09:01:45 +000028
Konrad Grochowski16a23a62014-11-13 15:33:38 +010029namespace apache {
30namespace thrift {
31namespace test {
Roger Meier2be7f242012-05-10 09:01:45 +000032
33/**
34 * A helper class to tell ServerThread how to create the server
35 */
36class ServerState {
Konrad Grochowski16a23a62014-11-13 15:33:38 +010037public:
Sebastian Zenker042580f2019-01-29 15:48:12 +010038 virtual ~ServerState() = default;
Roger Meier2be7f242012-05-10 09:01:45 +000039
40 /**
41 * Create a server to listen on the specified port.
42 *
43 * If the server returned fails to bind to the specified port when serve() is
44 * called on it, createServer() may be called again on a different port.
45 */
cyy316723a2019-01-05 16:35:14 +080046 virtual std::shared_ptr<server::TServer> createServer(uint16_t port) = 0;
Roger Meier2be7f242012-05-10 09:01:45 +000047
48 /**
49 * Get the TServerEventHandler to set on the server.
50 *
51 * This is only called after the server successfully binds and is about to
52 * start serving traffic. It is invoked from the server thread, rather than
53 * the main thread.
54 */
cyy316723a2019-01-05 16:35:14 +080055 virtual std::shared_ptr<server::TServerEventHandler> getServerEventHandler() {
56 return std::shared_ptr<server::TServerEventHandler>();
Roger Meier2be7f242012-05-10 09:01:45 +000057 }
58
59 /**
60 * This method is called in the server thread after server binding succeeds.
61 *
62 * Subclasses may override this method if they wish to record the final
63 * port that was used for the server.
64 */
Konrad Grochowski16a23a62014-11-13 15:33:38 +010065 virtual void bindSuccessful(uint16_t /*port*/) {}
Roger Meier2be7f242012-05-10 09:01:45 +000066};
67
68/**
69 * ServerThread starts a thrift server running in a separate thread.
70 */
71class ServerThread {
Konrad Grochowski16a23a62014-11-13 15:33:38 +010072public:
cyy316723a2019-01-05 16:35:14 +080073 ServerThread(const std::shared_ptr<ServerState>& state, bool autoStart)
James E. King, III7edc8fa2017-01-20 10:11:41 -050074 : port_(0),
Roger Meier2be7f242012-05-10 09:01:45 +000075 running_(false),
76 serving_(false),
77 error_(false),
78 serverState_(state) {
79 if (autoStart) {
80 start();
81 }
82 }
83
84 void start();
85 void stop();
86
Konrad Grochowski16a23a62014-11-13 15:33:38 +010087 uint16_t getPort() const { return port_; }
Roger Meier2be7f242012-05-10 09:01:45 +000088
89 ~ServerThread() {
90 if (running_) {
91 try {
92 stop();
93 } catch (...) {
94 GlobalOutput.printf("error shutting down server");
95 }
96 }
97 }
98
Konrad Grochowski16a23a62014-11-13 15:33:38 +010099protected:
Roger Meier2be7f242012-05-10 09:01:45 +0000100 // Annoying. thrift forces us to use shared_ptr, so we have to use
101 // a helper class that we can allocate on the heap and give to thrift.
102 // It would be simpler if we could just make Runnable and TServerEventHandler
103 // private base classes of ServerThread.
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100104 class Helper : public concurrency::Runnable, public server::TServerEventHandler {
105 public:
106 Helper(ServerThread* serverThread) : serverThread_(serverThread) {}
Roger Meier2be7f242012-05-10 09:01:45 +0000107
Sebastian Zenker042580f2019-01-29 15:48:12 +0100108 void run() override { serverThread_->run(); }
Roger Meier2be7f242012-05-10 09:01:45 +0000109
Sebastian Zenker042580f2019-01-29 15:48:12 +0100110 void preServe() override { serverThread_->preServe(); }
Roger Meier2be7f242012-05-10 09:01:45 +0000111
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100112 private:
Roger Meier2be7f242012-05-10 09:01:45 +0000113 ServerThread* serverThread_;
114 };
115
116 void run();
117 void preServe();
118
cyy316723a2019-01-05 16:35:14 +0800119 std::shared_ptr<Helper> helper_;
Roger Meier2be7f242012-05-10 09:01:45 +0000120
121 uint16_t port_;
122 bool running_;
123 bool serving_;
124 bool error_;
125 concurrency::Monitor serverMonitor_;
126
cyy316723a2019-01-05 16:35:14 +0800127 std::shared_ptr<ServerState> serverState_;
128 std::shared_ptr<server::TServer> server_;
129 std::shared_ptr<concurrency::Thread> thread_;
Roger Meier2be7f242012-05-10 09:01:45 +0000130};
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100131}
132}
133} // apache::thrift::test
Roger Meier2be7f242012-05-10 09:01:45 +0000134
135#endif // _THRIFT_TEST_SERVERTHREAD_H_