26 #ifndef _HACLIENTIMPL_H_ 27 #define _HACLIENTIMPL_H_ 38 class HAClientImpl :
public ClientImpl
41 HAClientImpl(
const std::string& name_)
42 : ClientImpl(name_), _timeout(AMPS_HACLIENT_TIMEOUT_DEFAULT)
43 , _reconnectDelay(AMPS_HACLIENT_RECONNECT_DEFAULT)
44 , _reconnectDelayStrategy(new ExponentialDelayStrategy(_reconnectDelay))
45 , _disconnected(false)
47 #ifdef AMPS_USE_FUNCTIONAL 48 setDisconnectHandler(HADisconnectHandler());
52 setSubscriptionManager(
new MemorySubscriptionManager());
61 void setTimeout(
int timeout_)
66 int getTimeout()
const 71 unsigned int getReconnectDelay(
void)
const 73 return _reconnectDelay;
76 void setReconnectDelay(
unsigned int reconnectDelay_)
78 _reconnectDelay = reconnectDelay_;
79 setReconnectDelayStrategy(
new FixedDelayStrategy(
80 (
unsigned int)reconnectDelay_));
83 void setReconnectDelayStrategy(
const ReconnectDelayStrategy& strategy_)
85 _reconnectDelayStrategy = strategy_;
88 ReconnectDelayStrategy getReconnectDelayStrategy(
void)
const 90 return _reconnectDelayStrategy;
93 std::string getLogonOptions(
void)
const 98 void setLogonOptions(
const std::string& logonOptions_)
100 _logonOptions = logonOptions_;
103 void setLogonOptions(
const char* logonOptions_)
105 _logonOptions = logonOptions_;
108 ServerChooser getServerChooser()
const 110 return _serverChooser;
113 void setServerChooser(
const ServerChooser& serverChooser_)
115 _serverChooser = serverChooser_;
118 class HADisconnectHandler
121 HADisconnectHandler() {}
122 static void invoke(Client& client,
void* );
123 #ifdef AMPS_USE_FUNCTIONAL 124 void operator()(Client& client)
126 invoke(client, NULL);
130 void connectAndLogon()
132 Lock<Mutex> l(_connectAndLogonLock);
133 _disconnected =
false;
136 connectAndLogonInternal();
140 if(_subscriptionManager)
143 _subscriptionManager->resubscribe(c);
144 broadcastConnectionStateChanged(
145 ConnectionStateListener::Resubscribed);
149 catch(
const AMPSException& subEx)
151 _serverChooser.reportFailure(subEx, getConnectionInfo());
156 virtual void connect(
const std::string& )
161 virtual std::string logon(
long , Authenticator& ,
164 if (_disconnected)
throw DisconnectedException(
"Attempt to call logon on a disconnected HAClient. Use connectAndLogon() instead.");
165 throw AlreadyConnectedException(
"Attempt to call logon on an HAClient. Use connectAndLogon() instead.");
168 class HADoNothingDisconnectHandler
171 HADoNothingDisconnectHandler() {}
172 static void invoke(Client& ,
void* ) {;}
173 #ifdef AMPS_USE_FUNCTIONAL 174 void operator()(Client& client)
176 invoke(client, NULL);
181 class DisconnectHandlerDisabler
184 DisconnectHandlerDisabler() : _client(NULL) { }
185 DisconnectHandlerDisabler(HAClientImpl* client_)
188 _handler = _client->getDisconnectHandler();
191 ~DisconnectHandlerDisabler() { clear(); }
196 _client->setDisconnectHandler(_handler);
200 void setClient(HAClientImpl* client_)
205 _handler = _client->getDisconnectHandler();
211 #ifdef AMPS_USE_FUNCTIONAL 212 _client->setDisconnectHandler(HADoNothingDisconnectHandler());
214 _client->setDisconnectHandler(DisconnectHandler(
215 &HADoNothingDisconnectHandler::invoke,
220 HAClientImpl* _client;
221 DisconnectHandler _handler;
224 void connectAndLogonInternal()
226 if(!_serverChooser.isValid())
228 throw ConnectionException(
"No server chooser registered with HAClient");
231 DisconnectHandlerDisabler disconnectDisabler;
232 while(!_disconnected)
234 std::string uri = _serverChooser.getCurrentURI();
237 throw ConnectionException(
"No AMPS instances available for connection. " + _serverChooser.getError());
239 Authenticator& auth = _serverChooser.getCurrentAuthenticator();
240 _sleepBeforeConnecting(uri);
244 Lock<Mutex> l(_connectLock);
246 if(_disconnected || _connected)
251 disconnectDisabler.setClient((HAClientImpl*)
this);
253 ClientImpl::connect(uri);
254 if (_logonOptions.empty())
256 ClientImpl::logon(_timeout, auth);
260 ClientImpl::logon(_timeout, auth, _logonOptions.c_str());
262 disconnectDisabler.clear();
265 _serverChooser.reportSuccess(getConnectionInfo());
266 _reconnectDelayStrategy.reset();
268 catch(
const AMPSException& e)
270 ClientImpl::disconnect();
271 throw AMPSException(e);
275 catch(
const AMPSException& ex)
277 ConnectionInfo ci = getConnectionInfo();
279 ci[
"client.uri"] = uri;
280 _serverChooser.reportFailure(ex,ci);
283 ClientImpl::setDisconnected();
285 catch (
const AMPSException& e)
289 _exceptionListener->exceptionThrown(e);
298 ConnectionInfo gatherConnectionInfo()
const 300 return getConnectionInfo();
303 ConnectionInfo getConnectionInfo()
const 305 ConnectionInfo info = ClientImpl::getConnectionInfo();
306 std::ostringstream writer;
308 writer << getReconnectDelay();
309 info[
"haClient.reconnectDelay"] = writer.str();
310 writer.clear(); writer.str(
"");
312 info[
"haClient.timeout"] = writer.str();
317 bool disconnected()
const 319 return _disconnected;
326 Lock<Mutex> l(_connectLock);
327 _disconnected =
true;
329 ClientImpl::disconnect();
331 void _millisleep(
unsigned int millis_)
337 ts.tv_sec = millis_ / 1000;
338 ts.tv_nsec = millis_ % 1000 * 1000000;
339 nanosleep(&ts, NULL);
342 void _sleepBeforeConnecting(
const std::string& uri_)
347 _reconnectDelayStrategy.getConnectWaitDuration(uri_));
349 catch(
const ConnectionException&)
353 catch(
const std::exception& ex_)
355 _exceptionListener->exceptionThrown(ex_);
356 throw ConnectionException(ex_.what());
360 throw ConnectionException(
"Unknown exception thrown by " 361 "the HAClient's delay strategy.");
366 Mutex _connectAndLogonLock;
368 unsigned int _reconnectDelay;
369 ReconnectDelayStrategy _reconnectDelayStrategy;
370 ServerChooser _serverChooser;
371 volatile bool _disconnected;
372 std::string _logonOptions;
378 #endif //_HACLIENTIMPL_H_ Provides AMPS::MemorySubscriptionManager, used by an AMPS::HAClient to resubmit subscriptions if conn...
Core type, function, and class declarations for the AMPS C++ client.
Provides AMPS::ReconnectDelayStrategy, called by an AMPS::HAClient to determine how long to wait betw...
Provides AMPS::ServerChooser, the abstract base class that defines the interface that an AMPS::HAClie...
Definition: ampsplusplus.hpp:136