Rewrite RPC method factory function

pull/114/head
Tatsuhiro Tsujikawa 2013-07-11 21:50:47 +09:00
parent 7c06b903f3
commit 59e63d956e
5 changed files with 56 additions and 72 deletions

View File

@ -226,9 +226,9 @@ bool HttpServerBodyCommand::execute()
addHttpServerResponseCommand(); addHttpServerResponseCommand();
return true; return true;
} }
auto method = rpc::RpcMethodFactory::create(req.methodName);
A2_LOG_INFO(fmt("Executing RPC method %s", req.methodName.c_str())); A2_LOG_INFO(fmt("Executing RPC method %s", req.methodName.c_str()));
rpc::RpcResponse res = method->execute(std::move(req), e_); auto res = rpc::getMethod(req.methodName)
->execute(std::move(req), e_);
bool gzip = httpServer_->supportsGZip(); bool gzip = httpServer_->supportsGZip();
std::string responseData = rpc::toXml(res, gzip); std::string responseData = rpc::toXml(res, gzip);
httpServer_->feedResponse(std::move(responseData), "text/xml"); httpServer_->feedResponse(std::move(responseData), "text/xml");

View File

@ -42,115 +42,114 @@ namespace aria2 {
namespace rpc { namespace rpc {
namespace { namespace {
std::shared_ptr<RpcMethod> getNoSuchMethod() std::map<std::string, std::unique_ptr<RpcMethod>> cache;
{
static std::shared_ptr<RpcMethod> m(new NoSuchMethodRpcMethod());
return m;
}
} // namespace } // namespace
namespace { namespace {
std::shared_ptr<RpcMethod> std::unique_ptr<RpcMethod> noSuchRpcMethod;
} // namespace
namespace {
std::unique_ptr<RpcMethod>
createMethod(const std::string& methodName) createMethod(const std::string& methodName)
{ {
if(methodName == AddUriRpcMethod::getMethodName()) { if(methodName == AddUriRpcMethod::getMethodName()) {
return std::shared_ptr<RpcMethod>(new AddUriRpcMethod()); return make_unique<AddUriRpcMethod>();
#ifdef ENABLE_BITTORRENT #ifdef ENABLE_BITTORRENT
} else if(methodName == AddTorrentRpcMethod::getMethodName()) { } else if(methodName == AddTorrentRpcMethod::getMethodName()) {
return std::shared_ptr<RpcMethod>(new AddTorrentRpcMethod()); return make_unique<AddTorrentRpcMethod>();
#endif // ENABLE_BITTORRENT #endif // ENABLE_BITTORRENT
#ifdef ENABLE_METALINK #ifdef ENABLE_METALINK
} }
else if(methodName == AddMetalinkRpcMethod::getMethodName()) { else if(methodName == AddMetalinkRpcMethod::getMethodName()) {
return std::shared_ptr<RpcMethod>(new AddMetalinkRpcMethod()); return make_unique<AddMetalinkRpcMethod>();
#endif // ENABLE_METALINK #endif // ENABLE_METALINK
} }
else if(methodName == RemoveRpcMethod::getMethodName()) { else if(methodName == RemoveRpcMethod::getMethodName()) {
return std::shared_ptr<RpcMethod>(new RemoveRpcMethod()); return make_unique<RemoveRpcMethod>();
} else if(methodName == PauseRpcMethod::getMethodName()) { } else if(methodName == PauseRpcMethod::getMethodName()) {
return std::shared_ptr<RpcMethod>(new PauseRpcMethod()); return make_unique<PauseRpcMethod>();
} else if(methodName == ForcePauseRpcMethod::getMethodName()) { } else if(methodName == ForcePauseRpcMethod::getMethodName()) {
return std::shared_ptr<RpcMethod>(new ForcePauseRpcMethod()); return make_unique<ForcePauseRpcMethod>();
} else if(methodName == PauseAllRpcMethod::getMethodName()) { } else if(methodName == PauseAllRpcMethod::getMethodName()) {
return std::shared_ptr<RpcMethod>(new PauseAllRpcMethod()); return make_unique<PauseAllRpcMethod>();
} else if(methodName == ForcePauseAllRpcMethod::getMethodName()) { } else if(methodName == ForcePauseAllRpcMethod::getMethodName()) {
return std::shared_ptr<RpcMethod>(new ForcePauseAllRpcMethod()); return make_unique<ForcePauseAllRpcMethod>();
} else if(methodName == UnpauseRpcMethod::getMethodName()) { } else if(methodName == UnpauseRpcMethod::getMethodName()) {
return std::shared_ptr<RpcMethod>(new UnpauseRpcMethod()); return make_unique<UnpauseRpcMethod>();
} else if(methodName == UnpauseAllRpcMethod::getMethodName()) { } else if(methodName == UnpauseAllRpcMethod::getMethodName()) {
return std::shared_ptr<RpcMethod>(new UnpauseAllRpcMethod()); return make_unique<UnpauseAllRpcMethod>();
} else if(methodName == ForceRemoveRpcMethod::getMethodName()) { } else if(methodName == ForceRemoveRpcMethod::getMethodName()) {
return std::shared_ptr<RpcMethod>(new ForceRemoveRpcMethod()); return make_unique<ForceRemoveRpcMethod>();
} else if(methodName == ChangePositionRpcMethod::getMethodName()) { } else if(methodName == ChangePositionRpcMethod::getMethodName()) {
return std::shared_ptr<RpcMethod>(new ChangePositionRpcMethod()); return make_unique<ChangePositionRpcMethod>();
} else if(methodName == TellStatusRpcMethod::getMethodName()) { } else if(methodName == TellStatusRpcMethod::getMethodName()) {
return std::shared_ptr<RpcMethod>(new TellStatusRpcMethod()); return make_unique<TellStatusRpcMethod>();
} else if(methodName == GetUrisRpcMethod::getMethodName()) { } else if(methodName == GetUrisRpcMethod::getMethodName()) {
return std::shared_ptr<RpcMethod>(new GetUrisRpcMethod()); return make_unique<GetUrisRpcMethod>();
} else if(methodName == GetFilesRpcMethod::getMethodName()) { } else if(methodName == GetFilesRpcMethod::getMethodName()) {
return std::shared_ptr<RpcMethod>(new GetFilesRpcMethod()); return make_unique<GetFilesRpcMethod>();
#ifdef ENABLE_BITTORRENT #ifdef ENABLE_BITTORRENT
} }
else if(methodName == GetPeersRpcMethod::getMethodName()) { else if(methodName == GetPeersRpcMethod::getMethodName()) {
return std::shared_ptr<RpcMethod>(new GetPeersRpcMethod()); return make_unique<GetPeersRpcMethod>();
#endif // ENABLE_BITTORRENT #endif // ENABLE_BITTORRENT
} else if(methodName == GetServersRpcMethod::getMethodName()) { } else if(methodName == GetServersRpcMethod::getMethodName()) {
return std::shared_ptr<RpcMethod>(new GetServersRpcMethod()); return make_unique<GetServersRpcMethod>();
} else if(methodName == TellActiveRpcMethod::getMethodName()) { } else if(methodName == TellActiveRpcMethod::getMethodName()) {
return std::shared_ptr<RpcMethod>(new TellActiveRpcMethod()); return make_unique<TellActiveRpcMethod>();
} else if(methodName == TellWaitingRpcMethod::getMethodName()) { } else if(methodName == TellWaitingRpcMethod::getMethodName()) {
return std::shared_ptr<RpcMethod>(new TellWaitingRpcMethod()); return make_unique<TellWaitingRpcMethod>();
} else if(methodName == TellStoppedRpcMethod::getMethodName()) { } else if(methodName == TellStoppedRpcMethod::getMethodName()) {
return std::shared_ptr<RpcMethod>(new TellStoppedRpcMethod()); return make_unique<TellStoppedRpcMethod>();
} else if(methodName == GetOptionRpcMethod::getMethodName()) { } else if(methodName == GetOptionRpcMethod::getMethodName()) {
return std::shared_ptr<RpcMethod>(new GetOptionRpcMethod()); return make_unique<GetOptionRpcMethod>();
} else if(methodName == ChangeUriRpcMethod::getMethodName()) { } else if(methodName == ChangeUriRpcMethod::getMethodName()) {
return std::shared_ptr<RpcMethod>(new ChangeUriRpcMethod()); return make_unique<ChangeUriRpcMethod>();
} else if(methodName == ChangeOptionRpcMethod::getMethodName()) { } else if(methodName == ChangeOptionRpcMethod::getMethodName()) {
return std::shared_ptr<RpcMethod>(new ChangeOptionRpcMethod()); return make_unique<ChangeOptionRpcMethod>();
} else if(methodName == GetGlobalOptionRpcMethod::getMethodName()) { } else if(methodName == GetGlobalOptionRpcMethod::getMethodName()) {
return std::shared_ptr<RpcMethod>(new GetGlobalOptionRpcMethod()); return make_unique<GetGlobalOptionRpcMethod>();
} else if(methodName == ChangeGlobalOptionRpcMethod::getMethodName()) { } else if(methodName == ChangeGlobalOptionRpcMethod::getMethodName()) {
return std::shared_ptr<RpcMethod>(new ChangeGlobalOptionRpcMethod()); return make_unique<ChangeGlobalOptionRpcMethod>();
} else if(methodName == PurgeDownloadResultRpcMethod::getMethodName()) { } else if(methodName == PurgeDownloadResultRpcMethod::getMethodName()) {
return std::shared_ptr<RpcMethod>(new PurgeDownloadResultRpcMethod()); return make_unique<PurgeDownloadResultRpcMethod>();
} else if(methodName == RemoveDownloadResultRpcMethod::getMethodName()) { } else if(methodName == RemoveDownloadResultRpcMethod::getMethodName()) {
return std::shared_ptr<RpcMethod>(new RemoveDownloadResultRpcMethod()); return make_unique<RemoveDownloadResultRpcMethod>();
} else if(methodName == GetVersionRpcMethod::getMethodName()) { } else if(methodName == GetVersionRpcMethod::getMethodName()) {
return std::shared_ptr<RpcMethod>(new GetVersionRpcMethod()); return make_unique<GetVersionRpcMethod>();
} else if(methodName == GetSessionInfoRpcMethod::getMethodName()) { } else if(methodName == GetSessionInfoRpcMethod::getMethodName()) {
return std::shared_ptr<RpcMethod>(new GetSessionInfoRpcMethod()); return make_unique<GetSessionInfoRpcMethod>();
} else if(methodName == ShutdownRpcMethod::getMethodName()) { } else if(methodName == ShutdownRpcMethod::getMethodName()) {
return std::shared_ptr<RpcMethod>(new ShutdownRpcMethod()); return make_unique<ShutdownRpcMethod>();
} else if(methodName == ForceShutdownRpcMethod::getMethodName()) { } else if(methodName == ForceShutdownRpcMethod::getMethodName()) {
return std::shared_ptr<RpcMethod>(new ForceShutdownRpcMethod()); return make_unique<ForceShutdownRpcMethod>();
} else if(methodName == GetGlobalStatRpcMethod::getMethodName()) { } else if(methodName == GetGlobalStatRpcMethod::getMethodName()) {
return std::shared_ptr<RpcMethod>(new GetGlobalStatRpcMethod()); return make_unique<GetGlobalStatRpcMethod>();
} else if(methodName == SystemMulticallRpcMethod::getMethodName()) { } else if(methodName == SystemMulticallRpcMethod::getMethodName()) {
return std::shared_ptr<RpcMethod>(new SystemMulticallRpcMethod()); return make_unique<SystemMulticallRpcMethod>();
} else { } else {
return nullptr; return nullptr;
} }
} }
} // namespace } // namespace
std::map<std::string, std::shared_ptr<RpcMethod> > RpcMethodFactory::cache_; RpcMethod* getMethod(const std::string& methodName)
std::shared_ptr<RpcMethod>
RpcMethodFactory::create(const std::string& methodName)
{ {
std::map<std::string, std::shared_ptr<RpcMethod> >::const_iterator itr = auto itr = cache.find(methodName);
cache_.find(methodName); if(itr == cache.end()) {
if(itr == cache_.end()) { auto m = createMethod(methodName);
std::shared_ptr<RpcMethod> m = createMethod(methodName);
if(m) { if(m) {
cache_.insert(std::make_pair(methodName, m)); auto rv = cache.insert(std::make_pair(methodName, std::move(m)));
return m; return (*rv.first).second.get();
} else { } else {
return getNoSuchMethod(); if(!noSuchRpcMethod) {
noSuchRpcMethod = make_unique<NoSuchMethodRpcMethod>();
}
return noSuchRpcMethod.get();
} }
} else { } else {
return (*itr).second; return (*itr).second.get();
} }
} }

View File

@ -38,7 +38,6 @@
#include "common.h" #include "common.h"
#include <string> #include <string>
#include <map>
#include <memory> #include <memory>
namespace aria2 { namespace aria2 {
@ -47,12 +46,7 @@ namespace rpc {
class RpcMethod; class RpcMethod;
class RpcMethodFactory { RpcMethod* getMethod(const std::string& methodName);
public:
static std::shared_ptr<RpcMethod> create(const std::string& methodName);
private:
static std::map<std::string, std::shared_ptr<RpcMethod> > cache_;
};
} // namespace rpc } // namespace rpc

View File

@ -1381,8 +1381,7 @@ std::unique_ptr<ValueBase> SystemMulticallRpcMethod::process
} else { } else {
paramsList = List::g(); paramsList = List::g();
} }
auto method = RpcMethodFactory::create(methodName->s()); RpcResponse res = getMethod(methodName->s())->execute
RpcResponse res = method->execute
({methodName->s(), std::move(paramsList), nullptr, req.jsonRpc}, e); ({methodName->s(), std::move(paramsList), nullptr, req.jsonRpc}, e);
if(res.code == 0) { if(res.code == 0) {
auto l = List::g(); auto l = List::g();

View File

@ -98,17 +98,9 @@ RpcResponse processJsonRpcRequest(Dict* jsondict, DownloadEngine* e)
return createJsonRpcErrorResponse(-32602, "Invalid params.", return createJsonRpcErrorResponse(-32602, "Invalid params.",
std::move(id)); std::move(id));
} }
std::shared_ptr<RpcMethod> method;
try {
method = rpc::RpcMethodFactory::create(methodName->s());
} catch(RecoverableException& e) {
A2_LOG_INFO_EX(EX_EXCEPTION_CAUGHT, e);
return createJsonRpcErrorResponse(-32601, "Method not found.",
std::move(id));
}
A2_LOG_INFO(fmt("Executing RPC method %s", methodName->s().c_str())); A2_LOG_INFO(fmt("Executing RPC method %s", methodName->s().c_str()));
return method->execute({methodName->s(), std::move(params), return getMethod(methodName->s())->execute
std::move(id), true}, e); ({methodName->s(), std::move(params), std::move(id), true}, e);
} }
} // namespace rpc } // namespace rpc