blob: d8bbf962e88228e03affcc35f61fa88a208648a2 [file]
/**
* Copyright (C) 2013 kangliqiang ,kangliq@163.com
*
* 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.
*/
#ifndef __TCPREMOTINGCLIENT_H__
#define __TCPREMOTINGCLIENT_H__
#include <map>
#include <string>
#include <list>
#include "RocketMQClient.h"
#include "SocketUtil.h"
#include "Epoller.h"
#include "RemotingCommand.h"
#include "Thread.h"
#include "ThreadPool.h"
#include "ThreadPoolWork.h"
#include "RemoteClientConfig.h"
#include "TcpTransport.h"
#include "ScopedLock.h"
#include "KPRUtil.h"
#include "Semaphore.h"
#include "ResponseFuture.h"
namespace rmq
{
class TcpTransport;
class InvokeCallback;
class TcpRemotingClient;
class ResponseFuture;
class TcpRequestProcessor;
class ProcessDataWork : public kpr::ThreadPoolWork
{
public:
ProcessDataWork(TcpRemotingClient* pClient, TcpTransport* pTts, std::string* pData);
virtual ~ProcessDataWork();
virtual void Do();
private:
TcpRemotingClient* m_pClient;
TcpTransport* m_pTts;
std::string* m_pData;
};
typedef kpr::RefHandleT<ProcessDataWork> ProcessDataWorkPtr;
class TcpRemotingClient
{
class EventThread : public kpr::Thread
{
public:
EventThread(TcpRemotingClient& client)
: Thread("NetThread"), m_client(client)
{
}
void Run()
{
m_client.run();
}
private :
TcpRemotingClient& m_client;
};
friend class EventThread;
friend class ProcessDataWork;
public:
static const int s_LockTimeoutMillis = 3000;
static const int s_CheckIntervalMillis = 1000;
static const int s_ClientOnewaySemaphoreValue = 2048;
static const int s_ClientAsyncSemaphoreValue = 2048;
public:
TcpRemotingClient(const RemoteClientConfig& config);
virtual ~TcpRemotingClient();
virtual void start();
virtual void shutdown();
void updateNameServerAddressList(const std::vector<std::string>& addrs);
std::vector<std::string> getNameServerAddressList();
void registerProcessor(int requestCode, TcpRequestProcessor* pProcessor);
RemotingCommand* invokeSync(const std::string& addr, RemotingCommand* pRequest, int timeoutMillis) ;
void invokeAsync(const std::string& addr, RemotingCommand* pRequest, int timeoutMillis, InvokeCallback* invokeCallback);
int invokeOneway(const std::string& addr, RemotingCommand* pRequest, int timeoutMillis);
private:
void run();
int sendCmd(TcpTransport* pTts, RemotingCommand* pRequest, int timeoutMillis);
void removeTTS(TcpTransport* pTts, bool isDisConnected = false);
void processData(TcpTransport* pTts, std::string* data);
void handleTimerEvent();
void scanResponseTable();
void scanCloseTransportTable();
void processMessageReceived(TcpTransport* pTts, RemotingCommand* pCmd);
void processRequestCommand(TcpTransport* pTts, RemotingCommand* pCmd);
void processResponseCommand(TcpTransport* pTts, RemotingCommand* pCmd);
TcpTransport* getAndCreateTransport(const std::string& addr, int timeoutMillis);
TcpTransport* getAndCreateNameserverTransport(int timeoutMillis);
TcpTransport* createTransport(const std::string& addr, int timeoutMillis);
RemotingCommand* invokeSyncImpl(TcpTransport* pTts, RemotingCommand* pRequest, int timeoutMillis) ;
void invokeAsyncImpl(TcpTransport* pTts, RemotingCommand* pRequest, int timeoutMillis, InvokeCallback* pInvokeCallback);
int invokeOnewayImpl(TcpTransport* pTts, RemotingCommand* pRequest, int timeoutMillis);
private:
bool m_stop;
kpr::Epoller m_epoller;
RemoteClientConfig m_config;
kpr::Semaphore m_semaphoreOneway;
kpr::Semaphore m_semaphoreAsync;
std::map<std::string , TcpTransport*> m_transportTable;
kpr::RWMutex m_transportTableLock;
std::list<TcpTransport*> m_closeTransportTable;
kpr::Mutex m_closeTransportTableLock;
std::map<int, ResponseFuturePtr> m_responseTable;
kpr::RWMutex m_responseTableLock;
std::vector<std::string> m_namesrvAddrList;
kpr::AtomicInteger m_namesrvIndex;
kpr::AtomicReference<std::string> m_namesrvAddrChoosed;
kpr::Mutex m_namesrvAddrChoosedLock;
kpr::ThreadPoolPtr m_pNetThreadPool;
kpr::ThreadPtr m_pEventThread;
TcpRequestProcessor* m_pDefaultRequestProcessor;
std::map<int, TcpRequestProcessor*> m_processorTable;
};
}
#endif