Implement a database connection pool
[?]
May 29, 2015, 6:55 PM
YZAI5GQU3HNMK5MEGF2Y7WS445AN4YKD3HNJQVQP545ODN3F5DLACDependencies
- [2]
62MQPRXCPass null values to libpqxx properly - [3]
T2EIYJNGOn SIGINT, shut down the builder threads - [4]
ENXUSMSVMake concurrency more robust - [5]
NJJ7H64SVery basic multi-threaded queue runner - [6]
24BMQDZAStart of single-process hydra-queue-runner
Change contents
- edit in src/hydra-queue-runner/hydra-queue-runner.cc at line 12
#include "pool.hh" - replacement in src/hydra-queue-runner/hydra-queue-runner.cc at line 149
std::mutex queueMonitorMutex;/* CV for waking up the queue. */ - edit in src/hydra-queue-runner/hydra-queue-runner.cc at line 152
std::mutex queueMonitorMutex; - edit in src/hydra-queue-runner/hydra-queue-runner.cc at line 170
/* PostgreSQL connection pool. */Pool<Connection> dbPool; - replacement in src/hydra-queue-runner/hydra-queue-runner.cc at line 179
void markActiveBuildStepsAsAborted(pqxx::connection & conn, time_t stopTime);void markActiveBuildStepsAsAborted(time_t stopTime); - replacement in src/hydra-queue-runner/hydra-queue-runner.cc at line 191
void getQueuedBuilds(std::shared_ptr<StoreAPI> store, pqxx::connection & conn);void getQueuedBuilds(std::shared_ptr<StoreAPI> store); - edit in src/hydra-queue-runner/hydra-queue-runner.cc at line 222
Connection conn; - replacement in src/hydra-queue-runner/hydra-queue-runner.cc at line 223
markActiveBuildStepsAsAborted(conn, time(0));markActiveBuildStepsAsAborted(time(0)); - replacement in src/hydra-queue-runner/hydra-queue-runner.cc at line 230
void State::markActiveBuildStepsAsAborted(pqxx::connection & conn, time_t stopTime)void State::markActiveBuildStepsAsAborted(time_t stopTime) - replacement in src/hydra-queue-runner/hydra-queue-runner.cc at line 232
pqxx::work txn(conn);auto conn(dbPool.get());pqxx::work txn(*conn); - edit in src/hydra-queue-runner/hydra-queue-runner.cc at line 280
Connection conn; - replacement in src/hydra-queue-runner/hydra-queue-runner.cc at line 282
getQueuedBuilds(store, conn);getQueuedBuilds(store); - replacement in src/hydra-queue-runner/hydra-queue-runner.cc at line 294
void State::getQueuedBuilds(std::shared_ptr<StoreAPI> store, pqxx::connection & conn)void State::getQueuedBuilds(std::shared_ptr<StoreAPI> store) - edit in src/hydra-queue-runner/hydra-queue-runner.cc at line 297
auto conn(dbPool.get()); - replacement in src/hydra-queue-runner/hydra-queue-runner.cc at line 317
pqxx::work txn(conn);pqxx::work txn(*conn); - replacement in src/hydra-queue-runner/hydra-queue-runner.cc at line 349
pqxx::work txn(conn);pqxx::work txn(*conn); - replacement in src/hydra-queue-runner/hydra-queue-runner.cc at line 369
pqxx::work txn(conn);pqxx::work txn(*conn); - replacement in src/hydra-queue-runner/hydra-queue-runner.cc at line 627
Connection conn;auto conn(dbPool.get()); - replacement in src/hydra-queue-runner/hydra-queue-runner.cc at line 631
pqxx::work txn(conn);pqxx::work txn(*conn); - replacement in src/hydra-queue-runner/hydra-queue-runner.cc at line 677
pqxx::work txn(conn);pqxx::work txn(*conn); - replacement in src/hydra-queue-runner/hydra-queue-runner.cc at line 766
{Connection conn;markActiveBuildStepsAsAborted(conn, 0);}markActiveBuildStepsAsAborted(0); - edit in src/hydra-queue-runner/hydra-queue-runner.cc at line 791
printMsg(lvlError, format("psql connections = %1%") % dbPool.count()); - file addition: pool.hh[4.187]
#pragma once#include <memory>#include <list>#include "sync.hh"/* This template class implements a simple pool manager of resourcesof some type R, such as database connections. It is used asfollows:class Connection { ... };Pool<Connection> pool;{auto conn(pool.get());conn->exec("select ...");}Here, the Connection object referenced by ‘conn’ is automaticallyreturned to the pool when ‘conn’ goes out of scope.*/template <class R>class Pool{private:struct State{unsigned int count = 0;std::list<std::shared_ptr<R>> idle;};Sync<State> state;public:class Handle{private:Pool & pool;std::shared_ptr<R> r;friend Pool;Handle(Pool & pool, std::shared_ptr<R> r) : pool(pool), r(r) { }public:Handle(Handle && h) : pool(h.pool), r(h.r) { h.r.reset(); }Handle(const Handle & l) = delete;~Handle(){auto state_(pool.state.lock());if (r) state_->idle.push_back(r);}R * operator -> () { return r; }R & operator * () { return *r; }};Handle get(){{auto state_(state.lock());if (!state_->idle.empty()) {auto p = state_->idle.back();state_->idle.pop_back();return Handle(*this, p);}state_->count++;}/* Note: we don't hold the lock while creating a new instance,because creation might take a long time. */return Handle(*this, std::make_shared<R>());}unsigned int count(){auto state_(state.lock());return state_->count;}};