MOWI in Deamon Mode
When MOWI runs in deamon mode (called mowid) it acts much like your web server. It waits until a client connects, processes the request, sends it on to Oracle, and then returns results to the client. By running in deamon mode, mowid stays logged in to Oracle and therefore doesn't incure the large overhead of connecting and disconnecting from Oracle. In addition the MOWI deamon stays in RAM and reduces the overhead of starting and stopping a large process.
Mowid tracks IP address of the last connection and also knows which user id it is using to talk to Oracle. Mowid will automatically disconnect and reconnect to Oracle with the correct user id depending on what client is talking to it. This allows for a more flexible web application; one that leverages Oracle security instead of embedding all security in the web forms themselves.
The whole MOWI process in deamon mode is outlined below:
- Step 1
- The client connects to your web server (hear after called httpd)
- Step 2
- Httpd decides whether the request is for a static page or one stored in Oracle. We're only interested in Oracle based data so...
Your httpd server calls what is known as a CGI script (mowi). This script is used to set some critical environment variables like ORACLE_HOME and ORACLE_SID. These environment variables are used by every process that interacts with Oracle including SQL*Plus etc. In most cases, another environment variable is set (MOWI_UID). This variable is the userid/password combination used to connect to Oracle.
- Step 3
- During step 3, the CGI script launches the mowiStub program. Notice the capitalization in the name. The mowiStub program is a very small executable program and thus it does not cause a huge memory hit on your machine when it starts up. The mowiStub program reads a special control file (usually located in /tmp/mowid.ctl). It scans the control file for copies of the MOWI deamon (mowid). While it is reading the file, it will check to see which of the deamons is logged in on the correct MOWI_UID. MowiStub also checks to see which of the deamons is free to handle a connection. If none of the deamons are free, or if there are no deamons running, mowiStub will return an error message to the web client.
- Step 4
- During step 4, mowiStub will open a connection to one of the mowid processes. The connection is made through Unix domain sockets. This connection is essentially an open pipe between the two processes. Information can only pass one way through the pipe, so mowiStub opens two sockets. The connection is represented in the Unix operating system by file names somewhere in the file system of the computer. The default location of these "files" is in the /tmp directory. It's important to note that the "files" don't take up any space, but the mowiStub, mowid, and httpd processes need read and write permissions to the files. Most web servers are set up to run as a "nobody" user, this "nobody" user must have r/w permissions into the directory holding these socket files.
- Step 5
- This is a complicated process so it is broken down into several steps.
- Mowid will mark itself as "busy" in the mowid.ctl control file so that other stubs will not try to connect.
- Verify that mowid is logged into the correct Oracle userid by checking the MOWI_UID environment variable. If it is not logged in correctly, it will logout of Oracle, and reconnect with the userid and password stored in MOWI_UID. Actually mowiStub and mowid check three different environment variables to determine the correct Oracle userid and password. They are checked in order and are: MOWI_UID, WOW_UID and UID.
- Mowid will read the input from mowiStub (which came from the mowi script which in turn came from the httpd server) and package it up into a stored procedure call. The request must be either an http GET or POST request.
- As the request is processed, mowid will attempt to determine if any of the input variables (on an HTML form) are arrays. Forms that have more than one item (a checkbox, or textbox, etc) with the same name, will automatically be processed as arrays.
- Mowid will "describe" the Oracle stored procedure to be called. Based on the results of this describe, mowid will pick the FIRST most likely definition of a procedure. So, if you have "overloaded" your procedure calls, mowid will stop checking their descriptions when it finds the first procedure with all the correct matching items on the HTML form. It is critical to note that the items on the HTML form will be matched in the order that they are received by mowid. Mowid will not re-order the items on your HTML form to match the Oracle stored proceddure call. This behavior may change at a later date.
- Certain environment variables will be packaged up and included with the call to your stored procedure. The variables will be available as Oracle global variables. They include: REMOTE_ADDR, REMOTE_HOST, REMOTE_USER, HTTP_ACCEPT, SERVER_SOFTWARE, SERVER_NAME, GATEWAY_INTERFACE, SERVER_PROTOCOL, REQUEST_METHOD, PATH_INFO, and MOWI_SPARE. You can add your own variables to this list by modifying the mowi.c file and the list of global variables in mowi.sql
- Once the input data is packaged up, mowid will call the stored procedure used in the request. It will then read from the dbms_output package until there is no more data stored there. If you don't return any data to the client during your stored procedure call, then the web client won't receive any data either. You must output data with the routines stored in the htp and htf packages.
- Step 7
- During this step, data is read from dbms_output and sent back to the client. Mowid will remain logged in as this user, until a request is received with a different userid. When this step is finished, mowid will break the connection to mowiStub and modify it's entry in the mowid.ctl file to show that it is free to handle new requests.
- Step 8
- MowiStub will return data to the CGI script through stdout
- Step 9
- The mowi CGI script will return data to the webserver through stdout
- Step 10
- The httpd server will return data to the web client
The whole process seems long and complicated, but each step of the way performs a slightly differnt set of tasks.
Why use MOWID?
Using mowid should improve server performance because:
- Only a small process is launched for each request from the client. Look at the size differences between mowiStub and mowid
- There is no overhead of connecting and disconnecting from Oracle if all your web clients log in as the same user.
- The overhead in reading the control file for mowid, and opening the sockets between mowiStub and mowid should be negligable compared to the overhead of spawning a large single process that must connect to Oracle
Mowid relies on the Oracle Call Interface libraries to process much of the data sent to Oracle. Those libraries have a horrible tendency to use large amounts of RAM an NOT free it up when it is finished. I've logged a TAR with Oracle, but I doubt there is a good solution to this problem.
The large RAM hit only occurrs when processing PL/SQL arrays. So most web pages won't cause any problem.
The RAM bloat, as I like to call it, is also not cumulative. The RAM in use by mowid will usually grow to a stable point and not go further. For forms with relatively few arrays, this stable size will be around 3 megabytes. The larger the arrays, the larger the stable size. I've had a mowid process on my machine grow to over 70 megabytes in one call when processing a form with 6 arrays of over 150 items each. This is obviously an extreme case, but I was shocked at the size.
I believe that Oracle's Web Server also suffers from this problem, and that is why Oracle has put severe limits on the number of form items that it will process. This is of course a guess, since I do not have access to Web Server or it's source code. Oracle may have lifted this limit or have other reasons for putting in the limits.
I have spoken with others in the industry who run deamons similar to mowid, they report the same strange bloating affect.
There is apparently no way to shrink the size of the mowid process except by stopping the deamon and restarting it.
You can check how much RAM mowid allocated outside of the Oracle Call Interface libraries by uncommenting the "DEBUGMALLOC" flag in mowi.c. When this flag is defined, mowid will count the amount of RAM that it allocates, and print an HTML comment at the bottom of the web page showing the total byte count. The largest I have every seen this go is 140K bytes. I have checked my code very thouroughly for memory leaks, and cannot find any during normal operation.
It is important to note that the stand alone version of mowi (mowistub <-notice the capitalization here) has this same problem. But, since it doesn't stay running, the RAM hit goes away at the end of each web client call.
You must evaluate your circumstances and decide whether the RAM bloat problem will affect you. Remember that it only happens when using lots of arrays or arrays with a large number of items on each form. So if each one of your HTML forms has 2 arrays of 5 items, the bloat should never go past a certain point.
Back to the MOWI home page
Oracle, Oracle Call Interface, OCI, and PL/SQL are trademarks of Oracle Corporation. (Hope I haven't missed anyone)