Rev 2 of Thrift, the Pillar successor
Summary: End-to-end communications and serialization in C++ is working
Reviewed By: aditya
Test Plan: See the new top-level test/ folder. It vaguely resembles a unit test, though it could be more automated.
Revert Plan: Revertible
Notes: Still a LOT of optimization work to be done on the generated C++ code, which should be using dynamic memory in a number of places. Next major task is writing the PHP/Java/Python generators.
git-svn-id: https://svn.apache.org/repos/asf/incubator/thrift/trunk@664712 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/lib/cpp/server/TServer.h b/lib/cpp/server/TServer.h
new file mode 100644
index 0000000..9c4cc59
--- /dev/null
+++ b/lib/cpp/server/TServer.h
@@ -0,0 +1,36 @@
+#ifndef T_SERVER_H
+#define T_SERVER_H
+
+#include "TDispatcher.h"
+
+class TServerOptions;
+
+/**
+ * Thrift server.
+ *
+ * @author Mark Slee <mcslee@facebook.com>
+ */
+class TServer {
+ public:
+ virtual ~TServer() {}
+ virtual void run() = 0;
+
+ protected:
+ TServer(TDispatcher* dispatcher, TServerOptions* options) :
+ dispatcher_(dispatcher), options_(options) {}
+
+ TDispatcher* dispatcher_;
+ TServerOptions* options_;
+};
+
+/**
+ * Class to encapsulate all generic server options.
+ */
+class TServerOptions {
+ public:
+ // TODO(mcslee): Fill in getters/setters here
+ protected:
+ // TODO(mcslee): Fill data members in here
+};
+
+#endif
diff --git a/lib/cpp/server/TSimpleServer.cc b/lib/cpp/server/TSimpleServer.cc
new file mode 100644
index 0000000..16f5006
--- /dev/null
+++ b/lib/cpp/server/TSimpleServer.cc
@@ -0,0 +1,60 @@
+#include "server/TSimpleServer.h"
+#include <string>
+using namespace std;
+
+void TSimpleServer::run() {
+ TTransport* client;
+
+ // Start the server listening
+ if (serverTransport_->listen() == false) {
+ // TODO(mcslee): Log error here
+ fprintf(stderr, "TSimpleServer::run(): Call to listen failed\n");
+ return;
+ }
+
+ // Fetch client from server
+ while (true) {
+ // fprintf(stderr, "Listening for connection\n");
+ if ((client = serverTransport_->accept()) == NULL) {
+ // fprintf(stderr, "Got NULL connection, exiting.\n");
+ break;
+ }
+
+ while (true) {
+ // Read header from client
+ // fprintf(stderr, "Reading 4 byte header from client.\n");
+ string in;
+ if (client->read(in, 4) <= 0) {
+ // fprintf(stderr, "Size header negative. Exception!\n");
+ break;
+ }
+
+ // Read payload from client
+ int32_t size = *(int32_t*)(in.data());
+ // fprintf(stderr, "Reading %d byte payload from client.\n", size);
+ if (client->read(in, size) < size) {
+ // fprintf(stderr, "Didn't get enough data!!!\n");
+ break;
+ }
+
+ // Pass payload to dispatcher
+ // TODO(mcslee): Wrap this in try/catch and return exceptions
+ string out = dispatcher_->dispatch(in);
+
+ size = out.size();
+
+ // Write size of response packet
+ client->write(string((char*)&size, 4));
+
+ // Write response payload
+ client->write(out);
+ }
+
+ // Clean up that client
+ // fprintf(stderr, "Closing and cleaning up client\n");
+ client->close();
+ delete client;
+ }
+
+ // TODO(mcslee): Is this a timeout case or the real thing?
+}
diff --git a/lib/cpp/server/TSimpleServer.h b/lib/cpp/server/TSimpleServer.h
new file mode 100644
index 0000000..47ab69e
--- /dev/null
+++ b/lib/cpp/server/TSimpleServer.h
@@ -0,0 +1,30 @@
+#ifndef T_SIMPLE_SERVER_H
+#define T_SIMPLE_SERVER_H
+
+#include "server/TServer.h"
+#include "transport/TServerTransport.h"
+
+/**
+ * This is the most basic simple server. It is single-threaded and runs a
+ * continuous loop of accepting a single connection, processing requests on
+ * that connection until it closes, and then repeating. It is a good example
+ * of how to extend the TServer interface.
+ *
+ * @author Mark Slee <mcslee@facebook.com>
+ */
+class TSimpleServer : public TServer {
+ public:
+ TSimpleServer(TDispatcher* dispatcher,
+ TServerOptions* options,
+ TServerTransport* serverTransport) :
+ TServer(dispatcher, options), serverTransport_(serverTransport) {}
+
+ ~TSimpleServer() {}
+
+ void run();
+
+ protected:
+ TServerTransport* serverTransport_;
+};
+
+#endif