/* Web Polygraph http://www.web-polygraph.org/
* (C) 2003-2006 The Measurement Factory
* Licensed under the Apache License, Version 2.0 */
#include "base/polygraph.h"
#include "base/OLog.h"
#include "runtime/LogComment.h"
#include "runtime/SharedOpts.h"
#include "runtime/StatIntvl.h"
#include "runtime/XactFarm.h"
#include "client/AsyncClt.h"
#include "client/SyncClt.h"
#include "client/PassClt.h"
#include "client/CltOpts.h"
#include "client/ServerRep.h"
#include "server/Server.h"
#include "server/SrvOpts.h"
#include "cache/Cache.h"
#include "cache/DistrPoint.h"
#include "icp/IcpProxy.h"
#include "proxy/PxyCltXact.h"
#include "proxy/PxySrvXact.h"
#include "proxy/PolyPxy.h"
#include "pgl/CacheSym.h"
#include "pgl/RobotSym.h"
#include "pgl/ServerSym.h"
#include "pgl/ProxySym.h"
#include "base/polyLogCats.h"
#include "xstd/gadgets.h"
#include "xstd/rndDistrs.h"
#include "runtime/globals.h"
typedef XactFarmT<CltXact, PxyCltXact> PxyCltXactFarm;
typedef XactFarmT<SrvXact, PxySrvXact> PxySrvXactFarm;
PolyPxy::PolyPxy() {
theAgentType = "Proxy";
}
Agent *PolyPxy::makeAgent(const AgentSym &agent, const NetAddr &address) {
const ProxySym *pcfg = &(const ProxySym&)agent.cast("Proxy");
int icpSrv = -1, icpClt = -1; // port numbers
Client *client = 0;
Server *server = 0;
Cache *cache = 0;
if (const CacheSym *ccfg = pcfg->cache()) {
cache = new Cache;
cache->configure(ccfg);
ccfg->icpPort(icpSrv);
} else {
cerr << pcfg->loc() << "must configure cache for the proxy" << endl;
exit(-3);
}
if (const RobotSym *rcfg = pcfg->client()) {
RndDistr *iad = 0;
if (rcfg->reqInterArrival(iad)) {
if (iad)
client = new AsyncClt(iad);
else
client = new PassClt();
} else {
client = new SyncClt();
}
client->configure(rcfg, address);
addAgent(client);
rcfg->icpPort(icpClt);
}
if (const ServerSym *scfg = pcfg->server()) {
server = new Server();
server->configure(scfg, address);
addAgent(server);
}
IcpClient *icpClient = 0;
if (icpClt == icpSrv && icpSrv >= 0) {
IcpProxy *i = new IcpProxy;
i->configure(NetAddr(address.addrN(), icpSrv));
i->cache(cache);
addIcpAgent(i);
icpClient = i;
} else {
if (icpSrv >= 0) {
IcpServer *i = new IcpServer;
i->configure(NetAddr(address.addrN(), icpSrv));
i->cache(cache);
addIcpAgent(i);
}
if (icpClt >= 0) {
IcpClient *i = new IcpClient;
i->configure(NetAddr(address.addrN(), icpClt));
addIcpAgent(i);
icpClient = i;
}
}
if (client) {
client->cache(cache);
client->icpClient(icpClient);
}
if (server)
server->cache(cache);
cache->client(client);
return server; // XXX: could be NULL and we ignore the client
}
void PolyPxy::addIcpAgent(IcpBase *icpAgent) {
Assert(icpAgent);
theIcpAgents.append(icpAgent);
}
void PolyPxy::configure() {
PolyApp::configure();
Client::Farm(new PxyCltXactFarm);
Server::Farm(new PxySrvXactFarm);
IcpCltXact::TheTimeout = TheCltOpts.theIcpTout;
StatIntvl::ActiveCat(lgcCltSide);
StatIntvl::ActiveCat(lgcSrvSide);
StatIntvl::TheReportCat = lgcCltSide;
}
void PolyPxy::getOpts(Array<OptGrp*> &opts) {
PolyApp::getOpts(opts);
opts.append(&TheCltOpts);
opts.append(&TheSrvOpts);
}
void PolyPxy::reportCfg() {
PolyApp::reportCfg();
}
const String PolyPxy::sideName() const {
return "proxy";
}
void PolyPxy::logState(OLog &log) {
PolyApp::logState(log);
Client::LogState(log);
}
void PolyPxy::startAgents() {
Comment(1) << "starting " << theIcpAgents.count() << " ICP agents..." << endc;
for (int i = 0; i < theIcpAgents.count(); ++i)
theIcpAgents[i]->start();
PolyApp::startAgents();
}
void PolyPxy::step() {
PolyApp::step();
DistrPoint::CallAll();
}
int PolyPxy::logCat() const {
return lgcCltSide;
}
int main(int argc, char *argv[]) {
PolyPxy app;
return app.run(argc, argv);
}
syntax highlighted by Code2HTML, v. 0.9.1