PL/SQL Gateway for Apache 2.0

Doug McMahon
(Doug.McMahon@oracle.com)

October 10, 2002


Introduction

This is a version of the mod_owa PL/SQL gateway for Apache 2.0. It is functionally equivalent to the Apache 1.3.x version, except as noted in the remainder of this document.

Source Code

This version of mod_owa uses the same source code as the 1.3.x version. A compilation flag, APACHE20, is used to build the 2.0 linkage in modowa.c.

Installation and Configuration

Installation is the same as for Apache 1.3.x. Configuration is essentially the same, however in this version all of the directives have been changed to conform to Apache naming standards (I've been unwilling to make this change in the 1.3 version because of compatibility concerns).

Problems and Issues

There are several issues and problems with the Apache 2.0 version that you should be aware of:

Exact version of 2.0 must match

This extremely annoying behavior seems to have appeared in 2.0. If you take a module that was built against (say) 2.0.39 and try to run it against (say) 2.0.43, you will get an error message about the module version. Since new 2.0.x releases appear all the time, it's impossible for me to keep up. 1.3 was much better, you could run a module built with any 1.3.x release. The current binaries for Apache 2.0 were built with 2.0.43.

SQL*Net Connection Required

In the 1.3.x version of mod_owa, I described a subtle bug I'd found where, using Oracle's so-called "bequeath" mode of connecting to the database, the OCI does a fork() to create the database worker process, and this carries off a handle to the socket Apache's using to communicate with the browser. This problem does not occur on the Windows-based platforms because these platforms start the database workers in a completely different manner. And the problem never occurs with SQL*Net connections because in those cases the TNS listener process on the database server is used to start the worker. The workaround on this was to close out the keepalive connection in any situation where a database worker was being forked. Unfortunately this solution is only viable when Apache is single-threaded; since this was always true for Unix versions of 1.3.x, it worked. But now that Apache 2.0 allows threading on Unix, it won't work any more, and so the only alternative is to require the use of SQL*Net for all connections on Unix deployments. mod_owa will attempt to determine if the bequeath mode is being used, and if so, it will simply disable keepalive by return 0 content length for all pages.

Semaphores needed on Unix

Apache 2.0 now supports threaded operation on Unix. This requires mod_owa to use mutexes and semaphores in a manner similar to the way the 1.3 NT version worked. While mutexes behave similarly, Unix semaphores do not automatically get cleaned up when the process exits. mod_owa hooks the pool exit event and tries to clean up these resources before the process exits, but it's possible that some shutdown scenarios (and certainly crashes) will result in the "loss" of semaphores that were used by mod_owa. You can look at semaphore usage with the Unix ipcs command, and if necessary you can clean them manually with ipcrm. Also note that during operation mod_owa will need one semaphore per Location per worker process. This is potentially a lot of semaphores, especially if you don't use the threaded modes of operation (i.e. if you use prefork rather than worker or perchild). To avoid these problems, the latest implementation uses pthread mutexes and condition variables.

Stuck processes on Unix shutdown

When I shut Apache 2.0 down on Unix, after having run some requests through (both static and OWA), I find that at least one of the worker processes (always the process that served my requests) will not shut down. I have no clue as to why this is happening.

Child process shutdown not always done on Windows

Apache 2.0 lacks a few of the callbacks that mod_owa depends on. In particular, it lacks the callback for the "module initializer" and the callbacks for the "child initializer" and "child shutdown". Apache 2.0 provides a mechanism whereby you can hook these events, and mod_owa attempts to hook its callbacks using this mechanism. This seems to work on Unix, but on Windows the child shutdown sometimes seems never to get called. The child shutdown is needed mainly to close database connections cleanly.

Range transfers not supported

Byte-range transfer modes are not supported, because Apache 2.0 lacks APIs that are compatible with the 1.3.x versions. It appears that to get this functionality back the entire module would have to be rewritten to work with the "bucket-brigade" model.

Missing timeout APIs

The original (Gelzinis/Kulikova) mod_owa began all requests with a call to ap_soft_timeout() and ended all requests by calling ap_kill_timeout(). It did this for reasons that were never clear to me; I've kept this code in place because I was not sure what effect removing it would have. Unfortunately, these APIs no longer appear in Apache 2.0, so I was forced to remove them in that build anyway. It's still unclear what effect this has on the module's operation.

Dynamic memory requirements

On Unix, the 1.3 version of mod_owa used a fixed-sized global buffer for binding data to/from the OCI. This ensured that mod_owa's memory use would minimally fragment the process heap during heavy operation. On NT, because of the need to support threads, mod_owa is forced to allocate this memory from the Apache request pool, where it will be released by Apache upon request completion. The 2.0 version of mod_owa uses this same code on all platforms, including Unix. As a result, it's possible that over time the heap may become fragmented and the process size could continue to grow as a result, even though no memory is actually being "leaked".