aboutsummaryrefslogtreecommitdiff
path: root/brep
diff options
context:
space:
mode:
authorKaren Arutyunov <karen@codesynthesis.com>2016-03-06 13:52:48 +0300
committerKaren Arutyunov <karen@codesynthesis.com>2016-03-07 00:05:29 +0300
commitb72424fca7a6af6ff7921101c450850fef875152 (patch)
treeac295d1e228379b1b31c6af3a84e7057f2ea96ae /brep
parent0f9c65e489a7b59f76ccbf2ca6e76ab0a1012932 (diff)
Support multiple instances of brep in a single Apache instance
Diffstat (limited to 'brep')
-rw-r--r--brep/database.cxx58
-rw-r--r--brep/mod-package-details8
-rw-r--r--brep/mod-package-details.cxx23
-rw-r--r--brep/mod-package-search8
-rw-r--r--brep/mod-package-search.cxx23
-rw-r--r--brep/mod-package-version-details8
-rw-r--r--brep/mod-package-version-details.cxx21
-rw-r--r--brep/mod-repository-details8
-rw-r--r--brep/mod-repository-details.cxx21
-rw-r--r--brep/mod-repository-root6
-rw-r--r--brep/mod-repository-root.cxx33
-rw-r--r--brep/module2
-rw-r--r--brep/module.cxx12
13 files changed, 171 insertions, 60 deletions
diff --git a/brep/database.cxx b/brep/database.cxx
index 9177b55..17605c5 100644
--- a/brep/database.cxx
+++ b/brep/database.cxx
@@ -4,40 +4,50 @@
#include <brep/database>
+#include <map>
+
#include <odb/pgsql/database.hxx>
namespace brep
{
+ namespace options
+ {
+ bool
+ operator< (const db& x, const db& y)
+ {
+ int r;
+ if ((r = x.db_user ().compare (y.db_user ())) != 0 ||
+ (r = x.db_password ().compare (y.db_password ())) != 0 ||
+ (r = x.db_name ().compare (y.db_name ())) != 0 ||
+ (r = x.db_host ().compare (y.db_host ())))
+ return r < 0;
+
+ return x.db_port () < y.db_port ();
+ }
+ }
+
shared_ptr<odb::database>
shared_database (const options::db& o)
{
using odb::pgsql::database;
- static weak_ptr<database> db;
- // In C++11, function-static variable initialization is guaranteed to be
- // thread-safe, thought this doesn't seem to be enough in our case
- // (because we are re-initializing the weak pointer).
- //
- if (shared_ptr<database> d = db.lock ())
- {
- if (o.db_user () != d->user () ||
- o.db_password () != d->password () ||
- o.db_name () != d->db () ||
- o.db_host () != d->host () ||
- o.db_port () != d->port ())
- throw runtime_error ("shared database options mismatch");
-
- return d;
- }
- else
+ static std::map<options::db, weak_ptr<database>> databases;
+
+ auto i (databases.find (o));
+ if (i != databases.end ())
{
- d = make_shared<database> (o.db_user (),
- o.db_password (),
- o.db_name (),
- o.db_host (),
- o.db_port ());
- db = d;
- return d;
+ if (shared_ptr<database> d = i->second.lock ())
+ return d;
}
+
+ shared_ptr<database> d (
+ make_shared<database> (o.db_user (),
+ o.db_password (),
+ o.db_name (),
+ o.db_host (),
+ o.db_port ()));
+
+ databases[o] = d;
+ return d;
}
}
diff --git a/brep/mod-package-details b/brep/mod-package-details
index a99d271..0a86fc2 100644
--- a/brep/mod-package-details
+++ b/brep/mod-package-details
@@ -18,6 +18,14 @@ namespace brep
class package_details: public module
{
public:
+ package_details () = default;
+
+ // Create a shallow copy (handling instance) if initialized and a deep
+ // copy (context exemplar) otherwise.
+ //
+ explicit
+ package_details (const package_details&);
+
virtual bool
handle (request&, response&);
diff --git a/brep/mod-package-details.cxx b/brep/mod-package-details.cxx
index fa07dd1..a5c2e3e 100644
--- a/brep/mod-package-details.cxx
+++ b/brep/mod-package-details.cxx
@@ -24,6 +24,18 @@
using namespace odb::core;
using namespace brep::cli;
+// While currently the user-defined copy constructor is not required (we don't
+// need to deep copy nullptr's), it is a good idea to keep the placeholder
+// ready for less trivial cases.
+//
+brep::package_details::
+package_details (const package_details& r)
+ : module (r),
+ options_ (r.initialized_ ? r.options_ : nullptr),
+ db_ (r.initialized_ ? r.db_ : nullptr)
+{
+}
+
void brep::package_details::
init (scanner& s)
{
@@ -61,13 +73,8 @@ handle (request& rq, response& rs)
MODULE_DIAG;
- // The module options object is not changed after being created once per
- // server process.
- //
- static const size_t res_page (options_->search_results ());
- static const dir_path& root (options_->root ());
- static const fragment& logo (options_->logo ());
- static const vector<page_menu>& menu (options_->menu ());
+ const size_t res_page (options_->search_results ());
+ const dir_path& root (options_->root ());
const string& name (*rq.path ().rbegin ());
const string ename (mime_url_encode (name));
@@ -130,7 +137,7 @@ handle (request& rq, response& rs)
<< SCRIPT << " " << ~SCRIPT
<< ~HEAD
<< BODY
- << DIV_HEADER (root, logo, menu)
+ << DIV_HEADER (root, options_->logo (), options_->menu ())
<< DIV(ID="content");
if (full)
diff --git a/brep/mod-package-search b/brep/mod-package-search
index 7db976b..1730be4 100644
--- a/brep/mod-package-search
+++ b/brep/mod-package-search
@@ -18,6 +18,14 @@ namespace brep
class package_search: public module
{
public:
+ package_search () = default;
+
+ // Create a shallow copy (handling instance) if initialized and a deep
+ // copy (context exemplar) otherwise.
+ //
+ explicit
+ package_search (const package_search&);
+
virtual bool
handle (request&, response&);
diff --git a/brep/mod-package-search.cxx b/brep/mod-package-search.cxx
index 7505e02..77a06b6 100644
--- a/brep/mod-package-search.cxx
+++ b/brep/mod-package-search.cxx
@@ -27,6 +27,18 @@
using namespace odb::core;
using namespace brep::cli;
+// While currently the user-defined copy constructor is not required (we don't
+// need to deep copy nullptr's), it is a good idea to keep the placeholder
+// ready for less trivial cases.
+//
+brep::package_search::
+package_search (const package_search& r)
+ : module (r),
+ options_ (r.initialized_ ? r.options_ : nullptr),
+ db_ (r.initialized_ ? r.db_ : nullptr)
+{
+}
+
void brep::package_search::
init (scanner& s)
{
@@ -74,13 +86,8 @@ handle (request& rq, response& rs)
MODULE_DIAG;
- // The module options object is not changed after being created once per
- // server process.
- //
- static const size_t res_page (options_->search_results ());
- static const dir_path& root (options_->root ());
- static const fragment& logo (options_->logo ());
- static const vector<page_menu>& menu (options_->menu ());
+ const size_t res_page (options_->search_results ());
+ const dir_path& root (options_->root ());
params::package_search params;
@@ -124,7 +131,7 @@ handle (request& rq, response& rs)
<< SCRIPT << " " << ~SCRIPT
<< ~HEAD
<< BODY
- << DIV_HEADER (root, logo, menu)
+ << DIV_HEADER (root, options_->logo (), options_->menu ())
<< DIV(ID="content");
session sn;
diff --git a/brep/mod-package-version-details b/brep/mod-package-version-details
index d102fdf..cfbcf94 100644
--- a/brep/mod-package-version-details
+++ b/brep/mod-package-version-details
@@ -18,6 +18,14 @@ namespace brep
class package_version_details: public module
{
public:
+ package_version_details () = default;
+
+ // Create a shallow copy (handling instance) if initialized and a deep
+ // copy (context exemplar) otherwise.
+ //
+ explicit
+ package_version_details (const package_version_details&);
+
virtual bool
handle (request&, response&);
diff --git a/brep/mod-package-version-details.cxx b/brep/mod-package-version-details.cxx
index c9055a5..cbf9c86 100644
--- a/brep/mod-package-version-details.cxx
+++ b/brep/mod-package-version-details.cxx
@@ -25,6 +25,18 @@ using namespace std;
using namespace odb::core;
using namespace brep::cli;
+// While currently the user-defined copy constructor is not required (we don't
+// need to deep copy nullptr's), it is a good idea to keep the placeholder
+// ready for less trivial cases.
+//
+brep::package_version_details::
+package_version_details (const package_version_details& r)
+ : module (r),
+ options_ (r.initialized_ ? r.options_ : nullptr),
+ db_ (r.initialized_ ? r.db_ : nullptr)
+{
+}
+
void brep::package_version_details::
init (scanner& s)
{
@@ -48,12 +60,7 @@ handle (request& rq, response& rs)
MODULE_DIAG;
- // The module options object is not changed after being created once per
- // server process.
- //
- static const dir_path& root (options_->root ());
- static const fragment& logo (options_->logo ());
- static const vector<page_menu>& menu (options_->menu ());
+ const dir_path& root (options_->root ());
auto i (rq.path ().rbegin ());
version ver;
@@ -107,7 +114,7 @@ handle (request& rq, response& rs)
<< CSS_LINKS (path ("package-version-details.css"), root)
<< ~HEAD
<< BODY
- << DIV_HEADER (root, logo, menu)
+ << DIV_HEADER (root, options_->logo (), options_->menu ())
<< DIV(ID="content");
if (full)
diff --git a/brep/mod-repository-details b/brep/mod-repository-details
index 5f1e93f..411d9e6 100644
--- a/brep/mod-repository-details
+++ b/brep/mod-repository-details
@@ -18,6 +18,14 @@ namespace brep
class repository_details: public module
{
public:
+ repository_details () = default;
+
+ // Create a shallow copy (handling instance) if initialized and a deep
+ // copy (context exemplar) otherwise.
+ //
+ explicit
+ repository_details (const repository_details&);
+
virtual bool
handle (request&, response&);
diff --git a/brep/mod-repository-details.cxx b/brep/mod-repository-details.cxx
index 0a88a16..f040be6 100644
--- a/brep/mod-repository-details.cxx
+++ b/brep/mod-repository-details.cxx
@@ -31,6 +31,18 @@ using namespace std;
using namespace odb::core;
using namespace brep::cli;
+// While currently the user-defined copy constructor is not required (we don't
+// need to deep copy nullptr's), it is a good idea to keep the placeholder
+// ready for less trivial cases.
+//
+brep::repository_details::
+repository_details (const repository_details& r)
+ : module (r),
+ options_ (r.initialized_ ? r.options_ : nullptr),
+ db_ (r.initialized_ ? r.db_ : nullptr)
+{
+}
+
void brep::repository_details::
init (scanner& s)
{
@@ -54,12 +66,7 @@ handle (request& rq, response& rs)
MODULE_DIAG;
- // The module options object is not changed after being created once per
- // server process.
- //
- static const dir_path& root (options_->root ());
- static const fragment& logo (options_->logo ());
- static const vector<page_menu>& menu (options_->menu ());
+ const dir_path& root (options_->root ());
// Make sure no parameters passed.
//
@@ -82,7 +89,7 @@ handle (request& rq, response& rs)
<< CSS_LINKS (path ("repository-details.css"), root)
<< ~HEAD
<< BODY
- << DIV_HEADER (root, logo, menu)
+ << DIV_HEADER (root, options_->logo (), options_->menu ())
<< DIV(ID="content");
transaction t (db_->begin ());
diff --git a/brep/mod-repository-root b/brep/mod-repository-root
index 254dfa3..f2c2ba0 100644
--- a/brep/mod-repository-root
+++ b/brep/mod-repository-root
@@ -23,6 +23,12 @@ namespace brep
public:
repository_root ();
+ // Create a shallow copy (handling instance) if initialized and a deep
+ // copy (context exemplar) otherwise.
+ //
+ explicit
+ repository_root (const repository_root&);
+
private:
virtual bool
handle (request&, response&);
diff --git a/brep/mod-repository-root.cxx b/brep/mod-repository-root.cxx
index 61aa71b..7c27a60 100644
--- a/brep/mod-repository-root.cxx
+++ b/brep/mod-repository-root.cxx
@@ -58,6 +58,37 @@ namespace brep
{
}
+ repository_root::
+ repository_root (const repository_root& r)
+ : module (r),
+ //
+ // Deep/shallow-copy sub-modules depending on whether this is an
+ // exemplar/handler.
+ //
+ package_search_ (
+ r.initialized_
+ ? r.package_search_
+ : make_shared<package_search> (*r.package_search_)),
+ package_details_ (
+ r.initialized_
+ ? r.package_details_
+ : make_shared<package_details> (*r.package_details_)),
+ package_version_details_ (
+ r.initialized_
+ ? r.package_version_details_
+ : make_shared<package_version_details> (
+ *r.package_version_details_)),
+ repository_details_ (
+ r.initialized_
+ ? r.repository_details_
+ : make_shared<repository_details> (*r.repository_details_)),
+ options_ (
+ r.initialized_
+ ? r.options_
+ : nullptr)
+ {
+ }
+
// Return amalgamation of repository_root and all its sub-modules option
// descriptions.
//
@@ -112,7 +143,7 @@ namespace brep
{
MODULE_DIAG;
- static const dir_path& root (options_->root ());
+ const dir_path& root (options_->root ());
const path& rpath (rq.path ());
if (!rpath.sub (root))
diff --git a/brep/module b/brep/module
index 4ea5164..52106cd 100644
--- a/brep/module
+++ b/brep/module
@@ -88,7 +88,7 @@ namespace brep
// Set to true when the module is successfully initialized.
//
- bool loaded_ {false};
+ bool initialized_ {false};
// Implementation details.
//
diff --git a/brep/module.cxx b/brep/module.cxx
index e8a824d..1257d82 100644
--- a/brep/module.cxx
+++ b/brep/module.cxx
@@ -30,7 +30,7 @@ namespace brep
try
{
- if (!loaded_)
+ if (!initialized_)
{
MODULE_DIAG;
fail << "not initialized, presumably due to misconfiguration";
@@ -187,7 +187,7 @@ namespace brep
void module::
init (const name_values& options, log& log)
{
- assert (!loaded_);
+ assert (!initialized_);
log_ = &log;
@@ -207,7 +207,7 @@ namespace brep
options::module o (s, cli::unknown_mode::fail, cli::unknown_mode::fail);
verb_ = o.verbosity ();
- loaded_ = true;
+ initialized_ = true;
}
catch (const server_error& e)
{
@@ -236,7 +236,11 @@ namespace brep
// Custom copy constructor is required to initialize log_writer_ properly.
//
module::
- module (const module& m): module () {verb_ = m.verb_; loaded_ = m.loaded_;}
+ module (const module& m): module ()
+ {
+ verb_ = m.verb_;
+ initialized_ = m.initialized_;
+ }
// For function func declared like this:
// using B = std::string (*)(int);