/* Web Polygraph       http://www.web-polygraph.org/
 * (C) 2003-2006 The Measurement Factory
 * Licensed under the Apache License, Version 2.0 */

#ifndef POLYGRAPH__RUNTIME_XACTION_H
#define POLYGRAPH__RUNTIME_XACTION_H

#include "xstd/Error.h"
#include "xstd/FileScanner.h"
#include "xstd/Checksum.h"
#include "base/ObjId.h"
#include "runtime/RepSize.h"
#include "runtime/XactAbortCoord.h"
#include "runtime/Connection.h"

class IOBuf;
class Agent;
class RndDistr;

class Xaction: public FileScanUser {
	public:
		static int TheSampleDebt; // log xactions until no debt

	public:
		virtual void reset(); // XXX: split into local/virtual reset

		const UniqId &id() const { return theId; }
		const ObjId &oid() const { return theOid; }
		Connection *conn() { return theConn; }
		int logCat() const { return theLogCat; }
		bool started() const { return theStartTime > 0; }
		bool finished() const { return theState == stDone; }
		bool sslConfigured() const { return theConn && theConn->sslConfigured(); }
		bool sslActive() const { return theConn && theConn->sslActive(); }

		void countSuccess();
		void countFailure();

		const RepSize &repSize() const { return theRepSize; }
		Time queueTime() const { return theEnqueTime > 0 ? theStartTime - theEnqueTime : Time::Sec(0); }
		Time lifeTime() const { return theLifeTime; }
		int httpStatus() const { return theHttpStatus; }

		virtual bool needRetry() const { return false; }

		void oid(const ObjId &anOid) { theOid = anOid; }

	protected:
		enum State { stNone = 0,
			// for CONNECT tunnels
			stTunnelConnWaiting, stTunnelSpaceWaiting, stTunnelRespWaiting,
			// for all transactions
			stConnWaiting,
			stSpaceWaiting, stHdrWaiting, stBodyWaiting, stDone };

	protected:
		virtual Agent *owner() = 0;
		virtual void newState(State aState);

		void start(Connection *conn);
		virtual void finish(Error err);

		bool abortBeforeIo() const;
		bool abortAfterIo(Size size);
		bool abortIo(Connection::IoMethod m, Size *size = 0);
		virtual void abortNow();

		RndDistr *seedOidDistr(RndDistr *raw, int globSeed);

		void logStats();
		virtual void logStats(OLog &ol) const;

		void printMsg(const IOBuf &buf) const;
		void printMsg(const IOBuf &buf, Size maxSize) const;
		void printMsg(const char *buf, Size maxSize) const;
		void printXactLogEntry() const;

	protected:
		static int TheCount; // to report xaction "position"

	protected:
		Connection *theConn;
		UniqId theId;

		Time theEnqueTime;  // put in a queue (optional)
		Time theStartTime;  // started doing something
		Time theLifeTime;   // [start, stop]; set in stop()
		ObjId theOid;       // various details about the transfered object
		RepSize theRepSize; // reply size
		Size theReqSize;    // request size
		Size theAbortSize;  // decremented on each I/O; abort if zero
		XactAbortCoord theAbortCoord; // other side abort coordinates
		ChecksumAlg theCheckAlg; // not used by default
		int theHttpStatus;
		int theLogCat;      // log entry category

		State theState;
};

#endif


syntax highlighted by Code2HTML, v. 0.9.1