blob: 70b381ac928176d153d1338cfe85dbd850339780 [file] [log] [blame]
Allen George8b96bfb2016-11-02 08:01:08 -04001// 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
Allen George0e22c362017-01-30 07:15:00 -050018//! Types used to implement a Thrift server.
Allen George8b96bfb2016-11-02 08:01:08 -040019
Allen Georgebc1344d2017-04-28 10:22:03 -040020use protocol::{TInputProtocol, TMessageIdentifier, TMessageType, TOutputProtocol};
Allen Georgeef7a1892018-12-16 18:01:37 -050021use {ApplicationError, ApplicationErrorKind};
Allen George8b96bfb2016-11-02 08:01:08 -040022
Allen George8b96bfb2016-11-02 08:01:08 -040023mod multiplexed;
Allen George0e22c362017-01-30 07:15:00 -050024mod threaded;
Allen George8b96bfb2016-11-02 08:01:08 -040025
Allen George8b96bfb2016-11-02 08:01:08 -040026pub use self::multiplexed::TMultiplexedProcessor;
Allen George0e22c362017-01-30 07:15:00 -050027pub use self::threaded::TServer;
Allen George8b96bfb2016-11-02 08:01:08 -040028
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;
43/// use thrift::protocol::{TInputProtocol, TOutputProtocol};
44/// use thrift::server::TProcessor;
45///
46/// //
47/// // auto-generated
48/// //
49///
50/// // processor for `SimpleService`
51/// struct SimpleServiceSyncProcessor;
52/// impl SimpleServiceSyncProcessor {
53/// fn new<H: SimpleServiceSyncHandler>(processor: H) -> SimpleServiceSyncProcessor {
54/// unimplemented!();
55/// }
56/// }
57///
58/// // `TProcessor` implementation for `SimpleService`
59/// impl TProcessor for SimpleServiceSyncProcessor {
Allen George0e22c362017-01-30 07:15:00 -050060/// fn process(&self, i: &mut TInputProtocol, o: &mut TOutputProtocol) -> thrift::Result<()> {
Allen George8b96bfb2016-11-02 08:01:08 -040061/// unimplemented!();
62/// }
63/// }
64///
65/// // service functions for SimpleService
66/// trait SimpleServiceSyncHandler {
Allen George0e22c362017-01-30 07:15:00 -050067/// fn service_call(&self) -> thrift::Result<()>;
Allen George8b96bfb2016-11-02 08:01:08 -040068/// }
69///
70/// //
71/// // user-code follows
72/// //
73///
74/// // define a handler that will be invoked when `service_call` is received
75/// struct SimpleServiceHandlerImpl;
76/// impl SimpleServiceSyncHandler for SimpleServiceHandlerImpl {
Allen George0e22c362017-01-30 07:15:00 -050077/// fn service_call(&self) -> thrift::Result<()> {
Allen George8b96bfb2016-11-02 08:01:08 -040078/// unimplemented!();
79/// }
80/// }
81///
82/// // instantiate the processor
83/// let processor = SimpleServiceSyncProcessor::new(SimpleServiceHandlerImpl {});
84///
85/// // at this point you can pass the processor to the server
Allen George0e22c362017-01-30 07:15:00 -050086/// // let server = TServer::new(..., processor);
Allen George8b96bfb2016-11-02 08:01:08 -040087/// ```
88pub trait TProcessor {
89 /// Process a Thrift service call.
90 ///
91 /// Reads arguments from `i`, executes the user's handler code, and writes
92 /// the response to `o`.
93 ///
94 /// Returns `()` if the handler was executed; `Err` otherwise.
Allen George0e22c362017-01-30 07:15:00 -050095 fn process(&self, i: &mut TInputProtocol, o: &mut TOutputProtocol) -> ::Result<()>;
Allen George8b96bfb2016-11-02 08:01:08 -040096}
Allen Georgebc1344d2017-04-28 10:22:03 -040097
98/// Convenience function used in generated `TProcessor` implementations to
99/// return an `ApplicationError` if thrift message processing failed.
100pub fn handle_process_result(
101 msg_ident: &TMessageIdentifier,
102 res: ::Result<()>,
103 o_prot: &mut TOutputProtocol,
104) -> ::Result<()> {
105 if let Err(e) = res {
106 let e = match e {
107 ::Error::Application(a) => a,
108 _ => ApplicationError::new(ApplicationErrorKind::Unknown, format!("{:?}", e)),
109 };
110
111 let ident = TMessageIdentifier::new(
112 msg_ident.name.clone(),
113 TMessageType::Exception,
114 msg_ident.sequence_number,
115 );
116
117 o_prot.write_message_begin(&ident)?;
118 ::Error::write_application_error_to_out_protocol(&e, o_prot)?;
119 o_prot.write_message_end()?;
120 o_prot.flush()
121 } else {
122 Ok(())
123 }
124}