INTRODUCTION Overview Download and Install Quick Start Documentation Publications NONFRAMEWORK CODE Driver Interfaces Drivers Libraries Utilities FRAMEWORK CODE Interfaces Components Libraries Utilities Full Software Listings DEVELOPER Tutorials Examples Dev Guide Dashboard PEOPLE Contributors Users Project Download Mailing lists
|
icestormutils.h00001 00002 00003 /* 00004 * Orca-Robotics Project: Components for robotics 00005 * http://orca-robotics.sf.net/ 00006 * Copyright (c) 2004-2009 Alex Brooks, Alexei Makarenko, Tobias Kaupp 00007 * 00008 * This copy of Orca is licensed to you under the terms described in 00009 * the LICENSE file included in this distribution. 00010 * 00011 */ 00012 00013 #ifndef ORCAICE_ICESTORM_UTILITIES_H 00014 #define ORCAICE_ICESTORM_UTILITIES_H 00015 00016 #include <IceStorm/IceStorm.h> 00017 00018 #include <orcaice/context.h> 00019 #include <orcaice/exceptions.h> 00020 #include <orcaice/configutils.h> 00021 #include <orcaice/printutils.h> 00022 #include <orcaice/stringutils.h> 00023 00024 namespace orcaice 00025 { 00030 00054 template<class ConsumerProxyType> 00055 ConsumerProxyType 00056 createConsumerInterface( const Context & context, 00057 Ice::ObjectPtr & consumer ) 00058 { 00059 // create servant and tell adapter about it (let it make up a globally unique name) 00060 // NOTE: addWithUUID() does not throw exceptions. 00061 try 00062 { 00063 Ice::ObjectPrx obj = context.adapter()->addWithUUID( consumer ); 00064 00065 // make a direct proxy 00066 Ice::ObjectPrx prx = context.adapter()->createDirectProxy( obj->ice_getIdentity() ); 00067 return ConsumerProxyType::uncheckedCast( prx ); 00068 } 00069 catch( const Ice::ObjectAdapterDeactivatedException &e ) 00070 { 00071 std::stringstream ss; 00072 ss << "orcaice::Component: Failed to create consumer interface because the adapter is destroyed : " << e; 00073 bool localOnly = true; 00074 context.tracer().warning( ss.str(), 1, localOnly ); 00075 throw orcaice::ComponentDeactivatingException( ERROR_INFO, ss.str() ); 00076 } 00077 } 00078 00079 // FUNCTIONS WITHOUT DOXYGEN TAGS ARE UTILITY FUNCTIONS 00080 // THEY ARE PUBLICLY AVAILABLE BUT ARE NOT ADVERTIZED THROUGH DOXYGEN 00081 00082 /* 00083 * Behaves the same as the one above but connects to the topic manager 00084 * specified in the current properties. 00085 */ 00086 IceStorm::TopicPrx connectToIceStormTopicPrx( const Context &, 00087 const std::string & topicName, 00088 bool createIfMissing=false ); 00089 00090 /* 00091 * Behaves the same as the one above but connects to the topic manager 00092 * specified in the communicator's properties. 00093 */ 00094 IceStorm::TopicPrx connectToIceStormTopicPrx( const Ice::CommunicatorPtr & communicator, 00095 const std::string & topicName, 00096 bool createIfMissing=false ); 00097 00098 /* 00099 * Given the stingified proxy to topic manager and topic name, connect to the topic proxy. 00100 * If topic manager does not exist, throws Exception exception. 00101 */ 00102 IceStorm::TopicPrx connectToIceStormTopicPrxWithManager( const Ice::CommunicatorPtr & communicator, 00103 const std::string & topicName, 00104 const std::string & topicManagerString, 00105 bool createIfMissing=false ); 00106 00107 /* 00108 Publisher is the IceStorm's consumer of information. 00109 So the publisher component (the provider of data) can push data into it. 00110 Remote calls! 00111 Connects to the topic and returns the topic's publisher. 00112 */ 00113 Ice::ObjectPrx connectToIceStormTopicPublisherPrx( const Ice::CommunicatorPtr & communicator, 00114 const std::string & topicName ); 00115 00116 /* 00117 Local calls only. 00118 */ 00119 Ice::ObjectPrx getIceStormTopicPublisherPrx( const IceStorm::TopicPrx & topic ); 00120 00136 template<class ConsumerProxyType> 00137 IceStorm::TopicPrx 00138 connectToTopicWithString( const Context & context, 00139 ConsumerProxyType & publisher, 00140 const std::string & topicName, 00141 bool localReportingOnly=false ) 00142 { 00143 IceStorm::TopicPrx topicPrx; 00144 00145 try { 00146 const bool createIfMissing = true; 00147 // 00148 // set the proxy to the topic 00149 // 00150 topicPrx = connectToIceStormTopicPrx( context.communicator(), topicName, createIfMissing ); 00151 00152 Ice::ObjectPrx obj = getIceStormTopicPublisherPrx( topicPrx ); 00153 // 00154 // set the proxy to the publisher 00155 // 00156 publisher = ConsumerProxyType::uncheckedCast(obj); 00157 } 00158 //catch ( const gbxutilacfr::Exception & e ) { 00159 // we'll catch it here if the topic manager does not exist 00160 //} 00161 catch ( Ice::ConnectionRefusedException &e ) 00162 { 00163 // Give some feedback as to why this isn't working 00164 std::stringstream ss; ss<<"Error while connecting to IceStorm topic publisher '"<<topicName<<"': "<<e; 00165 // not using status because we would need to add localReportingOnly option 00166 initTracerError( context, ss.str(), localReportingOnly ); 00167 initTracerInfo( context, "hint: Is IceStorm running?", localReportingOnly ); 00168 throw orcaice::NetworkException( ERROR_INFO, ss.str() ); 00169 } 00170 catch( const Ice::LocalException &e ) 00171 { 00172 std::stringstream ss; 00173 ss<<"Error while connecting to IceStorm topic publisher '"<<topicName<<"': "<<e; 00174 // not using status because we would need to add localReportingOnly option 00175 initTracerError( context, ss.str(), localReportingOnly ); 00176 throw gbxutilacfr::Exception( ERROR_INFO, ss.str() ); 00177 } 00178 catch ( Ice::Exception &e ) 00179 { 00180 // Give some feedback as to why this isn't working 00181 std::stringstream ss; ss<<"Error while connecting to IceStorm topic publisher '"<<topicName<<"': "<<e; 00182 // not using status because we would need to add localReportingOnly option 00183 initTracerError( context, ss.str(), localReportingOnly ); 00184 throw orcaice::NetworkException( ERROR_INFO, ss.str() ); 00185 } 00186 00187 return topicPrx; 00188 } 00189 00198 template<class ConsumerProxyType> 00199 IceStorm::TopicPrx 00200 connectToTopicWithTag( const Context & context, 00201 ConsumerProxyType & publisher, 00202 const std::string & interfaceTag, 00203 const std::string & subtopic="*", 00204 bool localReportingOnly=false ) 00205 { 00206 context.tracer().debug( "orcaice::connectToTopicWithTag() tag="+interfaceTag, 10 ); 00207 00208 // lookup the name of the interface in the config file and generate topic name. 00209 // this generates a standard topic name based on fully-qualified interface name. 00210 std::string topicName = orcaice::toString( 00211 orcaice::getProvidedTopicWithTag( context, interfaceTag, subtopic ) ); 00212 00213 return connectToTopicWithString( context, publisher, topicName, localReportingOnly ); 00214 } 00215 00217 00218 namespace detail { 00219 00220 // Catches all exceptions. 00221 // Returns: 00222 // 0 : if re-connected 00223 // 1 : if failed to re-connect 00224 // -1 : if got CommunicatorDestroyedException 00225 template<class ConsumerPrxType> 00226 int 00227 tryReconnectToIceStorm( orcaice::Context &context, 00228 ConsumerPrxType &publisherPrx, 00229 IceStorm::TopicPrx &topicPrx, 00230 const std::string &topicName ) 00231 { 00232 try { 00233 topicPrx = orcaice::connectToTopicWithString<ConsumerPrxType> 00234 ( context, publisherPrx, topicName ); 00235 00236 std::string msg = "Re-connected to IceStorm topic "+topicName; 00237 context.tracer().info( msg ); 00238 00239 return 0; 00240 } 00241 catch ( const Ice::CommunicatorDestroyedException& ) 00242 { 00243 return -1; 00244 } 00245 catch ( const Ice::Exception& e ) 00246 { 00247 std::stringstream ss; 00248 ss << "Re-connection to IceStorm topic " << topicName << " failed:\n" 00249 << e.what(); 00250 bool localOnly = true; 00251 context.tracer().warning( ss.str(), 1, localOnly ); 00252 return 1; 00253 } 00254 catch ( ... ) 00255 { 00256 std::string msg = "Re-connection to IceStorm topic "+topicName+" failed."; 00257 bool localOnly = true; 00258 context.tracer().warning( msg, 1, localOnly ); 00259 return 1; 00260 } 00261 } 00262 00263 } 00264 00266 00267 00277 template<class ConsumerPrxType, class DataType> 00278 void tryPushToIceStormWithReconnect( orcaice::Context &context, 00279 ConsumerPrxType &publisherPrx, 00280 const DataType &data, 00281 IceStorm::TopicPrx &topicPrx, 00282 const std::string &topicName ) 00283 { 00284 // check that communicator still exists 00285 if ( !context.communicator() ) { 00286 return; 00287 } 00288 00289 // check that we are connected to the publisher 00290 if ( !publisherPrx ) { 00291 int reconnected = detail::tryReconnectToIceStorm( 00292 context, publisherPrx, topicPrx, topicName ); 00293 bool localOnly = true; 00294 if ( reconnected==0 ) { 00295 context.tracer().info( "(while pushing data to IceStorm) connected to publisher.", 1, localOnly ); 00296 } 00297 else if ( reconnected>0 ) { 00298 context.tracer().info( "(while pushing data to IceStorm) failed to connect to publisher.", 1, localOnly ); 00299 return; 00300 } 00301 else { 00302 // CommunicatorDestroyedException 00303 // If we see this, we're obviously shutting down. Don't bitch about anything. 00304 return; 00305 } 00306 } 00307 00308 try { 00309 publisherPrx->setData( data ); 00310 } 00311 catch ( Ice::CommunicatorDestroyedException & ) 00312 { 00313 // If we see this, we're obviously shutting down. Don't bitch about anything. 00314 } 00315 catch ( Ice::Exception &e ) 00316 { 00317 // This could happen if IceStorm dies. 00318 // If we're running in an IceBox and the IceBox is shutting down, 00319 // this is expected (our co-located IceStorm is obviously going down). 00320 std::stringstream ss; 00321 ss << "(while pushing data to topic "<<topicName<<") 1st attempt failed: " << e.what(); 00322 bool localOnly = true; 00323 context.tracer().warning( ss.str(), 1, localOnly ); 00324 00325 // If IceStorm just re-started for some reason though, we want to try to re-connect 00326 int reconnected = detail::tryReconnectToIceStorm( 00327 context, publisherPrx, topicPrx, topicName ); 00328 if ( reconnected==0 ) 00329 { 00330 try { 00331 // try again to push that last bit of info 00332 publisherPrx->setData( data ); 00333 } 00334 catch ( Ice::Exception &e ) 00335 { 00336 std::stringstream ss; 00337 ss << "(while pushing data to topic "<<topicName<<") 2nd attempt failed: " << e.what(); 00338 bool localOnly = true; 00339 context.tracer().warning( ss.str(), 1, localOnly ); 00340 } 00341 } 00342 } 00343 } 00344 00346 00347 } // namespace 00348 00349 #endif |
Webmaster: Tobias Kaupp (tobasco at users.sourceforge.net)