I'm fairly new to GT.M, but I think it's a pretty nice environment for doing web applications because of great text processing capabilities, the persistence of globals, etc.
Anyway, while learning M, I've been experimenting with getting GT.M running under FastCGI. For those who don't know, where CGI creates a new process for each request, FastCGI keeps the process open and handles multiple requests. The web server communicates with the fastcgi process via a socket. Fastcgi has headers and a library that work to redirect stdin and stdout to the socket so it is output as a web page.
My approach is something is to use the GT.M call-in interface.
The C code (simplified) fcgi binary spawned by the web server looks like this:
<output web page headers>
gtm_ci(<a mumps routine to return a string with the time>);
<output buffer from gtm_ci to show call to mumps actually works>
<print page footer>
The program runs in the while loop once per FastCGI request.
PROBLEM: The web server (lighttpd) upon exiting sends a SIGTERM to it's FastCGI processes. the gtm_exit() never gets called. Instead it appears the GT.M code graps the signal and emits the error
"GTM-F-FORCEDHALT, Image HALTed my mupip stop."
This doesn't sound like the best way to exit....
my proposed solution: after calling gtm_init() in the main code, I register a signal handler for SIGTERM that is simply
void smoothexithanlder(int sig_num)
<some other C cleanup>
Now this SEEMS to work, but I'm not running any heavy M code so far...and the callin manual basically says "Don't mess with the GT.M signal handling." Am I looking for trouble????
On a final note. I switched to lighttpd from myserver. Lighttpd has robust fastcgi support and debug messages. Myserver is a small c++ web server that is easy to use and prototype with. However, I had a problem with myserver. It would run straight "C" fastcgi apps ok, but running something like the above, gtm_init() would always fail with a "GTM init error: 150380234,%GTM-E-GETSOCKNAMERR, Getting the socket name failed from getsockname(): (errno==107) Transport endpoint is not connected"
Now I'm not really sure if this is a GT.M, myserver, or libfcgi thing. It's basically the same code that works on lighttpd. I spent a little time trying to trace through the GTM call-in init code in the GT.M src, but that's some heavy duty code, and I didn't want to spend that much time :)....
If I get this working, I'll publish the full code and documentation.
Sorry about the typos.
Trust the documentation. Yes, you are looking for trouble if you mess with signal handling.
How are you starting the GT.M process? Since it is a server, perhaps you can redirect STDERR, e.g.: my_gtm_proc 2>logfile_$$.log
My message above was supposed to be a reply to your message. Still getting used to the sourceforge interface.
First, I don't want to confuse the issue. I was first using a different webserver: Myserver, which gave me the error GTM-E-GETSOCKNAMERR. I'm not concerned about this, because I am now using lightttpd, which has fcgi debug support.
Lighttpd + fcgi + GT.M (via libgtmshr) works, except when it's time to kill the GT.M processes. The web server sends a SIGTERM to the GT.M process, which ends in a "GTM-F-FORCEDHALT, Image HALTed my mupip stop.", and gtm_exit() not being called. This doesn't sound like a good way to shut down GT.M? Am I wrong?
How is the GT.M server being started? A C program is created that links in 2 libraries. libgtmshr and libfcgi. The server is started thru the gtm call-in interface e.g. gtm_init(). The way FCGI works is that the web server spawns the C program as a child process, and connects stdin and stdout to the web server via a UNIX socket. It's effectively working like a two-way pipe.
Here's another view of the C program
while (FCGX_Accept) <--- block until CGI request comes in from web server
<output some html from C>
gtm_ci() // call some gtm code and return a buffer with some more html code
<output some more html code from c>
} // end of while loop
The problem is that the program stays in the while loop until receiving the SIGTERM from the parent process, lighttpd. gtm_exit() is never called. the GT.M code seems to intercept the SIGTERM and exit with the "GTM-F-FORCEDHALT" error. This is why I thought maybe registering a handler that calls gtm_exit() might be a solution. I suppose this would work as long as gtm_ci() is not executing....but maybe would cause problems if it is in the middle of mumps code in a gtm_ci() call when this happens.
Ideally, the webserver would not kill a FCGI GTM process in the middle of a request, but we all know how ideal the real world is......
Hmmm...maybe no solution, unless GTM-F-FORCEDHALT is an "OK" way to exit....
Since GT.M expects to be halted from within, GTM-F-FORCEDHALT is just GT.M's way of telling the world that it is shutting down in response to a SIGTERM. This is normal behavior, and nothing to be alarmed about except that it seems the message is inconvenient for you. So, in the short term, the goal should be to find a way to not get the message. Does redirecting STDERR work for you?
The message to stderr is actually not inconvenient. Only stdin and stdout are redirected to/from the web server. stderr is output to the console's stderr where the web server (and it's childen) was started, or /dev/null I suppose if it's running as a daemon.
My only concern was that this is not a "good" shutdown scenario, and might lead to data corruption. A brief look at the GT.M signal handling code for SIGTERM verifies what you said.
Again, I'll probably be posting some code and a howto later -- I'm sure there are folks out there who would like to use GT.M as a web backend without having to spawn a new process for every request.
Thanks for your advice bhaskar!!!!
I have been developing web applications based on MUMPS for more than 12 years and for more than 5 years now almost exclusively with GT.M, Linux, and Apache. I may not have any direct help for you with fastCGI, but I might be able to help quite a bit when you go beyond the basics to building more complex web applications with GT.M. (see http://vista.vmth.ucdavis.edu\)
We (UCD VMTH) experimented with several approaches to running web applications with GT.M 5 years ago or so and decided to start with CGI and Apache in order to avoid complications with signals and sockets handling. We have found that CGI with GT.M and Apache seems to be quite robust and easily scalable well beyond our present needs. It also provides an advantage for rapid development in that modified routines will always be recompiled as needed.
I had not heard of lighttpd until you mentioned it. It apparently offers better performance than Apache in some cases, so I will be interested to know what kind of performance you get and how fastcgi compares with CGI for GT.M database access.
Log in to post a comment.
Sign up for the SourceForge newsletter:
You seem to have CSS turned off.
Please don't fill out this field.