blob: d65e3a5377cf09718835273767cc73c4a2e1cb41 [file] [log] [blame]
/*
* Copyright 2015 Twitter, Inc.
*
* 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.
*/
///////////////////////////////////////////////////////////////////////////////
// This file defines the BaseClient class.
// Each type of Heron client inherits from this class. The various
// derivations differ in what sort of protocol they speak. The only
// implementation is the Client class that speaks the Heron
// ProtocolBuffer Packets.
// The BaseClient knows how to bind and listen to a particular port.
// It tries to connect to a destination server and calls various
// callbacks like HandleConnect_Base and HandleClose_Base when
// the connection connects/closes.
// Derived classes differ in what sort of connections they init, and
// how requests are handled. Please see client.h
// for details on how to use the BaseClient class. No other classes should
// derive from the BaseClient class.
///////////////////////////////////////////////////////////////////////////////
#ifndef BASECLIENT_H_
#define BASECLIENT_H_
#include <functional>
#include "network/baseconnection.h"
#include "network/event_loop.h"
#include "network/networkoptions.h"
#include "network/network_error.h"
#include "basics/basics.h"
/*
* BaseClient class definition
*/
class BaseClient {
public:
enum State { DISCONNECTED = 0, CONNECTING, CONNECTED };
// Constructor/Destructor
// Note that constructor doesn't do much beyond initializing some members.
// Users must explicitly invoke the Start method to be able to send requests
// and receive responses.
BaseClient(EventLoop* eventLoop, const NetworkOptions& options);
virtual ~BaseClient();
// This starts the connect opereation.
// A return of this function doesnt mean that the client is ready to go.
// It just means that the connect operation is proceeding and we
// will be informed with the HandleConnect_Base method how things went.
void Start_Base();
// This one closes the underlying connection. No new responses will
// be delivered to the client after this call. The set of existing
// requests may not be sent by the client depending on whether they
// have already been sent out of wire or not. You might receive
// error notifications via the HandleSentRequest.
// A return from this doesn't mean that the underlying sockets have been
// closed. Merely that the process has begun. When the actual close
// happens, HandleClose_Base will be called.
void Stop_Base();
// Add a timer to be invoked after msecs microseconds. Returns the timer_id
sp_int64 AddTimer_Base(VCallback<> cb, sp_int64 msecs);
// Removes a given timer with timer_id
sp_int32 RemoveTimer_Base(sp_int64 timer_id);
// return the client options.
const NetworkOptions& get_clientoptions() const { return options_; }
protected:
// Instantiate a new connection
virtual BaseConnection* CreateConnection(ConnectionEndPoint* endpoint, ConnectionOptions* options,
EventLoop* eventLoop) = 0;
// Derived class should implement this method to handle Connection
// establishment. a status of OK implies that the Client was
// successful in connecting to hte client. Requests can now be sent to
// the server. Any other status implies that the connect failed.
virtual void HandleConnect_Base(NetworkErrorCode status) = 0;
// When the underlying socket is closed(either because of an explicit
// Stop done by derived class or because a read/write failed and
// the connection closed automatically on us), this method is
// called. A status of OK means that this was a user initiated
// Close that successfully went through. A status value of
// READ_ERROR implies that there was problem reading in the
// connection and thats why the connection was closed internally.
// A status value of WRITE_ERROR implies that there was a problem writing
// in the connection. Derived classes can do any cleanups in this method.
virtual void HandleClose_Base(NetworkErrorCode status) = 0;
// The options of this client.
NetworkOptions options_;
// The connection represents our link to the server. All reads/writes are
// done thru it.
BaseConnection* conn_;
State state_;
// The underlying EventLoop
EventLoop* eventLoop_;
private:
// Helper function that inits various objects
void Init(EventLoop* eventLoop, const NetworkOptions& _options);
// Internal method to be called by the Connection class when a
// connect happens.
void OnConnect(ConnectionEndPoint* endpoint, EventLoop::Status status);
// Internal method to be called by the Connection class when a close happens.
void OnClose(NetworkErrorCode status);
// When the timer event is called by the EventLoop
void OnTimer(VCallback<> cb, EventLoop::Status status);
// When we create a Connection structure, we use the following options
ConnectionOptions connection_options_;
};
#endif // BASECLIENT_H_