summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjsdelfino <jsdelfino@13f79535-47bb-0310-9956-ffa450edef68>2010-08-22 05:02:11 +0000
committerjsdelfino <jsdelfino@13f79535-47bb-0310-9956-ffa450edef68>2010-08-22 05:02:11 +0000
commit3c98b27f754a3ef97a8b0a02ecfd0ac1aa6e1fe5 (patch)
tree085366a1d1bb269197cf1c1844176ed784eff4be
parentb70da6b982209e43079708df1da43ae4054f3d80 (diff)
Improve performance by reusing HTTP proxy connections across invocations and using local function proxies instead of HTTP proxies for local wires.
git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@987845 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r--sca-cpp/trunk/modules/http/http.hpp7
-rw-r--r--sca-cpp/trunk/modules/http/httpd.hpp75
-rw-r--r--sca-cpp/trunk/modules/http/mod-ssltunnel.cpp4
-rw-r--r--sca-cpp/trunk/modules/scdl/scdl.hpp36
-rw-r--r--sca-cpp/trunk/modules/server/mod-cpp.hpp2
-rw-r--r--sca-cpp/trunk/modules/server/mod-eval.hpp75
-rw-r--r--sca-cpp/trunk/modules/server/mod-scheme.hpp2
-rw-r--r--sca-cpp/trunk/modules/server/mod-wiring.cpp17
-rw-r--r--sca-cpp/trunk/samples/store-cluster/domains/jane/store.composite4
-rw-r--r--sca-cpp/trunk/samples/store-cluster/domains/joe/store.composite4
10 files changed, 186 insertions, 40 deletions
diff --git a/sca-cpp/trunk/modules/http/http.hpp b/sca-cpp/trunk/modules/http/http.hpp
index b6de790028..6180518e23 100644
--- a/sca-cpp/trunk/modules/http/http.hpp
+++ b/sca-cpp/trunk/modules/http/http.hpp
@@ -314,9 +314,9 @@ const failable<value> evalExpr(const value& expr, const string& url, const CURLS
// Parse and return JSON-RPC result
const failable<value> rval = json::jsonResultValue(cadr<list<string> >(content(res)), cx);
+ debug(rval, "http::evalExpr::result");
if (!hasContent(rval))
return mkfailure<value>(reason(rval));
- debug(content(rval), "http::evalExpr::result");
return content(rval);
}
@@ -602,21 +602,22 @@ const failable<int> recv(char* c, const int l, const CURLSession& cs) {
* HTTP client proxy function.
*/
struct proxy {
- proxy(const string& uri, const string& ca, const string& cert, const string& key) : uri(uri), ca(ca), cert(cert), key(key) {
+ proxy(const string& uri, const string& ca, const string& cert, const string& key, const gc_pool& p) : p(p), uri(uri), ca(ca), cert(cert), key(key), cs(*(new (gc_new<CURLSession>(p)) CURLSession(ca, cert, key))) {
}
const value operator()(const list<value>& args) const {
- CURLSession cs(ca, cert, key);
failable<value> val = evalExpr(args, uri, cs);
if (!hasContent(val))
return value();
return content(val);
}
+ const gc_pool p;
const string uri;
const string ca;
const string cert;
const string key;
+ const CURLSession& cs;
};
}
diff --git a/sca-cpp/trunk/modules/http/httpd.hpp b/sca-cpp/trunk/modules/http/httpd.hpp
index 3c759d770c..f1b54d79ad 100644
--- a/sca-cpp/trunk/modules/http/httpd.hpp
+++ b/sca-cpp/trunk/modules/http/httpd.hpp
@@ -61,7 +61,7 @@ namespace httpd {
* Returns a server-scoped module configuration.
*/
template<typename C> void* makeServerConf(apr_pool_t *p, server_rec *s) {
- return new (gc_new<C>(p)) C(s);
+ return new (gc_new<C>(p)) C(p, s);
}
template<typename C> const C& serverConf(const request_rec* r, const module* mod) {
@@ -132,6 +132,13 @@ const bool isVirtualHostRequest(const server_rec* s, request_rec* r) {
}
/**
+ * Return true if a URI is absolute.
+ */
+const bool isAbsolute(const string& uri) {
+ return contains(uri, "://");
+}
+
+/**
* Return the protocol scheme for a server.
*/
const string scheme(const server_rec* s, const string& def = "http") {
@@ -405,6 +412,72 @@ const int internalRedirect(const string& uri, request_rec* r) {
}
/**
+ * Create an HTTPD sub request.
+ * Similar to httpd/server/request.c::make_sub_request
+ */
+const failable<request_rec*, int> internalSubRequest(const string& nr_uri, request_rec* r) {
+ if (ap_is_recursion_limit_exceeded(r))
+ return mkfailure<request_rec*, int>(HTTP_INTERNAL_SERVER_ERROR);
+
+ // Create a new sub pool
+ apr_pool_t *nrp;
+ apr_pool_create(&nrp, r->pool);
+ apr_pool_tag(nrp, "subrequest");
+
+ // Create a new POST request
+ request_rec* nr = (request_rec*)apr_pcalloc(nrp, sizeof(request_rec));
+ nr->connection = r->connection;
+ nr->server = r->server;
+ nr->pool = nrp;
+ nr->method = "POST";
+ nr->method_number = M_POST;
+ nr->allowed_methods = ap_make_method_list(nr->pool, 2);
+ ap_parse_uri(nr, apr_pstrdup(nr->pool, c_str(nr_uri)));
+ nr->filename = apr_pstrdup(nr->pool, c_str(string("/subreq:") + nr_uri));
+ nr->request_config = ap_create_request_config(r->pool);
+ nr->per_dir_config = r->server->lookup_defaults;
+
+ // Inherit some of the protocol info from the parent request
+ nr->the_request = r->the_request;
+ nr->hostname = r->hostname;
+ nr->request_time = r->request_time;
+ nr->allowed = r->allowed;
+ nr->status = HTTP_OK;
+ nr->assbackwards = r->assbackwards;
+ nr->header_only = r->header_only;
+ nr->protocol = const_cast<char*>("INCLUDED");
+ nr->hostname = r->hostname;
+ nr->request_time = r->request_time;
+ nr->main = r;
+ nr->headers_in = apr_table_make(r->pool, 12);
+ nr->headers_out = apr_table_make(r->pool, 12);
+ nr->err_headers_out = apr_table_make(nr->pool, 5);
+ nr->subprocess_env = r->subprocess_env;
+ nr->subprocess_env = apr_table_copy(nr->pool, r->subprocess_env);
+ nr->notes = apr_table_make(r->pool, 5);
+ nr->htaccess = r->htaccess;
+ nr->no_cache = r->no_cache;
+ nr->expecting_100 = r->expecting_100;
+ nr->no_local_copy = r->no_local_copy;
+ nr->read_length = 0;
+ nr->vlist_validator = r->vlist_validator;
+ nr->user = r->user;
+
+ // Setup input and output filters
+ nr->proto_output_filters = r->proto_output_filters;
+ nr->proto_input_filters = r->proto_input_filters;
+ nr->output_filters = nr->proto_output_filters;
+ nr->input_filters = nr->proto_input_filters;
+ ap_add_output_filter_handle(ap_subreq_core_filter_handle, NULL, nr, nr->connection);
+
+ // Run create request hook
+ ap_run_create_request(nr);
+ nr->used_path_info = AP_REQ_DEFAULT_PATH_INFO;
+
+ return nr;
+}
+
+/**
* Put a value in the process user data.
*/
const bool putUserData(const string& k, const void* v, const server_rec* s) {
diff --git a/sca-cpp/trunk/modules/http/mod-ssltunnel.cpp b/sca-cpp/trunk/modules/http/mod-ssltunnel.cpp
index 5337a4cac2..0d4fe3045f 100644
--- a/sca-cpp/trunk/modules/http/mod-ssltunnel.cpp
+++ b/sca-cpp/trunk/modules/http/mod-ssltunnel.cpp
@@ -47,8 +47,10 @@ namespace modssltunnel {
*/
class ServerConf {
public:
- ServerConf(server_rec* s) : server(s) {
+ ServerConf(apr_pool_t* p, server_rec* s) : p(p), server(s) {
}
+
+ const gc_pool p;
server_rec* server;
string pass;
string host;
diff --git a/sca-cpp/trunk/modules/scdl/scdl.hpp b/sca-cpp/trunk/modules/scdl/scdl.hpp
index 531144e219..0f008dc3a8 100644
--- a/sca-cpp/trunk/modules/scdl/scdl.hpp
+++ b/sca-cpp/trunk/modules/scdl/scdl.hpp
@@ -117,10 +117,33 @@ const list<value> references(const value& l) {
}
/**
+ * Returns a list of bindings in a service or reference.
+ */
+const bool filterBinding(const value& v) {
+ return isElement(v) && contains(string(cadr<value>(v)), "binding.");
+}
+
+const list<value> bindings(const value& l) {
+ return filter<value>(filterBinding, l);
+}
+
+/**
* Returns the target of a reference.
*/
+const value bindingsTarget(const list<value>& l) {
+ if (isNil(l))
+ return value();
+ const value u = uri(car(l));
+ if (!isNil(u))
+ return u;
+ return bindingsTarget(cdr(l));
+}
+
const value target(const value& l) {
- return attributeValue("target", l);
+ const value target = attributeValue("target", l);
+ if (!isNil(target))
+ return target;
+ return bindingsTarget(bindings(l));
}
/**
@@ -134,17 +157,6 @@ const list<value> referenceToTargetAssoc(const list<value>& r) {
}
/**
- * Returns a list of bindings in a service or reference.
- */
-const bool filterBinding(const value& v) {
- return isElement(v) && contains(string(cadr<value>(v)), "binding.");
-}
-
-const list<value> bindings(const value& l) {
- return filter<value>(filterBinding, l);
-}
-
-/**
* Returns a list of properties in a component.
*/
const list<value> properties(const value& l) {
diff --git a/sca-cpp/trunk/modules/server/mod-cpp.hpp b/sca-cpp/trunk/modules/server/mod-cpp.hpp
index b3828dd7d2..8cae35e493 100644
--- a/sca-cpp/trunk/modules/server/mod-cpp.hpp
+++ b/sca-cpp/trunk/modules/server/mod-cpp.hpp
@@ -64,8 +64,10 @@ struct applyImplementation {
const lib ilib;
const lambda<value(const list<value>&)> impl;
const list<value> px;
+
applyImplementation(const lib& ilib, const lambda<value(const list<value>&)>& impl, const list<value>& px) : ilib(ilib), impl(impl), px(px) {
}
+
const value operator()(const list<value>& params) const {
debug(params, "modeval::cpp::applyImplementation::input");
diff --git a/sca-cpp/trunk/modules/server/mod-eval.hpp b/sca-cpp/trunk/modules/server/mod-eval.hpp
index 391f5b8325..5eb9d5af72 100644
--- a/sca-cpp/trunk/modules/server/mod-eval.hpp
+++ b/sca-cpp/trunk/modules/server/mod-eval.hpp
@@ -53,9 +53,10 @@ namespace modeval {
*/
class ServerConf {
public:
- ServerConf(server_rec* s) : server(s), wiringServerName(""), contributionPath(""), compositeName(""), virtualHostContributionPath(""), virtualHostCompositeName(""), ca(""), cert(""), key("") {
+ ServerConf(apr_pool_t* p, server_rec* s) : p(p), server(s), wiringServerName(""), contributionPath(""), compositeName(""), virtualHostContributionPath(""), virtualHostCompositeName(""), ca(""), cert(""), key("") {
}
+ const gc_pool p;
server_rec* server;
lambda<value(const list<value>&)> lifecycle;
string wiringServerName;
@@ -259,16 +260,68 @@ int translate(request_rec *r) {
}
/**
- * Convert a list of component references to a list of HTTP proxy lambdas.
+ * Make an HTTP proxy lambda.
*/
-const value mkrefProxy(const value& ref, const string& base, const string& ca, const string& cert, const string& key) {
- return lambda<value(const list<value>&)>(http::proxy(base + string(scdl::name(ref)), ca, cert, key));
+const value mkhttpProxy(const ServerConf& sc, const string& ref, const string& base) {
+ const string uri = base + ref;
+ debug(uri, "modeval::mkhttpProxy::uri");
+ return lambda<value(const list<value>&)>(http::proxy(uri, sc.ca, sc.cert, sc.key, sc.p));
}
-const list<value> refProxies(const list<value>& refs, const string& base, const string& ca, const string& cert, const string& key) {
+/**
+ * Return a component implementation proxy lambda.
+ */
+class implProxy {
+public:
+ implProxy(const ServerConf& sc, const value& name) : sc(sc), name(name) {
+ }
+
+ const value operator()(const list<value>& params) const {
+ debug(params, "modeval::implProxy::input");
+
+ // Lookup the component implementation
+ const list<value> impl(assoctree<value>(name, sc.implTree));
+ if (isNil(impl))
+ return mkfailure<value>(string("Couldn't find component implementation: ") + name);
+
+ // Call its lambda function
+ const lambda<value(const list<value>&)> l(cadr<value>(impl));
+ const value func = c_str(car(params));
+ const failable<value> val = failableResult(l(cons(func, cdr(params))));
+ debug(val, "modeval::implProxy::result");
+ if (!hasContent(val))
+ return value();
+ return content(val);
+ }
+
+private:
+ const ServerConf& sc;
+ const value name;
+};
+
+const value mkimplProxy(const ServerConf& sc, const value& name) {
+ debug(name, "modeval::implProxy::impl");
+ return lambda<value(const list<value>&)>(implProxy(sc, name));
+}
+
+/**
+ * Convert a list of component references to a list of proxy lambdas.
+ */
+const value mkrefProxy(const ServerConf& sc, const value& ref, const string& base) {
+ const value target = scdl::target(ref);
+ debug(ref, "modeval::mkrefProxy::ref");
+ debug(target, "modeval::mkrefProxy::target");
+
+ // Use an HTTP proxy or an internal proxy to the component implementation
+ if (isNil(target) || httpd::isAbsolute(target))
+ return mkhttpProxy(sc, scdl::name(ref), base);
+ return mkimplProxy(sc, car(pathValues(target)));
+}
+
+const list<value> refProxies(const ServerConf& sc, const list<value>& refs, const string& base) {
if (isNil(refs))
return refs;
- return cons(mkrefProxy(car(refs), base, ca, cert, key), refProxies(cdr(refs), base, ca, cert, key));
+ return cons(mkrefProxy(sc, car(refs), base), refProxies(sc, cdr(refs), base));
}
/**
@@ -375,11 +428,13 @@ const value evalComponent(ServerConf& sc, const value& comp) {
extern const failable<lambda<value(const list<value>&)> > evalImplementation(const string& cpath, const value& impl, const list<value>& px, const lambda<value(const list<value>&)>& lifecycle);
const value impl = scdl::implementation(comp);
+ debug(comp, "modeval::evalComponent::comp");
+ debug(impl, "modeval::evalComponent::impl");
// Convert component references to configured proxy lambdas
ostringstream base;
base << sc.wiringServerName << "/references/" << string(scdl::name(comp)) << "/";
- const list<value> rpx(refProxies(scdl::references(comp), str(base), sc.ca, sc.cert, sc.key));
+ const list<value> rpx(refProxies(sc, scdl::references(comp), str(base)));
// Convert component proxies to configured proxy lambdas
const list<value> ppx(propProxies(scdl::properties(comp)));
@@ -486,7 +541,7 @@ const failable<bool> startComponents(ServerConf& sc) {
*/
class VirtualHostConf {
public:
- VirtualHostConf(const ServerConf& ssc) : sc(ssc.server) {
+ VirtualHostConf(const gc_pool& p, const ServerConf& ssc) : sc(pool(p), ssc.server) {
sc.virtualHostContributionPath = ssc.virtualHostContributionPath;
sc.virtualHostCompositeName = ssc.virtualHostCompositeName;
sc.ca = ssc.ca;
@@ -559,7 +614,7 @@ int handler(request_rec *r) {
const ServerConf& sc = httpd::serverConf<ServerConf>(r, &mod_tuscany_eval);
// Process dynamic virtual host configuration, if any
- VirtualHostConf vhc(sc);
+ VirtualHostConf vhc(gc_pool(r->pool), sc);
const bool usevh = hasVirtualCompositeConf(vhc.sc) && httpd::isVirtualHostRequest(sc.server, r);
if (usevh) {
const failable<bool> cr = virtualHostConfig(vhc.sc, r);
@@ -571,7 +626,7 @@ int handler(request_rec *r) {
const list<value> path(pathValues(r->uri));
const list<value> impl(assoctree<value>(cadr(path), usevh? vhc.sc.implTree : sc.implTree));
if (isNil(impl))
- return httpd::reportStatus(mkfailure<int>(string("Couldn't find component implementation")));
+ return httpd::reportStatus(mkfailure<int>(string("Couldn't find component implementation: ") + cadr(path)));
// Handle HTTP method
const lambda<value(const list<value>&)> l(cadr<value>(impl));
diff --git a/sca-cpp/trunk/modules/server/mod-scheme.hpp b/sca-cpp/trunk/modules/server/mod-scheme.hpp
index f5b9554c3f..43d7bf4041 100644
--- a/sca-cpp/trunk/modules/server/mod-scheme.hpp
+++ b/sca-cpp/trunk/modules/server/mod-scheme.hpp
@@ -54,8 +54,10 @@ const list<value> primitiveProcedures(const list<value>& l) {
struct applyImplementation {
const value impl;
const list<value> px;
+
applyImplementation(const value& impl, const list<value>& px) : impl(impl), px(scheme::quotedParameters(primitiveProcedures(px))) {
}
+
const value operator()(const list<value>& params) const {
const value expr = cons<value>(car(params), append(scheme::quotedParameters(cdr(params)), px));
debug(expr, "modeval::scheme::applyImplementation::input");
diff --git a/sca-cpp/trunk/modules/server/mod-wiring.cpp b/sca-cpp/trunk/modules/server/mod-wiring.cpp
index 17cfcaae0e..188aa620fb 100644
--- a/sca-cpp/trunk/modules/server/mod-wiring.cpp
+++ b/sca-cpp/trunk/modules/server/mod-wiring.cpp
@@ -53,8 +53,10 @@ const bool useModProxy = true;
*/
class ServerConf {
public:
- ServerConf(server_rec* s) : server(s), contributionPath(""), compositeName(""), virtualHostContributionPath(""), virtualHostCompositeName("") {
+ ServerConf(apr_pool_t* p, server_rec* s) : p(p), server(s), contributionPath(""), compositeName(""), virtualHostContributionPath(""), virtualHostCompositeName("") {
}
+
+ const gc_pool p;
server_rec* server;
string contributionPath;
string compositeName;
@@ -79,13 +81,6 @@ const bool hasVirtualCompositeConf(const ServerConf& sc) {
}
/**
- * Returns true if a URI is absolute.
- */
-const bool isAbsolute(const string& uri) {
- return contains(uri, "://");
-}
-
-/**
* Route a /references/component-name/reference-name request,
* to the target of the component reference.
*/
@@ -107,7 +102,7 @@ int translateReference(const ServerConf& sc, request_rec *r) {
debug(target, "modwiring::translateReference::target");
// Route to an absolute target URI using mod_proxy or an HTTP client redirect
- if (isAbsolute(target)) {
+ if (httpd::isAbsolute(target)) {
if (useModProxy) {
// Build proxy URI using current request's protocol scheme
r->filename = apr_pstrdup(r->pool, c_str(string("proxy:") + httpd::scheme(r) + substr(target, find(target, "://"))));
@@ -270,7 +265,7 @@ const bool confComponents(ServerConf& sc) {
*/
class VirtualHostConf {
public:
- VirtualHostConf(const ServerConf& ssc) : sc(ssc.server) {
+ VirtualHostConf(const gc_pool& p, const ServerConf& ssc) : sc(pool(p), ssc.server) {
sc.virtualHostContributionPath = ssc.virtualHostContributionPath;
sc.virtualHostCompositeName = ssc.virtualHostCompositeName;
}
@@ -316,7 +311,7 @@ int translate(request_rec *r) {
const ServerConf& sc = httpd::serverConf<ServerConf>(r, &mod_tuscany_wiring);
// Process dynamic virtual host configuration
- VirtualHostConf vhc(sc);
+ VirtualHostConf vhc(gc_pool(r->pool), sc);
const bool usevh = hasVirtualCompositeConf(vhc.sc) && httpd::isVirtualHostRequest(sc.server, r);
if (usevh) {
const failable<bool> cr = virtualHostConfig(vhc.sc, r);
diff --git a/sca-cpp/trunk/samples/store-cluster/domains/jane/store.composite b/sca-cpp/trunk/samples/store-cluster/domains/jane/store.composite
index eeb5387588..be67d20955 100644
--- a/sca-cpp/trunk/samples/store-cluster/domains/jane/store.composite
+++ b/sca-cpp/trunk/samples/store-cluster/domains/jane/store.composite
@@ -51,7 +51,9 @@
<service name="Total">
<t:binding.jsonrpc uri="total"/>
</service>
- <reference name="cache" target="http://sca-store.com/cache"/>
+ <reference name="cache">
+ <t:binding.jsonrpc uri="http://sca-store.com/cache"/>
+ </reference>
</component>
<component name="CurrencyConverter">
diff --git a/sca-cpp/trunk/samples/store-cluster/domains/joe/store.composite b/sca-cpp/trunk/samples/store-cluster/domains/joe/store.composite
index eeb5387588..be67d20955 100644
--- a/sca-cpp/trunk/samples/store-cluster/domains/joe/store.composite
+++ b/sca-cpp/trunk/samples/store-cluster/domains/joe/store.composite
@@ -51,7 +51,9 @@
<service name="Total">
<t:binding.jsonrpc uri="total"/>
</service>
- <reference name="cache" target="http://sca-store.com/cache"/>
+ <reference name="cache">
+ <t:binding.jsonrpc uri="http://sca-store.com/cache"/>
+ </reference>
</component>
<component name="CurrencyConverter">