-- TFileTransport (Thrift Logfile)

Summary:
-- TBufferedFileWriter.h/cpp will be renamed to TFileTransport.h/cpp in the next commit.
-- TFileTransport is essentially reading and writing thrift calls to/from a file instead of a
   socket.
-- The code/design is somewhat similar to pillar_logfile but there are some significant changes.

todo:
-- still need to do error correction/detection

Reviewed By: Mark Slee

Test Plan:
-- Wrote test in thrift/test/cpp/src/main.cpp that appends to a file and replays requests

Notes:
It's finally time to port search over to Thrift


git-svn-id: https://svn.apache.org/repos/asf/incubator/thrift/trunk@664889 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/test/cpp/src/main.cpp b/test/cpp/src/main.cpp
index 8344a88..47ae671 100644
--- a/test/cpp/src/main.cpp
+++ b/test/cpp/src/main.cpp
@@ -11,6 +11,7 @@
 #include <transport/TTransportUtils.h>
 #include <transport/TBufferedRouterTransport.h>
 #include <transport/TBufferedFileWriter.h>
+#include <TLogging.h>
 
 #include "Service.h"
 
@@ -73,7 +74,12 @@
   int8_t echoByte(int8_t arg) {return arg;}
   int32_t echoI32(int32_t arg) {return arg;}
   int64_t echoI64(int64_t arg) {return arg;}
-  string echoString(string arg) {return arg;}
+  string echoString(string arg) {
+    if (arg != "hello") {
+      T_ERROR_ABORT("WRONG STRING!!!!");
+    }
+    return arg;
+  }
   vector<int8_t> echoList(vector<int8_t> arg) {return arg;}
   set<int8_t> echoSet(set<int8_t> arg) {return arg;}
   map<int8_t, int8_t> echoMap(map<int8_t, int8_t> arg) {return arg;}
@@ -189,20 +195,22 @@
   bool _done;
   Monitor _sleep;
 };
-    
+
+
 int main(int argc, char **argv) {
 
-  int port = 9090;
+  int port = 9091;
   string serverType = "thread-pool";
   string protocolType = "binary";
   size_t workerCount = 4;
-  size_t clientCount = 10;
-  size_t loopCount = 10000;
+  size_t clientCount = 20;
+  size_t loopCount = 50000;
   TType loopType  = T_VOID;
   string callName = "echoVoid";
   bool runServer = true;
   bool logRequests = false;
   string requestLogPath = "./requestlog.tlog";
+  bool replayRequests = false;
 
   ostringstream usage;
 
@@ -217,8 +225,10 @@
     "\tserver-type    Type of server, \"simple\" or \"thread-pool\".  Default is " << serverType << endl <<
     "\tprotocol-type  Type of protocol, \"binary\", \"ascii\", or \"xml\".  Default is " << protocolType << endl <<
     "\tlog-request    Log all request to ./requestlog.tlog. Default is " << logRequests << endl <<
+    "\treplay-request Replay requests from log file (./requestlog.tlog) Default is " << replayRequests << endl <<
     "\tworkers        Number of thread pools workers.  Only valid for thread-pool server type.  Default is " << workerCount << endl;
     
+        
   map<string, string>  args;
   
   for(int ix = 1; ix < argc; ix++) {
@@ -272,6 +282,10 @@
       logRequests = args["log-request"] == "true";
     }
 
+    if(!args["replay-request"].empty()) {
+      replayRequests = args["replay-request"] == "true";
+    }
+
     if(!args["server-type"].empty()) {
       serverType = args["server-type"];
       
@@ -299,6 +313,28 @@
   // Dispatcher
   shared_ptr<Server> serviceHandler(new Server());
 
+  if (replayRequests) {
+    shared_ptr<Server> serviceHandler(new Server());
+    shared_ptr<ServiceProcessor> serviceProcessor(new ServiceProcessor(serviceHandler));
+  
+    // Transports
+    shared_ptr<TFileTransport> fileTransport(new TFileTransport(requestLogPath));
+    fileTransport->setChunkSize(2 * 1024 * 1024);
+    fileTransport->setMaxEventSize(1024 * 16);
+    fileTransport->seekToEnd();
+
+    // Protocol Factory
+    shared_ptr<TProtocolFactory> protocolFactory(new TBinaryProtocolFactory());
+
+    TFileProcessor fileProcessor(serviceProcessor,
+                                 protocolFactory,
+                                 fileTransport);
+
+    fileProcessor.process(0, true);                                     
+    exit(0);
+  }
+
+
   if(runServer) {
 
     shared_ptr<ServiceProcessor> serviceProcessor(new ServiceProcessor(serviceHandler));
@@ -314,11 +350,12 @@
 
     if (logRequests) {
       // initialize the log file
-      shared_ptr<TBufferedFileWriter> bufferedFileWriter(new TBufferedFileWriter(requestLogPath, 1000));
-      bufferedFileWriter->setChunkSize(2 * 1024 * 1024);
-      bufferedFileWriter->setMaxEventSize(1024 * 16);
+      shared_ptr<TFileTransport> fileTransport(new TFileTransport(requestLogPath));
+      fileTransport->setChunkSize(2 * 1024 * 1024);
+      fileTransport->setMaxEventSize(1024 * 16);
       
-      transportFactory = shared_ptr<TTransportFactory>(new TBufferedRouterTransportFactory(bufferedFileWriter));
+      transportFactory = 
+        shared_ptr<TTransportFactory>(new TBufferedRouterTransportFactory(fileTransport));
     }
 
     shared_ptr<Thread> serverThread;