thrift/server/
mod.rs

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
20use crate::protocol::{TInputProtocol, TMessageIdentifier, TMessageType, TOutputProtocol};
21use crate::{ApplicationError, ApplicationErrorKind};
22
23mod multiplexed;
24mod threaded;
25
26pub use self::multiplexed::TMultiplexedProcessor;
27pub 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 dyn TInputProtocol, o: &mut dyn 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/// ```
87pub 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)
95        -> crate::Result<()>;
96}
97
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: crate::Result<()>,
103    o_prot: &mut dyn TOutputProtocol,
104) -> crate::Result<()> {
105    if let Err(e) = res {
106        let e = match e {
107            crate::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        crate::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}