fcgi, exceptions, random stuff
Oops, I typed repl without thinking and accidentally mailed this to Amos (sorry!)
At 12:58 AM 2/1/99 -0800, Quinn Dunkan wrote:
I posted this a while ago, but recieved no response, so I assume it either didn't make it, or everyone hates me.
I hope you don't seriously think this. As you are no doubt aware, this list gets a lot of traffic. If you are looking to get your questions answered quickly I would suggest trying to ask them as clearly and precisely as possible. Of course, feel free to ignore this advice ;-)
I was just being silly :) Your advice is good, and I always try to make my mails/postings clear, precise, and short. "short" is not my strong point though...
So I think that material is available, but I guess we need to do a better job organizing, labeling, and explaining it.
Definitely the material is available, but if I were trying to learn ZPublisher without previous knowledge I might not immedietely look in "Developer Reference" -> "Technical Introduction to Object Publishing ..." Perhaps Trinket and Intruduction could be cross referenced in HOWTOs? And I think it might be good have a "How can I use Zope" section, because some people's immediate reaction might be: "looks cool, but I've already got a huge site, I just want to clean up the cgi mess, I don't have a 'web application platform' just a plain old site." The "How can I use Zope" section would say "use ZP/ZT to clean up your cgi mess!"
One more general purpose way of handling shutting down is to include a published method which shuts down python, for example:
def shutdown(): "should require authorization to call this" raise SystemExit
Yeah, but fcgi runs a seperate python for each cgi, so I'd need to somehow communicate with that python. My ideal solution would be to have publish_module() reload its module every time (which is no time loss if the module hasn't changed). How can I tell publish_module() to do this? Ick, this doesn't deal with submodules properly, what I want is to have publish_module() re-import everything every time. Maybe if I take them out of sys.modules... I'm also having trouble with ZP exceptions, threads, sockets, and a few other things. Phillip was mentioning his fcgi efforts, so perhaps I needn't worry. My current approach is to use the fcgiapp module and an fcgi-module-publisher that's similar to cgi-module-publisher with fcgi.Accept() and fcgi.Finish() around it. Phillip, as soon you've gotten your fcgi working I'd love to see what you come up with.
I guess it's all pickled in the var directory and in various dtml / python source lying around, but I'm much more comfortable editing python and dtml with vim than filling out web forms / downloading stuff developed off-line. I guess ZServer's ftp server ought to make this a bit nicer, but I thought a nifty solution would be to write zope as a filesystem server
Well, writing the Zope FTP server is kind of like doing this, but only in a cross platform way ;-)
Yeah, sorta. But you have a rather restricted set of commands available. Maybe I could scratch together a python shell you can use to easily traverse the Zope hierarchy, run arbitrary shell commands on its objects and fake up browser-like ways to call them. In hand with the python / Zope debugger, this could be pretty useful. I gather medusa provides a ability to connect to a running server and feed python strings to it, perhaps they could be hooked together? That way you could admin your site by either going to /manage and entering your password, or, when you need something more powerful and low-level , telnetting into a special port talking to Zope in python. Or maybe you're just not on a machine that has a fancy graphical browser with frames, javascript and diddly-doo, and a fast net connection (as I frequently am), or maybe you don't want to have to fire up huge X and huger browser just to make a quick change (as I frequently do). Feasible? Reasonable? I've been looking through Response.py in an attempt to figure out how to insert my own exception handlers in. I want to be able to say raise mail_forms.UserError, "You need to fill out the 'name' field." and have that spit out an appropriately admonitory dtml. Or say: raise UserdbError, "Ack! Assertion diddly-doo wound up with doodly-dee!" and have that spit out a "I'm so sorry, but I screwed up, an error report has been mailed and I'm on it." message, meanwhile fishing the python state out of the traceback object and sending everything relevant to me. I'd also like to replace the default exception handling routine so I can have something a little more appropriate than "Sorry, an error occurred." (these are apparently hardcoded in Response.py?) and also be able to customize the traceback output without hand-hacking Response.py, since I don't care if people see my source code. Or for that matter, I could not show them anything and have the stack trace mailed to me, as I mentioned earlier. Of course, hopefully all of this can be done per-module, like __bobo_hide_tracebacks__ or whatever it's called, although maybe a little nicer than setting magic variables. Hmmm, would it be exceptionally weird (BOO HISS) to have the handler inside the traceback itself? Then each exception could be handled differently: raise UserdbError("Unexpected death scream!", mail_me=1) raise UserdbError("Expected death scream.", mail_me=0, error_doc=error_docs.temporary_failure) And of course, whoever catches them chooses whether to run their handler or just inspect their data and do something else. You get the idea. I can just wrap my published objects in a try except but that gets tedious after a while. Zope also still uses string exceptions. Unless there is significant need for python 1.4 compatibility, it shouldn't be too hard to come up with some sort of simple hierarchy, is that in the works? I understand "Bobo" is being phased out in favor of "Zope." I mourn. Zope is a cool word and all, but Bobo is, well, Bobo. Zopers will have to do some thinking to come up with a database name that flows as mellifluously off the tongue as "Bobobase". Well, maybe "flows mellifluously" isn't the right term... tumbles off the lips? But anyway, it sounds very sturdy. I picture this large chimpanzee hoarding all these little gizmos, which he will let you borrow if you ask him. In fact, Zopers miss the ability, when asked "how do you run your site?", to answer "I run it on Bobo", and having the other person momentarily get the image of the same big chimp squatting in your server room and manhandling html out the http port. Then "I run Bobo on Linux" and we see this short fat little penguin ordering this talented chimp around your server room. Grazing on the cables in the corner is a small herd of huge smelly Gnus who occaisionally do some of the heavy work. I don't mourn the loss of "Principia" quite so much. It's very dignified and all... I see this big "Principia Internetica" tome, dispensing its erudite trove of information to the elite (those who paid for it). And then there's the unfelicitous image of something that tries to be the Monolithic Ultimate Solution, only to be undermined by pesky Austrians. But "Bobo"... the passing of a gem...
At 12:44 AM 2/8/99 -0800, Quinn Dunkan wrote:
One more general purpose way of handling shutting down is to include a published method which shuts down python, for example:
def shutdown(): "should require authorization to call this" raise SystemExit
Yeah, but fcgi runs a seperate python for each cgi, so I'd need to somehow communicate with that python. My ideal solution would be to have publish_module() reload its module every time (which is no time loss if the module hasn't changed). How can I tell publish_module() to do this? Ick, this doesn't deal with submodules properly, what I want is to have publish_module() re-import everything every time. Maybe if I take them
out of
sys.modules...
I'm also having trouble with ZP exceptions, threads, sockets, and a few other things.
Phillip was mentioning his fcgi efforts, so perhaps I needn't worry. My current approach is to use the fcgiapp module and an fcgi-module-publisher that's similar to cgi-module-publisher with fcgi.Accept() and fcgi.Finish() around it. Phillip, as soon you've gotten your fcgi working I'd love to see what you come up with.
If you check back in the list archives, looking for "Launcher.py" you should be able to find the first fcgi support code I did. It supports specifying MAX_REQUESTS, IDLE_TIMEOUT, and MAX_LIFETIME settings so the server will die after a set period. During development, it can be useful to set these all low, so that in the amount of time it takes you to make a code change, the server will have died off due to inactivity. :) And if it didn't die due to idleness, you can always hit reload a few times and max out MAX_REQUESTS. :) In practice, I hardly ever do this, as I use ZPublisher as the front-end to a Zope-like application server that runs off the filesystem instead of a ZBase. The app server notices when timestamps change and automatically reloads the files, so I don't have to kill off the server to see changes unless I'm changing the engine itself. My newer FastCGI code is more a matter of changing to use Robin Dunn's "fcgi" module in place of DC's "fcgiapp" so that it can be run multithreaded, and creating a class framework for standalone publishers that takes care of most of the messy plumbing overhead. I'm factoring the code into (proposed) ZPublisher.Config and ZPublisher.Plumbing. I hope to have some working code to present today. ZPublisher.Config is working quite spiffily, and most of the base Plumbing class is ready to go. I'm going to make test CGI(Plumbing) and FastCGI(Plumbing) classes next.
You get the idea. I can just wrap my published objects in a try except but that gets tedious after a while. Zope also still uses string exceptions. Unless there is significant need for python 1.4 compatibility, it shouldn't be too hard to come up with some sort of simple hierarchy, is that in the works?
You should be aware that there is a significant performance penalty for using class exceptions, if your code throws them a lot. This is particularly noticeable with Acquisition, which does deep searches a fair bit faster with the -X flag on.
At 10:55 AM 2/8/99 -0500, Phillip J. Eby wrote:
My newer FastCGI code is more a matter of changing to use Robin Dunn's "fcgi" module in place of DC's "fcgiapp" so that it can be run multithreaded, and creating a class framework for standalone publishers that takes care of most of the messy plumbing overhead. I'm factoring the code into (proposed) ZPublisher.Config and ZPublisher.Plumbing. I hope to have some working code to present today.
Well, here they are: ZPublisher.Config - configuration and publishing defaults for Zope ZPublisher.Plumbing - Zope "plumbing" base class w/subclasses for CGI & FastCGI Zopestart - A script for starting Zope under CGI or FastCGI I have been running Zope under an earlier FastCGI attempt for the last couple of weeks; and have been running this version for a few hours today. To use these files, you'll need to stick Plumbing.py and Config.py into the lib/python/ZPublisher directory of your Zope installation, and Zopestart someplace it can be executed by your CGI back-end. You can edit it to override "INSTANCE_HOME" or you can pass it INSTANCE_HOME in the environment. You will need a FastCGI-supporting server or a cgi-fcgi script to use it. It should be possible to create subclasses to handle PCGI and direct HTTP, but may not be worthwhile in favor of using ZServer.
At 03:22 PM 2/8/99 -0500, Phillip J. Eby wrote:
Well, here they are:
A couple of things I neglected to mention about those modules... Robin Dunn's fcgi.py apparently does not work with cgi-fcgi on IRIX. It hangs waiting to receive all of the STDIN stream. To get it to work on my platform, I had to hack it in two places to check CONTENT_LENGTH and modify its behavior accordingly. Apparently cgi-fcgi doesn't send an EOF on the STDIN stream until/unless Apache closes STDIN, and Apache isn't doing that. Why? Who knows. Second thing I neglected to mention... the USE_THREADS option is pretty much worthless on the same platform with Robin Dunn's fcgi.py, because when I enable it, the server seems to hang in a socket call somewhere. I suspect it's an IRIX sockets-and-threads-don't-mix type of problem. :( So much for having multithreaded FastCGI today. If anybody is using FastCGI on other platforms, could you please give the modules a try and let me know if they work with USE_THREADS=1? It would be nice to know whether it's an IRIX problem or whether I'm just not doing the thread stuff right. Thanks.
participants (2)
-
Phillip J. Eby -
Quinn Dunkan