/* * 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. */ #ifndef _THRIFT_SERVER_TSERVER_H_ #define _THRIFT_SERVER_TSERVER_H_ 1 #include #include #include #include #include namespace apache { namespace thrift { namespace server { using apache::thrift::TProcessor; using apache::thrift::protocol::TBinaryProtocolFactory; using apache::thrift::protocol::TProtocol; using apache::thrift::protocol::TProtocolFactory; using apache::thrift::transport::TServerTransport; using apache::thrift::transport::TTransport; using apache::thrift::transport::TTransportFactory; /** * Virtual interface class that can handle events from the server core. To * use this you should subclass it and implement the methods that you care * about. Your subclass can also store local data that you may care about, * such as additional "arguments" to these methods (stored in the object * instance's state). */ class TServerEventHandler { public: virtual ~TServerEventHandler() {} /** * Called before the server begins. */ virtual void preServe() {} /** * Called when a new client has connected and is about to being processing. */ virtual void* createContext(boost::shared_ptr input, boost::shared_ptr output) { (void)input; (void)output; return NULL; } /** * Called when a client has finished request-handling to delete server * context. */ virtual void deleteContext(void* serverContext, boost::shared_ptr input, boost::shared_ptr output) { (void)serverContext; (void)input; (void)output; } /** * Called when a client is about to call the processor. */ virtual void processContext(void* serverContext, boost::shared_ptr transport) { (void)serverContext; (void)transport; } protected: /** * Prevent direct instantiation. */ TServerEventHandler() {} }; /** * Thrift server. * */ class TServer : public concurrency::Runnable { public: virtual ~TServer() {} virtual void serve() = 0; virtual void stop() {} // Allows running the server as a Runnable thread virtual void run() { serve(); } boost::shared_ptr getProcessorFactory() { return processorFactory_; } boost::shared_ptr getServerTransport() { return serverTransport_; } boost::shared_ptr getInputTransportFactory() { return inputTransportFactory_; } boost::shared_ptr getOutputTransportFactory() { return outputTransportFactory_; } boost::shared_ptr getInputProtocolFactory() { return inputProtocolFactory_; } boost::shared_ptr getOutputProtocolFactory() { return outputProtocolFactory_; } boost::shared_ptr getEventHandler() { return eventHandler_; } protected: TServer(const boost::shared_ptr& processorFactory) : processorFactory_(processorFactory) { setInputTransportFactory(boost::shared_ptr(new TTransportFactory())); setOutputTransportFactory(boost::shared_ptr(new TTransportFactory())); setInputProtocolFactory(boost::shared_ptr(new TBinaryProtocolFactory())); setOutputProtocolFactory(boost::shared_ptr(new TBinaryProtocolFactory())); } TServer(const boost::shared_ptr& processor) : processorFactory_(new TSingletonProcessorFactory(processor)) { setInputTransportFactory(boost::shared_ptr(new TTransportFactory())); setOutputTransportFactory(boost::shared_ptr(new TTransportFactory())); setInputProtocolFactory(boost::shared_ptr(new TBinaryProtocolFactory())); setOutputProtocolFactory(boost::shared_ptr(new TBinaryProtocolFactory())); } TServer(const boost::shared_ptr& processorFactory, const boost::shared_ptr& serverTransport) : processorFactory_(processorFactory), serverTransport_(serverTransport) { setInputTransportFactory(boost::shared_ptr(new TTransportFactory())); setOutputTransportFactory(boost::shared_ptr(new TTransportFactory())); setInputProtocolFactory(boost::shared_ptr(new TBinaryProtocolFactory())); setOutputProtocolFactory(boost::shared_ptr(new TBinaryProtocolFactory())); } TServer(const boost::shared_ptr& processor, const boost::shared_ptr& serverTransport) : processorFactory_(new TSingletonProcessorFactory(processor)), serverTransport_(serverTransport) { setInputTransportFactory(boost::shared_ptr(new TTransportFactory())); setOutputTransportFactory(boost::shared_ptr(new TTransportFactory())); setInputProtocolFactory(boost::shared_ptr(new TBinaryProtocolFactory())); setOutputProtocolFactory(boost::shared_ptr(new TBinaryProtocolFactory())); } TServer(const boost::shared_ptr& processorFactory, const boost::shared_ptr& serverTransport, const boost::shared_ptr& transportFactory, const boost::shared_ptr& protocolFactory) : processorFactory_(processorFactory), serverTransport_(serverTransport), inputTransportFactory_(transportFactory), outputTransportFactory_(transportFactory), inputProtocolFactory_(protocolFactory), outputProtocolFactory_(protocolFactory) {} TServer(const boost::shared_ptr& processor, const boost::shared_ptr& serverTransport, const boost::shared_ptr& transportFactory, const boost::shared_ptr& protocolFactory) : processorFactory_(new TSingletonProcessorFactory(processor)), serverTransport_(serverTransport), inputTransportFactory_(transportFactory), outputTransportFactory_(transportFactory), inputProtocolFactory_(protocolFactory), outputProtocolFactory_(protocolFactory) {} TServer(const boost::shared_ptr& processorFactory, const boost::shared_ptr& serverTransport, const boost::shared_ptr& inputTransportFactory, const boost::shared_ptr& outputTransportFactory, const boost::shared_ptr& inputProtocolFactory, const boost::shared_ptr& outputProtocolFactory) : processorFactory_(processorFactory), serverTransport_(serverTransport), inputTransportFactory_(inputTransportFactory), outputTransportFactory_(outputTransportFactory), inputProtocolFactory_(inputProtocolFactory), outputProtocolFactory_(outputProtocolFactory) {} TServer(const boost::shared_ptr& processor, const boost::shared_ptr& serverTransport, const boost::shared_ptr& inputTransportFactory, const boost::shared_ptr& outputTransportFactory, const boost::shared_ptr& inputProtocolFactory, const boost::shared_ptr& outputProtocolFactory) : processorFactory_(new TSingletonProcessorFactory(processor)), serverTransport_(serverTransport), inputTransportFactory_(inputTransportFactory), outputTransportFactory_(outputTransportFactory), inputProtocolFactory_(inputProtocolFactory), outputProtocolFactory_(outputProtocolFactory) {} /** * Get a TProcessor to handle calls on a particular connection. * * This method should only be called once per connection (never once per * call). This allows the TProcessorFactory to return a different processor * for each connection if it desires. */ boost::shared_ptr getProcessor(boost::shared_ptr inputProtocol, boost::shared_ptr outputProtocol, boost::shared_ptr transport) { TConnectionInfo connInfo; connInfo.input = inputProtocol; connInfo.output = outputProtocol; connInfo.transport = transport; return processorFactory_->getProcessor(connInfo); } // Class variables boost::shared_ptr processorFactory_; boost::shared_ptr serverTransport_; boost::shared_ptr inputTransportFactory_; boost::shared_ptr outputTransportFactory_; boost::shared_ptr inputProtocolFactory_; boost::shared_ptr outputProtocolFactory_; boost::shared_ptr eventHandler_; public: void setInputTransportFactory(boost::shared_ptr inputTransportFactory) { inputTransportFactory_ = inputTransportFactory; } void setOutputTransportFactory(boost::shared_ptr outputTransportFactory) { outputTransportFactory_ = outputTransportFactory; } void setInputProtocolFactory(boost::shared_ptr inputProtocolFactory) { inputProtocolFactory_ = inputProtocolFactory; } void setOutputProtocolFactory(boost::shared_ptr outputProtocolFactory) { outputProtocolFactory_ = outputProtocolFactory; } void setServerEventHandler(boost::shared_ptr eventHandler) { eventHandler_ = eventHandler; } }; /** * Helper function to increase the max file descriptors limit * for the current process and all of its children. * By default, tries to increase it to as much as 2^24. */ #ifdef HAVE_SYS_RESOURCE_H int increase_max_fds(int max_fds = (1 << 24)); #endif } } } // apache::thrift::server #endif // #ifndef _THRIFT_SERVER_TSERVER_H_