]>
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/server/TConnectedClient.h> | |
21 | ||
22 | namespace apache { | |
23 | namespace thrift { | |
24 | namespace server { | |
25 | ||
26 | using apache::thrift::TProcessor; | |
27 | using apache::thrift::protocol::TProtocol; | |
28 | using apache::thrift::server::TServerEventHandler; | |
29 | using apache::thrift::transport::TTransport; | |
30 | using apache::thrift::transport::TTransportException; | |
31 | using std::shared_ptr; | |
32 | using std::string; | |
33 | ||
34 | TConnectedClient::TConnectedClient(const shared_ptr<TProcessor>& processor, | |
35 | const shared_ptr<TProtocol>& inputProtocol, | |
36 | const shared_ptr<TProtocol>& outputProtocol, | |
37 | const shared_ptr<TServerEventHandler>& eventHandler, | |
38 | const shared_ptr<TTransport>& client) | |
39 | ||
40 | : processor_(processor), | |
41 | inputProtocol_(inputProtocol), | |
42 | outputProtocol_(outputProtocol), | |
43 | eventHandler_(eventHandler), | |
44 | client_(client), | |
45 | opaqueContext_(nullptr) { | |
46 | } | |
47 | ||
48 | TConnectedClient::~TConnectedClient() = default; | |
49 | ||
50 | void TConnectedClient::run() { | |
51 | if (eventHandler_) { | |
52 | opaqueContext_ = eventHandler_->createContext(inputProtocol_, outputProtocol_); | |
53 | } | |
54 | ||
55 | for (bool done = false; !done;) { | |
56 | if (eventHandler_) { | |
57 | eventHandler_->processContext(opaqueContext_, client_); | |
58 | } | |
59 | ||
60 | try { | |
61 | if (!processor_->process(inputProtocol_, outputProtocol_, opaqueContext_)) { | |
62 | break; | |
63 | } | |
64 | } catch (const TTransportException& ttx) { | |
65 | switch (ttx.getType()) { | |
66 | case TTransportException::END_OF_FILE: | |
67 | case TTransportException::INTERRUPTED: | |
68 | case TTransportException::TIMED_OUT: | |
69 | // Client disconnected or was interrupted or did not respond within the receive timeout. | |
70 | // No logging needed. Done. | |
71 | done = true; | |
72 | break; | |
73 | ||
74 | default: { | |
75 | // All other transport exceptions are logged. | |
76 | // State of connection is unknown. Done. | |
77 | string errStr = string("TConnectedClient died: ") + ttx.what(); | |
78 | GlobalOutput(errStr.c_str()); | |
79 | done = true; | |
80 | break; | |
81 | } | |
82 | } | |
83 | } catch (const TException& tex) { | |
84 | string errStr = string("TConnectedClient processing exception: ") + tex.what(); | |
85 | GlobalOutput(errStr.c_str()); | |
86 | // Disconnect from client, because we could not process the message. | |
87 | done = true; | |
88 | } | |
89 | } | |
90 | ||
91 | cleanup(); | |
92 | } | |
93 | ||
94 | void TConnectedClient::cleanup() { | |
95 | if (eventHandler_) { | |
96 | eventHandler_->deleteContext(opaqueContext_, inputProtocol_, outputProtocol_); | |
97 | } | |
98 | ||
99 | try { | |
100 | inputProtocol_->getTransport()->close(); | |
101 | } catch (const TTransportException& ttx) { | |
102 | string errStr = string("TConnectedClient input close failed: ") + ttx.what(); | |
103 | GlobalOutput(errStr.c_str()); | |
104 | } | |
105 | ||
106 | try { | |
107 | outputProtocol_->getTransport()->close(); | |
108 | } catch (const TTransportException& ttx) { | |
109 | string errStr = string("TConnectedClient output close failed: ") + ttx.what(); | |
110 | GlobalOutput(errStr.c_str()); | |
111 | } | |
112 | ||
113 | try { | |
114 | client_->close(); | |
115 | } catch (const TTransportException& ttx) { | |
116 | string errStr = string("TConnectedClient client close failed: ") + ttx.what(); | |
117 | GlobalOutput(errStr.c_str()); | |
118 | } | |
119 | } | |
120 | } | |
121 | } | |
122 | } // apache::thrift::server |