/* 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 "runtime/LogComment.h" #include "pgl/RobotSym.h" #include "runtime/StatPhase.h" #include "runtime/StatPhaseMgr.h" #include "client/AsyncClt.h" AsyncClt::AsyncClt(RndDistr *aThinkDistr) { Assert(!theThinkDistr); Assert(aThinkDistr); theThinkDistr = aThinkDistr; } void AsyncClt::configure(const RobotSym *cfg, const NetAddr &aHost) { Assert(theThinkDistr); Client::configure(cfg, aHost); } void AsyncClt::becomeIdle() { cancelAlarms(); // unschedule the next request if any Client::becomeIdle(); } void AsyncClt::wakeUp(const Alarm &a) { Client::wakeUp(a); scheduleLaunch(a.time()); // next tryLaunch(); } void AsyncClt::scheduleLaunch(Time lastLaunch) { Assert(!thePendAlarmCnt); Assert(theThinkDistr); const double lf = TheStatPhaseMgr->loadFactor().current(); Assert(lf >= 0); if (lf <= 0) // zero load: no more requests needed return; double delay; if (TheStatPhaseMgr->loadFactor().flat()) { delay = theThinkDistr->trial()/lf; } else { // next launch should happen [0, 2dt] from last launch // where dt is 1/current_rate static RndGen rng; delay = rng(0.0, 2.*theThinkDistr->mean()/lf); } sleepTill(lastLaunch + Time::Secd(delay)); } bool AsyncClt::launchCanceled(CltXact *x) { // if no alarms are pending, we may get stuck and submit // no more xactions (but this should not happen with AsyncClt) Should(isIdle || thePendAlarmCnt || theCcXactLvl); return Client::launchCanceled(x); }