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