You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tuscany.apache.org by js...@apache.org on 2010/08/22 07:02:12 UTC

svn commit: r987845 - in /tuscany/sca-cpp/trunk: modules/http/ modules/scdl/ modules/server/ samples/store-cluster/domains/jane/ samples/store-cluster/domains/joe/

Author: jsdelfino
Date: Sun Aug 22 05:02:11 2010
New Revision: 987845

URL: http://svn.apache.org/viewvc?rev=987845&view=rev
Log:
Improve performance by reusing HTTP proxy connections across invocations and using local function proxies instead of HTTP proxies for local wires.

Modified:
    tuscany/sca-cpp/trunk/modules/http/http.hpp
    tuscany/sca-cpp/trunk/modules/http/httpd.hpp
    tuscany/sca-cpp/trunk/modules/http/mod-ssltunnel.cpp
    tuscany/sca-cpp/trunk/modules/scdl/scdl.hpp
    tuscany/sca-cpp/trunk/modules/server/mod-cpp.hpp
    tuscany/sca-cpp/trunk/modules/server/mod-eval.hpp
    tuscany/sca-cpp/trunk/modules/server/mod-scheme.hpp
    tuscany/sca-cpp/trunk/modules/server/mod-wiring.cpp
    tuscany/sca-cpp/trunk/samples/store-cluster/domains/jane/store.composite
    tuscany/sca-cpp/trunk/samples/store-cluster/domains/joe/store.composite

Modified: tuscany/sca-cpp/trunk/modules/http/http.hpp
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/modules/http/http.hpp?rev=987845&r1=987844&r2=987845&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/modules/http/http.hpp (original)
+++ tuscany/sca-cpp/trunk/modules/http/http.hpp Sun Aug 22 05:02:11 2010
@@ -314,9 +314,9 @@ const failable<value> evalExpr(const val
 
     // 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 
  * 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;
 };
 
 }

Modified: tuscany/sca-cpp/trunk/modules/http/httpd.hpp
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/modules/http/httpd.hpp?rev=987845&r1=987844&r2=987845&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/modules/http/httpd.hpp (original)
+++ tuscany/sca-cpp/trunk/modules/http/httpd.hpp Sun Aug 22 05:02:11 2010
@@ -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 se
 }
 
 /**
+ * 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&
 }
 
 /**
+ * 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) {

Modified: tuscany/sca-cpp/trunk/modules/http/mod-ssltunnel.cpp
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/modules/http/mod-ssltunnel.cpp?rev=987845&r1=987844&r2=987845&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/modules/http/mod-ssltunnel.cpp (original)
+++ tuscany/sca-cpp/trunk/modules/http/mod-ssltunnel.cpp Sun Aug 22 05:02:11 2010
@@ -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;

Modified: tuscany/sca-cpp/trunk/modules/scdl/scdl.hpp
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/modules/scdl/scdl.hpp?rev=987845&r1=987844&r2=987845&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/modules/scdl/scdl.hpp (original)
+++ tuscany/sca-cpp/trunk/modules/scdl/scdl.hpp Sun Aug 22 05:02:11 2010
@@ -117,10 +117,33 @@ const list<value> references(const value
 }
 
 /**
+ * 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
 }
 
 /**
- * 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) {

Modified: tuscany/sca-cpp/trunk/modules/server/mod-cpp.hpp
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/modules/server/mod-cpp.hpp?rev=987845&r1=987844&r2=987845&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/modules/server/mod-cpp.hpp (original)
+++ tuscany/sca-cpp/trunk/modules/server/mod-cpp.hpp Sun Aug 22 05:02:11 2010
@@ -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");
 

Modified: tuscany/sca-cpp/trunk/modules/server/mod-eval.hpp
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/modules/server/mod-eval.hpp?rev=987845&r1=987844&r2=987845&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/modules/server/mod-eval.hpp (original)
+++ tuscany/sca-cpp/trunk/modules/server/mod-eval.hpp Sun Aug 22 05:02:11 2010
@@ -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
     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(Ser
  */
 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));

Modified: tuscany/sca-cpp/trunk/modules/server/mod-scheme.hpp
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/modules/server/mod-scheme.hpp?rev=987845&r1=987844&r2=987845&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/modules/server/mod-scheme.hpp (original)
+++ tuscany/sca-cpp/trunk/modules/server/mod-scheme.hpp Sun Aug 22 05:02:11 2010
@@ -54,8 +54,10 @@ const list<value> primitiveProcedures(co
 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");

Modified: tuscany/sca-cpp/trunk/modules/server/mod-wiring.cpp
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/modules/server/mod-wiring.cpp?rev=987845&r1=987844&r2=987845&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/modules/server/mod-wiring.cpp (original)
+++ tuscany/sca-cpp/trunk/modules/server/mod-wiring.cpp Sun Aug 22 05:02:11 2010
@@ -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
 }
 
 /**
- * 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&
     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);

Modified: tuscany/sca-cpp/trunk/samples/store-cluster/domains/jane/store.composite
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/samples/store-cluster/domains/jane/store.composite?rev=987845&r1=987844&r2=987845&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/samples/store-cluster/domains/jane/store.composite (original)
+++ tuscany/sca-cpp/trunk/samples/store-cluster/domains/jane/store.composite Sun Aug 22 05:02:11 2010
@@ -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">

Modified: tuscany/sca-cpp/trunk/samples/store-cluster/domains/joe/store.composite
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/samples/store-cluster/domains/joe/store.composite?rev=987845&r1=987844&r2=987845&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/samples/store-cluster/domains/joe/store.composite (original)
+++ tuscany/sca-cpp/trunk/samples/store-cluster/domains/joe/store.composite Sun Aug 22 05:02:11 2010
@@ -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">