|
@@ -1,28 +1,30 @@
|
|
#include <signal.h>
|
|
#include <signal.h>
|
|
#include <cstdlib>
|
|
#include <cstdlib>
|
|
|
|
+#include <cstring>
|
|
#include <string>
|
|
#include <string>
|
|
#include <vector>
|
|
#include <vector>
|
|
#include <algorithm>
|
|
#include <algorithm>
|
|
-#include <mutex>
|
|
|
|
|
|
|
|
-#include <Wt/WServer>
|
|
|
|
-#include <Wt/WResource>
|
|
|
|
-#include <Wt/Http/Request>
|
|
|
|
-#include <Wt/Http/Response>
|
|
|
|
-#include <Wt/WTemplate>
|
|
|
|
-#include <Wt/Utils>
|
|
|
|
|
|
+#include <Wt/WServer.h>
|
|
|
|
+#include <Wt/WResource.h>
|
|
|
|
+#include <Wt/Http/Request.h>
|
|
|
|
+#include <Wt/Http/Response.h>
|
|
|
|
+#include <Wt/WTemplate.h>
|
|
|
|
+#include <Wt/Utils.h>
|
|
|
|
|
|
-#include <Wt/Dbo/Dbo>
|
|
|
|
-#include <Wt/Dbo/Json>
|
|
|
|
|
|
+#include <Wt/Dbo/Dbo.h>
|
|
|
|
+#include <Wt/Dbo/Json.h>
|
|
#ifndef BENCHMARK_USE_POSTGRES
|
|
#ifndef BENCHMARK_USE_POSTGRES
|
|
-#include <Wt/Dbo/backend/MySQL>
|
|
|
|
|
|
+#include <Wt/Dbo/backend/MySQL.h>
|
|
#else
|
|
#else
|
|
-#include <Wt/Dbo/backend/Postgres>
|
|
|
|
|
|
+#include <Wt/Dbo/backend/Postgres.h>
|
|
#endif
|
|
#endif
|
|
|
|
|
|
-#include <boost/random/uniform_int_distribution.hpp>
|
|
|
|
-#include <boost/random/taus88.hpp>
|
|
|
|
-#include <boost/thread/tss.hpp>
|
|
|
|
|
|
+#include <random>
|
|
|
|
+
|
|
|
|
+#ifndef WT_WIN32
|
|
|
|
+extern char **environ;
|
|
|
|
+#endif // WT_WIN32
|
|
|
|
|
|
class MyMessage {
|
|
class MyMessage {
|
|
public:
|
|
public:
|
|
@@ -113,20 +115,29 @@ public:
|
|
};
|
|
};
|
|
|
|
|
|
struct DbStruct {
|
|
struct DbStruct {
|
|
- MyConnection connection;
|
|
|
|
|
|
+ MyConnection *connection;
|
|
Wt::Dbo::Session session;
|
|
Wt::Dbo::Session session;
|
|
|
|
|
|
- boost::taus88 rng;
|
|
|
|
- boost::random::uniform_int_distribution<int> distribution;
|
|
|
|
|
|
+ std::default_random_engine rng;
|
|
|
|
+ std::uniform_int_distribution<int> distribution;
|
|
|
|
|
|
|
|
+ DbStruct()
|
|
|
|
+ : connection(0),
|
|
|
|
+ rng(clock()),
|
|
|
|
+ distribution(1, 10000) {
|
|
|
|
+ std::string dbHostStr = "localhost";
|
|
|
|
+ char *dbHost = std::getenv("DBHOST");
|
|
|
|
+ if (dbHost)
|
|
|
|
+ dbHostStr = std::string(dbHost);
|
|
#ifndef BENCHMARK_USE_POSTGRES
|
|
#ifndef BENCHMARK_USE_POSTGRES
|
|
- DbStruct() : connection("hello_world", "benchmarkdbuser", "benchmarkdbpass", "INSERT_DB_HOST_HERE", 3306),
|
|
|
|
|
|
+ auto c = Wt::cpp14::make_unique<MyConnection>("hello_world", "benchmarkdbuser", "benchmarkdbpass", dbHostStr, 3306);
|
|
#else
|
|
#else
|
|
- DbStruct() : connection("host=INSERT_DB_HOST_HERE port=5432 user=benchmarkdbuser password=benchmarkdbpass dbname=hello_world"),
|
|
|
|
|
|
+ auto connStr = std::string("host=") + dbHostStr + " port=5432 user=benchmarkdbuser password=benchmarkdbpass dbname=hello_world";
|
|
|
|
+ auto c = Wt::cpp14::make_unique<MyConnection>(connStr);
|
|
#endif
|
|
#endif
|
|
- rng(clock()),
|
|
|
|
- distribution(1, 10000) {
|
|
|
|
- session.setConnection(connection);
|
|
|
|
|
|
+
|
|
|
|
+ connection = c.get();
|
|
|
|
+ session.setConnection(std::move(c));
|
|
session.mapClass<World>("world");
|
|
session.mapClass<World>("world");
|
|
session.mapClass<Fortune>("fortune");
|
|
session.mapClass<Fortune>("fortune");
|
|
}
|
|
}
|
|
@@ -137,7 +148,7 @@ struct DbStruct {
|
|
};
|
|
};
|
|
|
|
|
|
namespace {
|
|
namespace {
|
|
- boost::thread_specific_ptr<DbStruct> dbStruct_;
|
|
|
|
|
|
+ thread_local DbStruct *dbStruct_;
|
|
}
|
|
}
|
|
|
|
|
|
class DbResource : public Wt::WResource {
|
|
class DbResource : public Wt::WResource {
|
|
@@ -146,14 +157,12 @@ public:
|
|
response.setMimeType("application/json");
|
|
response.setMimeType("application/json");
|
|
response.addHeader("Server", "Wt");
|
|
response.addHeader("Server", "Wt");
|
|
|
|
|
|
- DbStruct* db = dbStruct_.get();
|
|
|
|
- if (!db) {
|
|
|
|
- db = new DbStruct();
|
|
|
|
- dbStruct_.reset(db);
|
|
|
|
|
|
+ if (!dbStruct_) {
|
|
|
|
+ dbStruct_ = new DbStruct();
|
|
}
|
|
}
|
|
|
|
|
|
- Wt::Dbo::Transaction transaction(db->session);
|
|
|
|
- Wt::Dbo::ptr<World> entry = db->session.load<World>(db->rand());
|
|
|
|
|
|
+ Wt::Dbo::Transaction transaction(dbStruct_->session);
|
|
|
|
+ Wt::Dbo::ptr<World> entry = dbStruct_->session.load<World>(dbStruct_->rand());
|
|
|
|
|
|
Wt::Dbo::JsonSerializer writer(response.out());
|
|
Wt::Dbo::JsonSerializer writer(response.out());
|
|
writer.serialize(entry);
|
|
writer.serialize(entry);
|
|
@@ -177,17 +186,15 @@ public:
|
|
response.setMimeType("application/json");
|
|
response.setMimeType("application/json");
|
|
response.addHeader("Server", "Wt");
|
|
response.addHeader("Server", "Wt");
|
|
|
|
|
|
- DbStruct* db = dbStruct_.get();
|
|
|
|
- if (!db) {
|
|
|
|
- db = new DbStruct();
|
|
|
|
- dbStruct_.reset(db);
|
|
|
|
|
|
+ if (!dbStruct_) {
|
|
|
|
+ dbStruct_ = new DbStruct();
|
|
}
|
|
}
|
|
|
|
|
|
- Wt::Dbo::Transaction transaction(db->session);
|
|
|
|
|
|
+ Wt::Dbo::Transaction transaction(dbStruct_->session);
|
|
std::vector<Wt::Dbo::ptr<World> > results;
|
|
std::vector<Wt::Dbo::ptr<World> > results;
|
|
results.reserve(n);
|
|
results.reserve(n);
|
|
for (int i = 0; i < n; ++i) {
|
|
for (int i = 0; i < n; ++i) {
|
|
- results.push_back(db->session.load<World>(db->rand()));
|
|
|
|
|
|
+ results.push_back(dbStruct_->session.load<World>(dbStruct_->rand()));
|
|
}
|
|
}
|
|
Wt::Dbo::JsonSerializer writer(response.out());
|
|
Wt::Dbo::JsonSerializer writer(response.out());
|
|
writer.serialize(results);
|
|
writer.serialize(results);
|
|
@@ -206,7 +213,11 @@ private:
|
|
const VFortunes *fortunes_;
|
|
const VFortunes *fortunes_;
|
|
mutable std::vector<Wt::Dbo::ptr<Fortune> >::const_iterator it_;
|
|
mutable std::vector<Wt::Dbo::ptr<Fortune> >::const_iterator it_;
|
|
public:
|
|
public:
|
|
- FortuneTemplate(const std::vector<Wt::Dbo::ptr<Fortune> >& fortunes) : fortunes_(&fortunes), it_(fortunes.end()), Wt::WTemplate(Wt::WString::tr("fortunes")) {
|
|
|
|
|
|
+ FortuneTemplate(const std::vector<Wt::Dbo::ptr<Fortune> >& fortunes)
|
|
|
|
+ : Wt::WTemplate(tr("fortunes")),
|
|
|
|
+ fortunes_(&fortunes),
|
|
|
|
+ it_(fortunes.end())
|
|
|
|
+ {
|
|
addFunction("while", &Wt::WTemplate::Functions::while_f);
|
|
addFunction("while", &Wt::WTemplate::Functions::while_f);
|
|
}
|
|
}
|
|
|
|
|
|
@@ -229,7 +240,7 @@ public:
|
|
if (varName == "id")
|
|
if (varName == "id")
|
|
result << it_->id();
|
|
result << it_->id();
|
|
else if (varName == "message")
|
|
else if (varName == "message")
|
|
- format(result, Wt::WString::fromUTF8((*it_)->message));
|
|
|
|
|
|
+ format(result, Wt::WString((*it_)->message));
|
|
else
|
|
else
|
|
Wt::WTemplate::resolveString(varName, vars, result);
|
|
Wt::WTemplate::resolveString(varName, vars, result);
|
|
}
|
|
}
|
|
@@ -241,20 +252,18 @@ public:
|
|
response.setMimeType("text/html; charset=utf-8");
|
|
response.setMimeType("text/html; charset=utf-8");
|
|
response.addHeader("Server", "Wt");
|
|
response.addHeader("Server", "Wt");
|
|
|
|
|
|
- DbStruct* db = dbStruct_.get();
|
|
|
|
- if (!db) {
|
|
|
|
- db = new DbStruct();
|
|
|
|
- dbStruct_.reset(db);
|
|
|
|
|
|
+ if (!dbStruct_) {
|
|
|
|
+ dbStruct_ = new DbStruct();
|
|
}
|
|
}
|
|
|
|
|
|
- Wt::Dbo::Transaction transaction(db->session);
|
|
|
|
- Fortunes fortunes = db->session.find<Fortune>();
|
|
|
|
|
|
+ Wt::Dbo::Transaction transaction(dbStruct_->session);
|
|
|
|
+ Fortunes fortunes = dbStruct_->session.find<Fortune>();
|
|
VFortunes vFortunes;
|
|
VFortunes vFortunes;
|
|
for (Fortunes::const_iterator i = fortunes.begin(); i != fortunes.end(); ++i)
|
|
for (Fortunes::const_iterator i = fortunes.begin(); i != fortunes.end(); ++i)
|
|
vFortunes.push_back(*i);
|
|
vFortunes.push_back(*i);
|
|
- Fortune* additionalFortune = new Fortune();
|
|
|
|
|
|
+ auto additionalFortune = Wt::cpp14::make_unique<Fortune>();
|
|
additionalFortune->message = "Additional fortune added at request time.";
|
|
additionalFortune->message = "Additional fortune added at request time.";
|
|
- vFortunes.push_back(Wt::Dbo::ptr<Fortune>(additionalFortune));
|
|
|
|
|
|
+ vFortunes.push_back(Wt::Dbo::ptr<Fortune>(std::move(additionalFortune)));
|
|
|
|
|
|
std::sort(vFortunes.begin(), vFortunes.end(), fortuneCmp);
|
|
std::sort(vFortunes.begin(), vFortunes.end(), fortuneCmp);
|
|
|
|
|
|
@@ -282,10 +291,8 @@ public:
|
|
response.setMimeType("application/json");
|
|
response.setMimeType("application/json");
|
|
response.addHeader("Server", "Wt");
|
|
response.addHeader("Server", "Wt");
|
|
|
|
|
|
- DbStruct* db = dbStruct_.get();
|
|
|
|
- if (!db) {
|
|
|
|
- db = new DbStruct();
|
|
|
|
- dbStruct_.reset(db);
|
|
|
|
|
|
+ if (!dbStruct_) {
|
|
|
|
+ dbStruct_ = new DbStruct();
|
|
}
|
|
}
|
|
|
|
|
|
std::vector<Wt::Dbo::ptr<World> > results;
|
|
std::vector<Wt::Dbo::ptr<World> > results;
|
|
@@ -294,9 +301,9 @@ public:
|
|
bool success = false;
|
|
bool success = false;
|
|
while (!success) {
|
|
while (!success) {
|
|
try {
|
|
try {
|
|
- Wt::Dbo::Transaction transaction(db->session);
|
|
|
|
- Wt::Dbo::ptr<World> world = db->session.load<World>(db->rand());
|
|
|
|
- world.modify()->randomNumber = db->rand();
|
|
|
|
|
|
+ Wt::Dbo::Transaction transaction(dbStruct_->session);
|
|
|
|
+ Wt::Dbo::ptr<World> world = dbStruct_->session.load<World>(dbStruct_->rand());
|
|
|
|
+ world.modify()->randomNumber = dbStruct_->rand();
|
|
transaction.commit();
|
|
transaction.commit();
|
|
results.push_back(world);
|
|
results.push_back(world);
|
|
success = true;
|
|
success = true;
|
|
@@ -323,12 +330,13 @@ class PlaintextResource : public Wt::WResource {
|
|
int main(int argc, char** argv) {
|
|
int main(int argc, char** argv) {
|
|
try {
|
|
try {
|
|
Wt::WServer server(argv[0]);
|
|
Wt::WServer server(argv[0]);
|
|
- Wt::WMessageResourceBundle *bundle = new Wt::WMessageResourceBundle();
|
|
|
|
- bundle->use("fortunes");
|
|
|
|
- server.setLocalizedStrings(bundle);
|
|
|
|
|
|
|
|
server.setServerConfiguration(argc, argv, WTHTTP_CONFIGURATION);
|
|
server.setServerConfiguration(argc, argv, WTHTTP_CONFIGURATION);
|
|
|
|
|
|
|
|
+ auto bundle = std::make_shared<Wt::WMessageResourceBundle>();
|
|
|
|
+ bundle->use(server.appRoot() + "fortunes");
|
|
|
|
+ server.setLocalizedStrings(bundle);
|
|
|
|
+
|
|
JsonResource jsonResource;
|
|
JsonResource jsonResource;
|
|
server.addResource(&jsonResource, "/json");
|
|
server.addResource(&jsonResource, "/json");
|
|
|
|
|
|
@@ -348,13 +356,15 @@ int main(int argc, char** argv) {
|
|
server.addResource(&plaintextResource, "/plaintext");
|
|
server.addResource(&plaintextResource, "/plaintext");
|
|
|
|
|
|
if (server.start()) {
|
|
if (server.start()) {
|
|
- int sig = Wt::WServer::waitForShutdown(argv[0]);
|
|
|
|
|
|
+ int sig = Wt::WServer::waitForShutdown();
|
|
|
|
|
|
std::cerr << "Shutdown (signal = " << sig << ")" << std::endl;
|
|
std::cerr << "Shutdown (signal = " << sig << ")" << std::endl;
|
|
server.stop();
|
|
server.stop();
|
|
|
|
|
|
|
|
+#ifndef WT_WIN32
|
|
if (sig == SIGHUP)
|
|
if (sig == SIGHUP)
|
|
Wt::WServer::restart(argc, argv, environ);
|
|
Wt::WServer::restart(argc, argv, environ);
|
|
|
|
+#endif // WT_WIN32
|
|
}
|
|
}
|
|
} catch (Wt::WServer::Exception& e) {
|
|
} catch (Wt::WServer::Exception& e) {
|
|
std::cerr << e.what() << "\n";
|
|
std::cerr << e.what() << "\n";
|