]>
Commit | Line | Data |
---|---|---|
f67539c2 TL |
1 | // Licensed to the Apache Software Foundation (ASF) under one |
2 | // or more contributor license agreements. See the NOTICE file | |
3 | // distributed with this work for additional information | |
4 | // regarding copyright ownership. The ASF licenses this file | |
5 | // to you under the Apache License, Version 2.0 (the | |
6 | // "License"); you may not use this file except in compliance | |
7 | // with the License. You may obtain a copy of the License at | |
8 | // | |
9 | // http://www.apache.org/licenses/LICENSE-2.0 | |
10 | // | |
11 | // Unless required by applicable law or agreed to in writing, | |
12 | // software distributed under the License is distributed on an | |
13 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | |
14 | // KIND, either express or implied. See the License for the | |
15 | // specific language governing permissions and limitations | |
16 | // under the License. | |
17 | ||
18 | //! Types used to implement a Thrift server. | |
19 | ||
20 | use protocol::{TInputProtocol, TMessageIdentifier, TMessageType, TOutputProtocol}; | |
21 | use {ApplicationError, ApplicationErrorKind}; | |
22 | ||
23 | mod multiplexed; | |
24 | mod threaded; | |
25 | ||
26 | pub use self::multiplexed::TMultiplexedProcessor; | |
27 | pub use self::threaded::TServer; | |
28 | ||
29 | /// Handles incoming Thrift messages and dispatches them to the user-defined | |
30 | /// handler functions. | |
31 | /// | |
32 | /// An implementation is auto-generated for each Thrift service. When used by a | |
33 | /// server (for example, a `TSimpleServer`), it will demux incoming service | |
34 | /// calls and invoke the corresponding user-defined handler function. | |
35 | /// | |
36 | /// # Examples | |
37 | /// | |
38 | /// Create and start a server using the auto-generated `TProcessor` for | |
39 | /// a Thrift service `SimpleService`. | |
40 | /// | |
41 | /// ```no_run | |
42 | /// use thrift::protocol::{TInputProtocol, TOutputProtocol}; | |
43 | /// use thrift::server::TProcessor; | |
44 | /// | |
45 | /// // | |
46 | /// // auto-generated | |
47 | /// // | |
48 | /// | |
49 | /// // processor for `SimpleService` | |
50 | /// struct SimpleServiceSyncProcessor; | |
51 | /// impl SimpleServiceSyncProcessor { | |
52 | /// fn new<H: SimpleServiceSyncHandler>(processor: H) -> SimpleServiceSyncProcessor { | |
53 | /// unimplemented!(); | |
54 | /// } | |
55 | /// } | |
56 | /// | |
57 | /// // `TProcessor` implementation for `SimpleService` | |
58 | /// impl TProcessor for SimpleServiceSyncProcessor { | |
59 | /// fn process(&self, i: &mut TInputProtocol, o: &mut TOutputProtocol) -> thrift::Result<()> { | |
60 | /// unimplemented!(); | |
61 | /// } | |
62 | /// } | |
63 | /// | |
64 | /// // service functions for SimpleService | |
65 | /// trait SimpleServiceSyncHandler { | |
66 | /// fn service_call(&self) -> thrift::Result<()>; | |
67 | /// } | |
68 | /// | |
69 | /// // | |
70 | /// // user-code follows | |
71 | /// // | |
72 | /// | |
73 | /// // define a handler that will be invoked when `service_call` is received | |
74 | /// struct SimpleServiceHandlerImpl; | |
75 | /// impl SimpleServiceSyncHandler for SimpleServiceHandlerImpl { | |
76 | /// fn service_call(&self) -> thrift::Result<()> { | |
77 | /// unimplemented!(); | |
78 | /// } | |
79 | /// } | |
80 | /// | |
81 | /// // instantiate the processor | |
82 | /// let processor = SimpleServiceSyncProcessor::new(SimpleServiceHandlerImpl {}); | |
83 | /// | |
84 | /// // at this point you can pass the processor to the server | |
85 | /// // let server = TServer::new(..., processor); | |
86 | /// ``` | |
87 | pub trait TProcessor { | |
88 | /// Process a Thrift service call. | |
89 | /// | |
90 | /// Reads arguments from `i`, executes the user's handler code, and writes | |
91 | /// the response to `o`. | |
92 | /// | |
93 | /// Returns `()` if the handler was executed; `Err` otherwise. | |
94 | fn process(&self, i: &mut dyn TInputProtocol, o: &mut dyn TOutputProtocol) -> ::Result<()>; | |
95 | } | |
96 | ||
97 | /// Convenience function used in generated `TProcessor` implementations to | |
98 | /// return an `ApplicationError` if thrift message processing failed. | |
99 | pub fn handle_process_result( | |
100 | msg_ident: &TMessageIdentifier, | |
101 | res: ::Result<()>, | |
102 | o_prot: &mut dyn TOutputProtocol, | |
103 | ) -> ::Result<()> { | |
104 | if let Err(e) = res { | |
105 | let e = match e { | |
106 | ::Error::Application(a) => a, | |
107 | _ => ApplicationError::new(ApplicationErrorKind::Unknown, format!("{:?}", e)), | |
108 | }; | |
109 | ||
110 | let ident = TMessageIdentifier::new( | |
111 | msg_ident.name.clone(), | |
112 | TMessageType::Exception, | |
113 | msg_ident.sequence_number, | |
114 | ); | |
115 | ||
116 | o_prot.write_message_begin(&ident)?; | |
117 | ::Error::write_application_error_to_out_protocol(&e, o_prot)?; | |
118 | o_prot.write_message_end()?; | |
119 | o_prot.flush() | |
120 | } else { | |
121 | Ok(()) | |
122 | } | |
123 | } |