00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 
00031 
00032 
00033 
00034 
00035 
00036 
00037 
00038 
00039 
00040 
00041 
00042 
00043 
00044 
00045 
00046 
00047 
00048 
00049 
00050 
00051 
00052 
00053 
00054 
00055 
00056 #ifndef ns_webtraf_h
00057 #define ns_webtraf_h
00058 
00059 #include "ranvar.h"
00060 #include "random.h"
00061 #include "timer-handler.h"
00062 
00063 #include "lib/bsd-list.h"
00064 #include "node.h"
00065 #include "tcp.h"
00066 #include "tcp-sink.h"
00067 #include "pagepool.h"
00068 #include "webserver.h"
00069 
00070 const int WEBTRAF_DEFAULT_OBJ_PER_PAGE = 1;
00071 
00072 class WebTrafPool;
00073 
00074 class WebTrafSession : public TimerHandler {
00075 public: 
00076         WebTrafSession(WebTrafPool *mgr, Node *src, int np, int id, int ftcp_, int recycle_p);
00077         virtual ~WebTrafSession();
00078 
00079         
00080         inline RandomVariable*& interPage() { return rvInterPage_; }
00081         inline RandomVariable*& pageSize() { return rvPageSize_; }
00082         inline RandomVariable*& interObj() { return rvInterObj_; }
00083         inline RandomVariable*& objSize() { return rvObjSize_; }
00084 
00085         void donePage(void* ClntData);
00086         void launchReq(void* ClntData, int obj, int size);
00087         inline int id() const { return id_; }
00088         inline WebTrafPool* mgr() { return mgr_; }
00089         inline void set_interPageOption(int option) { interPageOption_ = option; }
00090 
00091         static int LASTPAGE_;
00092 
00093 private:
00094         virtual void expire(Event *e = 0);
00095         virtual void handle(Event *e);
00096 
00097         RandomVariable *rvInterPage_, *rvPageSize_, *rvInterObj_, *rvObjSize_;
00098         WebTrafPool* mgr_;
00099         Node* src_;             
00100         int nPage_, curPage_, donePage_;
00101         int id_, interPageOption_;
00102         
00103         
00104         int fulltcp_;
00105         
00106         int recycle_page_;
00107 };
00108 
00109 class WebServer;
00110 class WebTrafPool : public PagePool {
00111 public: 
00112         WebTrafPool(); 
00113         virtual ~WebTrafPool(); 
00114 
00115         Node* picksrc();
00116         Node* pickdst();
00117         inline void doneSession(int idx) { 
00118                 assert((idx>=0) && (idx<nSession_) && (session_[idx]!=NULL));
00119                 if (isdebug())
00120                         printf("deleted session %d\n", idx);
00121                 delete session_[idx];
00122                 session_[idx] = NULL; 
00123         }
00124 
00125         void launchReq(Node*, void*, int, int);
00126         void launchResp(int, Node*, Node*, Agent*, Agent*, int, void*);
00127         inline int nTcp() { return nTcp_; }
00128         inline int nSink() { return nSink_; }
00129         inline int isdebug() { return debug_; }
00130 
00131         virtual void delay_bind_init_all();
00132         virtual int delay_bind_dispatch(const char*, const char*, TclObject*);
00133 
00134         
00135         void pick_ep(TcpAgent**, Agent**);
00136         TcpAgent* picktcp();
00137         TcpSink* picksink();
00138         
00139         int find_server(int);
00140 
00141 protected:
00142         virtual int command(int argc, const char*const* argv);
00143 
00144         
00145 
00146         
00147         
00148         int nSession_;
00149         WebTrafSession** session_; 
00150 
00151         
00152         int nServer_;
00153         
00154         
00155         WebServer *server_;
00156 
00157         
00158         int nClient_;
00159         Node** client_;
00160 
00161         
00162         int asimflag_;
00163 
00164         
00165         struct AgentListElem {
00166                 AgentListElem(Agent* a) : agt_(a) {
00167                         link.le_next = NULL;
00168                         link.le_prev = NULL;
00169                 }
00170                 Agent* agt_;
00171                 LIST_ENTRY(AgentListElem) link;
00172         };
00173         LIST_HEAD(AgentList, AgentListElem);
00174         inline void insertAgent(AgentList* l, Agent *a) {
00175                 AgentListElem *e = new AgentListElem(a);
00176                 LIST_INSERT_HEAD(l, e, link);
00177         }
00178         inline Agent* detachHead(AgentList* l) {
00179                 AgentListElem *e = l->lh_first;
00180                 if (e == NULL)
00181                         return NULL;
00182                 Agent *a = e->agt_;
00183                 LIST_REMOVE(e, link);
00184                 delete e;
00185                 return a;
00186         }
00187         int nTcp_, nSink_;
00188         int dbTcp_a, dbTcp_r, dbTcp_cr;
00189         AgentList tcpPool_;     
00190         AgentList sinkPool_;    
00191 
00192         
00193         inline int lookup_rv(RandomVariable*& rv, const char* name) {
00194                 if (rv != NULL)
00195                         Tcl::instance().evalf("delete %s", rv->name());
00196                 rv = (RandomVariable*)lookup_obj(name);
00197                 return rv ? (TCL_OK) : (TCL_ERROR);
00198         }
00199         int debug_;
00200         
00201         int fulltcp_;
00202         
00203         int recycle_page_;
00204 
00205         int dont_recycle_; 
00206 };
00207 
00208 #endif // ns_webtraf_h
00209 
00210