diff options
author | Dwayne Boone <dwayne@zeroc.com> | 2007-05-18 13:34:39 +0000 |
---|---|---|
committer | Dwayne Boone <dwayne@zeroc.com> | 2007-05-18 13:34:39 +0000 |
commit | bdcafea81addb5e3905c6ed5f4db093ec8ec0d15 (patch) | |
tree | 7cea0017b188b25abf1caac607476e21d63a8a7e /cpp/src | |
parent | Fixed comments (diff) | |
download | ice-bdcafea81addb5e3905c6ed5f4db093ec8ec0d15.tar.bz2 ice-bdcafea81addb5e3905c6ed5f4db093ec8ec0d15.tar.xz ice-bdcafea81addb5e3905c6ed5f4db093ec8ec0d15.zip |
Multi-home host support
Diffstat (limited to 'cpp/src')
-rw-r--r-- | cpp/src/Ice/ConnectionFactory.cpp | 103 | ||||
-rw-r--r-- | cpp/src/Ice/ConnectionFactory.h | 3 | ||||
-rw-r--r-- | cpp/src/Ice/EndpointI.h | 12 | ||||
-rw-r--r-- | cpp/src/Ice/Network.cpp | 32 | ||||
-rw-r--r-- | cpp/src/Ice/Network.h | 1 | ||||
-rw-r--r-- | cpp/src/Ice/Reference.cpp | 5 | ||||
-rw-r--r-- | cpp/src/Ice/TcpEndpointI.cpp | 26 | ||||
-rw-r--r-- | cpp/src/Ice/TcpEndpointI.h | 4 | ||||
-rw-r--r-- | cpp/src/Ice/UdpEndpointI.cpp | 26 | ||||
-rw-r--r-- | cpp/src/Ice/UdpEndpointI.h | 4 | ||||
-rw-r--r-- | cpp/src/Ice/UnknownEndpointI.cpp | 14 | ||||
-rw-r--r-- | cpp/src/Ice/UnknownEndpointI.h | 4 | ||||
-rw-r--r-- | cpp/src/IceSSL/EndpointI.cpp | 26 | ||||
-rw-r--r-- | cpp/src/IceSSL/EndpointI.h | 4 |
14 files changed, 200 insertions, 64 deletions
diff --git a/cpp/src/Ice/ConnectionFactory.cpp b/cpp/src/Ice/ConnectionFactory.cpp index 785d6264508..6bcc4c9ca20 100644 --- a/cpp/src/Ice/ConnectionFactory.cpp +++ b/cpp/src/Ice/ConnectionFactory.cpp @@ -24,6 +24,7 @@ #include <Ice/RouterInfo.h> #include <Ice/LocalException.h> #include <Ice/Functional.h> +#include <IceUtil/Random.h> #ifdef __BCPLUSPLUS__ # include <iterator> #endif @@ -35,6 +36,17 @@ using namespace IceInternal; IceUtil::Shared* IceInternal::upCast(OutgoingConnectionFactory* p) { return p; } IceUtil::Shared* IceInternal::upCast(IncomingConnectionFactory* p) { return p; } +namespace +{ +struct RandomNumberGenerator : public std::unary_function<ptrdiff_t, ptrdiff_t> +{ + ptrdiff_t operator()(ptrdiff_t d) + { + return IceUtil::random(static_cast<int>(d)); + } +}; +} + void IceInternal::OutgoingConnectionFactory::destroy() { @@ -91,7 +103,8 @@ IceInternal::OutgoingConnectionFactory::waitUntilFinished() ConnectionIPtr IceInternal::OutgoingConnectionFactory::create(const vector<EndpointIPtr>& endpts, bool moreEndpts, - bool threadPerConnection, bool& compress) + bool threadPerConnection, Ice::EndpointSelectionType selType, + bool& compress) { assert(!endpts.empty()); vector<EndpointIPtr> endpoints = endpts; @@ -267,13 +280,23 @@ IceInternal::OutgoingConnectionFactory::create(const vector<EndpointIPtr>& endpt try { - TransceiverPtr transceiver = endpoint->clientTransceiver(); - if(!transceiver) + vector<ConnectorPtr> connectors; + unsigned int size; + Int timeout; + + vector<TransceiverPtr> transceivers = endpoint->clientTransceivers(); + if(transceivers.size() == 0) { - ConnectorPtr connector = endpoint->connector(); - assert(connector); + connectors = endpoint->connectors(); + size = connectors.size(); + assert(size > 0); + + if(selType == Random) + { + RandomNumberGenerator rng; + random_shuffle(connectors.begin(), connectors.end(), rng); + } - Int timeout; if(_instance->defaultsAndOverrides()->overrideConnectTimeout) { timeout = _instance->defaultsAndOverrides()->overrideConnectTimeoutValue; @@ -285,14 +308,58 @@ IceInternal::OutgoingConnectionFactory::create(const vector<EndpointIPtr>& endpt { timeout = endpoint->timeout(); } - - transceiver = connector->connect(timeout); - assert(transceiver); } - connection = new ConnectionI(_instance, transceiver, endpoint, 0, threadPerConnection, - _instance->threadPerConnectionStackSize()); - connection->start(); - connection->validate(); + else + { + size = transceivers.size(); + if(selType == Random) + { + RandomNumberGenerator rng; + random_shuffle(transceivers.begin(), transceivers.end(), rng); + } + } + + for(unsigned int i = 0; i < size; ++i) + { + try + { + TransceiverPtr transceiver; + if(transceivers.size() == size) + { + transceiver = transceivers[i]; + } + else + { + transceiver = connectors[i]->connect(timeout); + assert(transceiver); + } + + connection = new ConnectionI(_instance, transceiver, endpoint, 0, threadPerConnection, + _instance->threadPerConnectionStackSize()); + connection->start(); + connection->validate(); + } + catch(const LocalException& ex) + { + // + // If a connection object was constructed, then validate() + // must have raised the exception. + // + if(connection) + { + connection->waitUntilFinished(); // We must call waitUntilFinished() for cleanup. + connection = 0; + } + + // + // Throw exception if this is last transceiver in list. + // + if(i == size - 1) + { + ex.ice_throw(); + } + } + } if(_instance->defaultsAndOverrides()->overrideCompress) { @@ -307,16 +374,6 @@ IceInternal::OutgoingConnectionFactory::create(const vector<EndpointIPtr>& endpt catch(const LocalException& ex) { exception.reset(dynamic_cast<LocalException*>(ex.ice_clone())); - - // - // If a connection object was constructed, then validate() - // must have raised the exception. - // - if(connection) - { - connection->waitUntilFinished(); // We must call waitUntilFinished() for cleanup. - connection = 0; - } } TraceLevelsPtr traceLevels = _instance->traceLevels(); diff --git a/cpp/src/Ice/ConnectionFactory.h b/cpp/src/Ice/ConnectionFactory.h index 7758e675b8d..0f517008f09 100644 --- a/cpp/src/Ice/ConnectionFactory.h +++ b/cpp/src/Ice/ConnectionFactory.h @@ -18,6 +18,7 @@ #include <Ice/InstanceF.h> #include <Ice/ObjectAdapterF.h> #include <Ice/EndpointIF.h> +#include <Ice/Endpoint.h> #include <Ice/AcceptorF.h> #include <Ice/TransceiverF.h> #include <Ice/RouterInfoF.h> @@ -44,7 +45,7 @@ public: void waitUntilFinished(); - Ice::ConnectionIPtr create(const std::vector<EndpointIPtr>&, bool, bool, bool&); + Ice::ConnectionIPtr create(const std::vector<EndpointIPtr>&, bool, bool, Ice::EndpointSelectionType, bool&); void setRouterInfo(const RouterInfoPtr&); void removeAdapter(const Ice::ObjectAdapterPtr&); void flushBatchRequests(); diff --git a/cpp/src/Ice/EndpointI.h b/cpp/src/Ice/EndpointI.h index 5d6362ecd93..d6f86782d0b 100644 --- a/cpp/src/Ice/EndpointI.h +++ b/cpp/src/Ice/EndpointI.h @@ -84,10 +84,10 @@ public: virtual bool unknown() const = 0; // - // Return a client side transceiver for this endpoint, or null if a - // transceiver can only be created by a connector. + // Return client side transceivers for this endpoint, or empty + // vector if a transceiver can only be created by a connector. // - virtual TransceiverPtr clientTransceiver() const = 0; + virtual std::vector<TransceiverPtr> clientTransceivers() const = 0; // // Return a server side transceiver for this endpoint, or null if a @@ -99,10 +99,10 @@ public: virtual TransceiverPtr serverTransceiver(EndpointIPtr&) const = 0; // - // Return a connector for this endpoint, or null if no connector - // is available. + // Return connectors for this endpoint, or empty vector if no + // connector is available. // - virtual ConnectorPtr connector() const = 0; + virtual std::vector<ConnectorPtr> connectors() const = 0; // // Return an acceptor for this endpoint, or null if no acceptors diff --git a/cpp/src/Ice/Network.cpp b/cpp/src/Ice/Network.cpp index 33bfec5739f..6e907c4bdbe 100644 --- a/cpp/src/Ice/Network.cpp +++ b/cpp/src/Ice/Network.cpp @@ -1260,6 +1260,38 @@ IceInternal::addrToString(const struct sockaddr_in& addr) } vector<string> +IceInternal::getHosts(const string& host) +{ + vector<string> result; + struct hostent* he = 0; + int retry = 5; + + do + { + he = gethostbyname(host.c_str()); + } + while(he == 0 && h_errno == TRY_AGAIN && --retry >= 0); + + if(he == 0) + { + DNSException ex(__FILE__, __LINE__); + ex.error = h_errno; + ex.host = host; + throw ex; + } + + char** ptr = he->h_addr_list; + while(*ptr) + { + struct in_addr* addr = reinterpret_cast<in_addr*>(*ptr); + result.push_back(inet_ntoa(*addr)); + ptr++; + } + + return result; +} + +vector<string> IceInternal::getLocalHosts() { vector<string> result; diff --git a/cpp/src/Ice/Network.h b/cpp/src/Ice/Network.h index 6ee6c80d72f..f03836965c6 100644 --- a/cpp/src/Ice/Network.h +++ b/cpp/src/Ice/Network.h @@ -107,6 +107,7 @@ ICE_API void fdToLocalAddress(SOCKET, struct sockaddr_in&); ICE_API bool fdToRemoteAddress(SOCKET, struct sockaddr_in&); ICE_API std::string addrToString(const struct sockaddr_in&); +ICE_API std::vector<std::string> getHosts(const std::string&); ICE_API std::vector<std::string> getLocalHosts(); #ifdef _WIN32 ICE_API std::vector<struct sockaddr_in> getLocalAddresses(); diff --git a/cpp/src/Ice/Reference.cpp b/cpp/src/Ice/Reference.cpp index 52ec2031ec7..b9e1d534836 100644 --- a/cpp/src/Ice/Reference.cpp +++ b/cpp/src/Ice/Reference.cpp @@ -1242,7 +1242,7 @@ IceInternal::RoutableReference::createConnection(const vector<EndpointIPtr>& all // Get an existing connection or create one if there's no // existing connection to one of the given endpoints. // - return factory->create(endpoints, false, _threadPerConnection, comp); + return factory->create(endpoints, false, _threadPerConnection, getEndpointSelection(), comp); } else { @@ -1263,7 +1263,8 @@ IceInternal::RoutableReference::createConnection(const vector<EndpointIPtr>& all try { endpoint.back() = *p; - return factory->create(endpoint, p + 1 == endpoints.end(), _threadPerConnection, comp); + return factory->create(endpoint, p + 1 == endpoints.end(), _threadPerConnection, + getEndpointSelection(), comp); } catch(const LocalException& ex) { diff --git a/cpp/src/Ice/TcpEndpointI.cpp b/cpp/src/Ice/TcpEndpointI.cpp index 6cf54872826..6b0b7a5c4b5 100644 --- a/cpp/src/Ice/TcpEndpointI.cpp +++ b/cpp/src/Ice/TcpEndpointI.cpp @@ -265,10 +265,11 @@ IceInternal::TcpEndpointI::unknown() const return false; } -TransceiverPtr -IceInternal::TcpEndpointI::clientTransceiver() const +vector<TransceiverPtr> +IceInternal::TcpEndpointI::clientTransceivers() const { - return 0; + vector<TransceiverPtr> ret; + return ret; } TransceiverPtr @@ -278,10 +279,23 @@ IceInternal::TcpEndpointI::serverTransceiver(EndpointIPtr& endp) const return 0; } -ConnectorPtr -IceInternal::TcpEndpointI::connector() const +vector<ConnectorPtr> +IceInternal::TcpEndpointI::connectors() const { - return new TcpConnector(_instance, _host, _port); + vector<ConnectorPtr> connectors; + vector<string> hosts = getHosts(_host); + if(hosts.size() > 1) + { + for(unsigned int i = 0; i < hosts.size(); ++i) + { + connectors.push_back(new TcpConnector(_instance, hosts[i], _port)); + } + } + else + { + connectors.push_back(new TcpConnector(_instance, _host, _port)); + } + return connectors; } AcceptorPtr diff --git a/cpp/src/Ice/TcpEndpointI.h b/cpp/src/Ice/TcpEndpointI.h index b3e542b09bd..0e003a179ef 100644 --- a/cpp/src/Ice/TcpEndpointI.h +++ b/cpp/src/Ice/TcpEndpointI.h @@ -37,9 +37,9 @@ public: virtual bool datagram() const; virtual bool secure() const; virtual bool unknown() const; - virtual TransceiverPtr clientTransceiver() const; + virtual std::vector<TransceiverPtr> clientTransceivers() const; virtual TransceiverPtr serverTransceiver(EndpointIPtr&) const; - virtual ConnectorPtr connector() const; + virtual std::vector<ConnectorPtr> connectors() const; virtual AcceptorPtr acceptor(EndpointIPtr&, const std::string&) const; virtual std::vector<EndpointIPtr> expand(bool) const; virtual bool publish() const; diff --git a/cpp/src/Ice/UdpEndpointI.cpp b/cpp/src/Ice/UdpEndpointI.cpp index 6681e8becbf..e6bfffa3818 100644 --- a/cpp/src/Ice/UdpEndpointI.cpp +++ b/cpp/src/Ice/UdpEndpointI.cpp @@ -430,10 +430,23 @@ IceInternal::UdpEndpointI::unknown() const return false; } -TransceiverPtr -IceInternal::UdpEndpointI::clientTransceiver() const +vector<TransceiverPtr> +IceInternal::UdpEndpointI::clientTransceivers() const { - return new UdpTransceiver(_instance, _host, _port); + vector<TransceiverPtr> transceivers; + vector<string> hosts = getHosts(_host); + if(hosts.size() > 1) + { + for(unsigned int i = 0; i < hosts.size(); ++i) + { + transceivers.push_back(new UdpTransceiver(_instance, hosts[i], _port)); + } + } + else + { + transceivers.push_back(new UdpTransceiver(_instance, _host, _port)); + } + return transceivers; } TransceiverPtr @@ -444,10 +457,11 @@ IceInternal::UdpEndpointI::serverTransceiver(EndpointIPtr& endp) const return p; } -ConnectorPtr -IceInternal::UdpEndpointI::connector() const +vector<ConnectorPtr> +IceInternal::UdpEndpointI::connectors() const { - return 0; + vector<ConnectorPtr> ret; + return ret; } AcceptorPtr diff --git a/cpp/src/Ice/UdpEndpointI.h b/cpp/src/Ice/UdpEndpointI.h index a19e1cbd295..7e5b5a87175 100644 --- a/cpp/src/Ice/UdpEndpointI.h +++ b/cpp/src/Ice/UdpEndpointI.h @@ -37,9 +37,9 @@ public: virtual bool datagram() const; virtual bool secure() const; virtual bool unknown() const; - virtual TransceiverPtr clientTransceiver() const; + virtual std::vector<TransceiverPtr> clientTransceivers() const; virtual TransceiverPtr serverTransceiver(EndpointIPtr&) const; - virtual ConnectorPtr connector() const; + virtual std::vector<ConnectorPtr> connectors() const; virtual AcceptorPtr acceptor(EndpointIPtr&, const std::string&) const; virtual std::vector<EndpointIPtr> expand(bool) const; virtual bool publish() const; diff --git a/cpp/src/Ice/UnknownEndpointI.cpp b/cpp/src/Ice/UnknownEndpointI.cpp index cb6526221c7..a50699e29c7 100644 --- a/cpp/src/Ice/UnknownEndpointI.cpp +++ b/cpp/src/Ice/UnknownEndpointI.cpp @@ -199,10 +199,11 @@ IceInternal::UnknownEndpointI::unknown() const return true; } -TransceiverPtr -IceInternal::UnknownEndpointI::clientTransceiver() const +vector<TransceiverPtr> +IceInternal::UnknownEndpointI::clientTransceivers() const { - return 0; + vector<TransceiverPtr> ret; + return ret; } TransceiverPtr @@ -212,10 +213,11 @@ IceInternal::UnknownEndpointI::serverTransceiver(EndpointIPtr& endp) const return 0; } -ConnectorPtr -IceInternal::UnknownEndpointI::connector() const +vector<ConnectorPtr> +IceInternal::UnknownEndpointI::connectors() const { - return 0; + vector<ConnectorPtr> ret; + return ret; } AcceptorPtr diff --git a/cpp/src/Ice/UnknownEndpointI.h b/cpp/src/Ice/UnknownEndpointI.h index c3036018eeb..2247c0485a2 100644 --- a/cpp/src/Ice/UnknownEndpointI.h +++ b/cpp/src/Ice/UnknownEndpointI.h @@ -34,9 +34,9 @@ public: virtual bool datagram() const; virtual bool secure() const; virtual bool unknown() const; - virtual TransceiverPtr clientTransceiver() const; + virtual std::vector<TransceiverPtr> clientTransceivers() const; virtual TransceiverPtr serverTransceiver(EndpointIPtr&) const; - virtual ConnectorPtr connector() const; + virtual std::vector<ConnectorPtr> connectors() const; virtual AcceptorPtr acceptor(EndpointIPtr&, const std::string&) const; virtual std::vector<EndpointIPtr> expand(bool) const; virtual bool publish() const; diff --git a/cpp/src/IceSSL/EndpointI.cpp b/cpp/src/IceSSL/EndpointI.cpp index 69866544132..a657b027874 100644 --- a/cpp/src/IceSSL/EndpointI.cpp +++ b/cpp/src/IceSSL/EndpointI.cpp @@ -265,10 +265,11 @@ IceSSL::EndpointI::unknown() const return false; } -IceInternal::TransceiverPtr -IceSSL::EndpointI::clientTransceiver() const +vector<IceInternal::TransceiverPtr> +IceSSL::EndpointI::clientTransceivers() const { - return 0; + vector<IceInternal::TransceiverPtr> ret; + return ret; } IceInternal::TransceiverPtr @@ -278,10 +279,23 @@ IceSSL::EndpointI::serverTransceiver(IceInternal::EndpointIPtr& endp) const return 0; } -IceInternal::ConnectorPtr -IceSSL::EndpointI::connector() const +vector<IceInternal::ConnectorPtr> +IceSSL::EndpointI::connectors() const { - return new ConnectorI(_instance, _host, _port); + vector<IceInternal::ConnectorPtr> connectors; + vector<string> hosts = IceInternal::getHosts(_host); + if(hosts.size() > 1) + { + for(unsigned int i = 0; i < hosts.size(); ++i) + { + connectors.push_back(new ConnectorI(_instance, hosts[i], _port)); + } + } + else + { + connectors.push_back(new ConnectorI(_instance, _host, _port)); + } + return connectors; } IceInternal::AcceptorPtr diff --git a/cpp/src/IceSSL/EndpointI.h b/cpp/src/IceSSL/EndpointI.h index 3aea7133ae8..1d842f2e345 100644 --- a/cpp/src/IceSSL/EndpointI.h +++ b/cpp/src/IceSSL/EndpointI.h @@ -38,9 +38,9 @@ public: virtual bool datagram() const; virtual bool secure() const; virtual bool unknown() const; - virtual IceInternal::TransceiverPtr clientTransceiver() const; + virtual std::vector<IceInternal::TransceiverPtr> clientTransceivers() const; virtual IceInternal::TransceiverPtr serverTransceiver(IceInternal::EndpointIPtr&) const; - virtual IceInternal::ConnectorPtr connector() const; + virtual std::vector<IceInternal::ConnectorPtr> connectors() const; virtual IceInternal::AcceptorPtr acceptor(IceInternal::EndpointIPtr&, const std::string&) const; virtual std::vector<IceInternal::EndpointIPtr> expand(bool) const; virtual bool publish() const; |