]>
Commit | Line | Data |
---|---|---|
f67539c2 TL |
1 | /* |
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 | ||
20 | #include <thrift/concurrency/ThreadManager.h> | |
21 | #include <thrift/concurrency/ThreadFactory.h> | |
22 | #include <thrift/protocol/TBinaryProtocol.h> | |
23 | #include <thrift/server/TSimpleServer.h> | |
24 | #include <thrift/server/TThreadPoolServer.h> | |
25 | #include <thrift/server/TThreadedServer.h> | |
26 | #include <thrift/transport/TServerSocket.h> | |
27 | #include <thrift/transport/TSocket.h> | |
28 | #include <thrift/transport/TTransportUtils.h> | |
29 | #include <thrift/TToString.h> | |
30 | ||
31 | #include <iostream> | |
32 | #include <stdexcept> | |
33 | #include <sstream> | |
34 | ||
35 | #include "../gen-cpp/Calculator.h" | |
36 | ||
37 | using namespace std; | |
38 | using namespace apache::thrift; | |
39 | using namespace apache::thrift::concurrency; | |
40 | using namespace apache::thrift::protocol; | |
41 | using namespace apache::thrift::transport; | |
42 | using namespace apache::thrift::server; | |
43 | ||
44 | using namespace tutorial; | |
45 | using namespace shared; | |
46 | ||
47 | class CalculatorHandler : public CalculatorIf { | |
48 | public: | |
49 | CalculatorHandler() = default; | |
50 | ||
51 | void ping() override { cout << "ping()" << endl; } | |
52 | ||
53 | int32_t add(const int32_t n1, const int32_t n2) override { | |
54 | cout << "add(" << n1 << ", " << n2 << ")" << endl; | |
55 | return n1 + n2; | |
56 | } | |
57 | ||
58 | int32_t calculate(const int32_t logid, const Work& work) override { | |
59 | cout << "calculate(" << logid << ", " << work << ")" << endl; | |
60 | int32_t val; | |
61 | ||
62 | switch (work.op) { | |
63 | case Operation::ADD: | |
64 | val = work.num1 + work.num2; | |
65 | break; | |
66 | case Operation::SUBTRACT: | |
67 | val = work.num1 - work.num2; | |
68 | break; | |
69 | case Operation::MULTIPLY: | |
70 | val = work.num1 * work.num2; | |
71 | break; | |
72 | case Operation::DIVIDE: | |
73 | if (work.num2 == 0) { | |
74 | InvalidOperation io; | |
75 | io.whatOp = work.op; | |
76 | io.why = "Cannot divide by 0"; | |
77 | throw io; | |
78 | } | |
79 | val = work.num1 / work.num2; | |
80 | break; | |
81 | default: | |
82 | InvalidOperation io; | |
83 | io.whatOp = work.op; | |
84 | io.why = "Invalid Operation"; | |
85 | throw io; | |
86 | } | |
87 | ||
88 | SharedStruct ss; | |
89 | ss.key = logid; | |
90 | ss.value = to_string(val); | |
91 | ||
92 | log[logid] = ss; | |
93 | ||
94 | return val; | |
95 | } | |
96 | ||
97 | void getStruct(SharedStruct& ret, const int32_t logid) override { | |
98 | cout << "getStruct(" << logid << ")" << endl; | |
99 | ret = log[logid]; | |
100 | } | |
101 | ||
102 | void zip() override { cout << "zip()" << endl; } | |
103 | ||
104 | protected: | |
105 | map<int32_t, SharedStruct> log; | |
106 | }; | |
107 | ||
108 | /* | |
109 | CalculatorIfFactory is code generated. | |
110 | CalculatorCloneFactory is useful for getting access to the server side of the | |
111 | transport. It is also useful for making per-connection state. Without this | |
112 | CloneFactory, all connections will end up sharing the same handler instance. | |
113 | */ | |
114 | class CalculatorCloneFactory : virtual public CalculatorIfFactory { | |
115 | public: | |
116 | ~CalculatorCloneFactory() override = default; | |
117 | CalculatorIf* getHandler(const ::apache::thrift::TConnectionInfo& connInfo) override | |
118 | { | |
119 | std::shared_ptr<TSocket> sock = std::dynamic_pointer_cast<TSocket>(connInfo.transport); | |
120 | cout << "Incoming connection\n"; | |
121 | cout << "\tSocketInfo: " << sock->getSocketInfo() << "\n"; | |
122 | cout << "\tPeerHost: " << sock->getPeerHost() << "\n"; | |
123 | cout << "\tPeerAddress: " << sock->getPeerAddress() << "\n"; | |
124 | cout << "\tPeerPort: " << sock->getPeerPort() << "\n"; | |
125 | return new CalculatorHandler; | |
126 | } | |
127 | void releaseHandler( ::shared::SharedServiceIf* handler) override { | |
128 | delete handler; | |
129 | } | |
130 | }; | |
131 | ||
132 | int main() { | |
133 | TThreadedServer server( | |
134 | std::make_shared<CalculatorProcessorFactory>(std::make_shared<CalculatorCloneFactory>()), | |
135 | std::make_shared<TServerSocket>(9090), //port | |
136 | std::make_shared<TBufferedTransportFactory>(), | |
137 | std::make_shared<TBinaryProtocolFactory>()); | |
138 | ||
139 | /* | |
140 | // if you don't need per-connection state, do the following instead | |
141 | TThreadedServer server( | |
142 | std::make_shared<CalculatorProcessor>(std::make_shared<CalculatorHandler>()), | |
143 | std::make_shared<TServerSocket>(9090), //port | |
144 | std::make_shared<TBufferedTransportFactory>(), | |
145 | std::make_shared<TBinaryProtocolFactory>()); | |
146 | */ | |
147 | ||
148 | /** | |
149 | * Here are some alternate server types... | |
150 | ||
151 | // This server only allows one connection at a time, but spawns no threads | |
152 | TSimpleServer server( | |
153 | std::make_shared<CalculatorProcessor>(std::make_shared<CalculatorHandler>()), | |
154 | std::make_shared<TServerSocket>(9090), | |
155 | std::make_shared<TBufferedTransportFactory>(), | |
156 | std::make_shared<TBinaryProtocolFactory>()); | |
157 | ||
158 | const int workerCount = 4; | |
159 | ||
160 | std::shared_ptr<ThreadManager> threadManager = | |
161 | ThreadManager::newSimpleThreadManager(workerCount); | |
162 | threadManager->threadFactory( | |
163 | std::make_shared<ThreadFactory>()); | |
164 | threadManager->start(); | |
165 | ||
166 | // This server allows "workerCount" connection at a time, and reuses threads | |
167 | TThreadPoolServer server( | |
168 | std::make_shared<CalculatorProcessorFactory>(std::make_shared<CalculatorCloneFactory>()), | |
169 | std::make_shared<TServerSocket>(9090), | |
170 | std::make_shared<TBufferedTransportFactory>(), | |
171 | std::make_shared<TBinaryProtocolFactory>(), | |
172 | threadManager); | |
173 | */ | |
174 | ||
175 | cout << "Starting the server..." << endl; | |
176 | server.serve(); | |
177 | cout << "Done." << endl; | |
178 | return 0; | |
179 | } |