Friday, March 13, 2009

mod_coherence for Apache webserver

After the advent of Servlet and ServletFilters importance of webserver plugins (ISAPI, NSAPI, Apache etc) have slowly subsided. But plugin's raw speed and low level content, connection and protocol capture still makes it a viable candidate for plenty of scenarios. Caching is an integral part of a web server and mod_cache is possibly the most used plugin. Not to replace it but lets write something that uses Oracle Coherence as the content repository. Apache being at the core of most App/webservers lets write one mod_coherence for Apache webserver....

#include <httpd.h>
#include <http_protocol.h>
#include <http_config.h>


static int coherence_handler (request_rec *r) {
if (!r->handler || strcmp(r->handler, "coherence")) {
return DECLINED;
}
char* uri = r->uri;
// -- useThisUri (uri);
// -- Open to implementation
// -- Scroll down for options
// -- Assuming we get the content (parsed) here using C++ API

NamedCache::Handle pCache = CacheFactory::getCache(<cache_name>);
String::View cnt = cast<String::View>(pCache->get (uri));
ap_set_content_type(r, "text/html;charset=ascii");
ap_rputs(cnt, r);
return OK;
}

static void coherence_hooks (apr_pool_t *pool) {
ap_hook_handler(coherence_handler, NULL, NULL, APR_HOOK_MIDDLE);
}

module AP_MODULE_DECLARE_DATA coherence_module = {
STANDARD20_MODULE_STUFF,
NULL,
NULL,
NULL,
NULL,
NULL,
coherence_hooks
};
Now compile this source to a shared object and put it under Apache modules/ directory and configure httpd.conf as:
LoadModule coherence_module modules/mod_coherence.so
<Location /*>
SetHandler coherence
</Location>
And thats all you need on the Apache side. The question is what to do with the uri and how to do it in coherence_handler? First depending on which language you are more comfortable with use Java with Java Invocation Framework or use Coherence's native C++ API. Second, use the uri (or some part of uri) as a Cache key and get the content from Coherence Cache. If using JNI we have an option to make Apache webserver plugin be made a storage disabled member of the Coherence cluster. If native C++ APIs are used make sure the cache configuration is *Extend instead. The option of implementations are:
  • Cache and UriCache are new C++ Objects that use Java Invocation Interface to work with Coherence Java APIs.

      // -- Following implementation is using JNI
      Cache* pCache = new UriCache ("Content");
      SomeObject* cnt = (SomeObject*) pCache->get (uri);
      // -- This SomeObject could be simple HTML String or an
      // -- XML Content to be parsed in the next few lines
  • All Java and no Cache implementation in C++
  • Using Coherence native C++ API
      NamedCache::Handle pCache = CacheFactory::getCache(cacheName);
      String::View cnt = cast<String::View>(pCache->get (uri));

Enjoy!

No comments: