1
0
Fork 0
arangodb/Scheduler/ConnectionTask.h

253 lines
9.3 KiB
C++

////////////////////////////////////////////////////////////////////////////////
/// @brief tasks used to establish connections
///
/// @file
///
/// DISCLAIMER
///
/// Copyright 2010-2011 triagens GmbH, Cologne, Germany
///
/// Licensed 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.
///
/// Copyright holder is triAGENS GmbH, Cologne, Germany
///
/// @author Dr. Frank Celler
/// @author Achim Brandt
/// @author Copyright 2009-2011, triAGENS GmbH, Cologne, Germany
////////////////////////////////////////////////////////////////////////////////
#ifndef TRIAGENS_FYN_REST_CONNECTION_TASK_H
#define TRIAGENS_FYN_REST_CONNECTION_TASK_H 1
#include "Scheduler/SocketTask.h"
namespace triagens {
namespace rest {
////////////////////////////////////////////////////////////////////////////////
/// @ingroup Scheduler
/// @brief task used to establish connections
////////////////////////////////////////////////////////////////////////////////
class ConnectionTask : public SocketTask {
ConnectionTask (ConnectionTask const &);
ConnectionTask& operator= (ConnectionTask const &);
public:
////////////////////////////////////////////////////////////////////////////////
/// @brief error status
////////////////////////////////////////////////////////////////////////////////
enum error_e {
ERROR_NO_ERROR,
ERROR_CONNECTION_FAILURE,
ERROR_CONNECTION_TIMEOUT,
ERROR_CONNECTION_CLOSED,
ERROR_EXECUTION_FAILURE,
ERROR_EXECUTION_TIMEOUT,
ERROR_GENERAL_ERROR,
ERROR_SHUTDOWN_IN_PROGRESS
};
public:
////////////////////////////////////////////////////////////////////////////////
/// @brief connection to given hostname and port
////////////////////////////////////////////////////////////////////////////////
ConnectionTask (string const& hostname, int port);
////////////////////////////////////////////////////////////////////////////////
/// @brief connection to given hostname and port
////////////////////////////////////////////////////////////////////////////////
ConnectionTask (string const& hostname, int port, double connectTimeout);
////////////////////////////////////////////////////////////////////////////////
/// @brief connection to given hostname and port
////////////////////////////////////////////////////////////////////////////////
ConnectionTask (string const& hostname, int port, double connectTimeout, double commTimeout);
////////////////////////////////////////////////////////////////////////////////
/// @brief connection using a given socket
////////////////////////////////////////////////////////////////////////////////
ConnectionTask (socket_t fd);
////////////////////////////////////////////////////////////////////////////////
/// @brief connection using a given socket
////////////////////////////////////////////////////////////////////////////////
ConnectionTask (socket_t fd, double commTimeout);
public:
////////////////////////////////////////////////////////////////////////////////
/// @brief checks if hostname is resolved
///
/// Note that you can use this method only before the call to registerTask.
////////////////////////////////////////////////////////////////////////////////
bool isResolved () const {
return resolved;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief checks if the socket is connected
///
/// Note that you can use this method only before the call to registerTask.
////////////////////////////////////////////////////////////////////////////////
bool isConnected () const {
return state == STATE_CONNECTED;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief checks if the socket is created
///
/// Note that you can use this method only before the call to registerTask.
////////////////////////////////////////////////////////////////////////////////
bool isConnecting () const {
return state == STATE_CONNECTED || state == STATE_CONNECTION_INPROGRESS;
}
int getPort () const {
return port;
}
protected:
////////////////////////////////////////////////////////////////////////////////
/// @brief called by the task to indicate connection success
////////////////////////////////////////////////////////////////////////////////
virtual bool handleConnected () = 0;
////////////////////////////////////////////////////////////////////////////////
/// @brief called by the task to indicate connection failure
////////////////////////////////////////////////////////////////////////////////
virtual bool handleConnectionFailure () = 0;
////////////////////////////////////////////////////////////////////////////////
/// @brief called by the task to indicate a timeout
////////////////////////////////////////////////////////////////////////////////
virtual bool handleConnectionTimeout () = 0;
////////////////////////////////////////////////////////////////////////////////
/// @brief called by the task to indicate a timeout
////////////////////////////////////////////////////////////////////////////////
virtual bool handleCommunicationTimeout () = 0;
protected:
////////////////////////////////////////////////////////////////////////////////
/// @brief destructs a connection task
////////////////////////////////////////////////////////////////////////////////
~ConnectionTask ();
protected:
////////////////////////////////////////////////////////////////////////////////
/// {@inheritDoc}
///
/// Note that you should only call registerTask if the address has been
/// resolved.
////////////////////////////////////////////////////////////////////////////////
void setup (Scheduler*, EventLoop);
////////////////////////////////////////////////////////////////////////////////
/// {@inheritDoc}
////////////////////////////////////////////////////////////////////////////////
void cleanup ();
////////////////////////////////////////////////////////////////////////////////
/// {@inheritDoc}
////////////////////////////////////////////////////////////////////////////////
bool handleEvent (EventToken, EventType);
protected:
////////////////////////////////////////////////////////////////////////////////
/// @brief timer event
////////////////////////////////////////////////////////////////////////////////
EventToken watcher;
protected:
////////////////////////////////////////////////////////////////////////////////
/// @brief state of the state machine
////////////////////////////////////////////////////////////////////////////////
enum state_e {
STATE_UNCONNECTED,
STATE_CONNECTION_INPROGRESS,
STATE_CONNECTED
};
////////////////////////////////////////////////////////////////////////////////
/// @brief the state of the socket
////////////////////////////////////////////////////////////////////////////////
state_e state;
////////////////////////////////////////////////////////////////////////////////
/// @brief true, if no request is in progress
///
/// Note that the sub-class must set/reset the idle flag in handleEvent.
////////////////////////////////////////////////////////////////////////////////
bool idle;
////////////////////////////////////////////////////////////////////////////////
/// @brief connection timeout in seconds
////////////////////////////////////////////////////////////////////////////////
double connectTimeout;
////////////////////////////////////////////////////////////////////////////////
/// @brief communication timeout in seconds
////////////////////////////////////////////////////////////////////////////////
double commTimeout;
private:
void resolveAddress ();
void connectSocket ();
bool handleConnectionEvent (EventToken token, EventType event);
bool handleCommunicationEvent (EventToken token, EventType event);
private:
string const hostname;
int const port;
char* netaddress;
size_t netaddressLength;
bool resolved;
};
}
}
#endif