[PEAK] Does a PEAK-ized webware esist ?

Phillip J. Eby pje at telecommunity.com
Wed Jan 28 20:03:40 EST 2004


At 06:41 PM 1/28/04 -0600, Ian Bicking wrote:
>On Jan 28, 2004, at 6:08 PM, Phillip J. Eby wrote:
>>At 06:49 PM 1/28/04 -0500, Phillip J. Eby wrote:
>>>At 11:57 PM 1/28/04 +0100, gian paolo ciceri wrote:
>>>
>>>
>>>>Hi all,
>>>>is somewhere an attempt to provide a PEAK wrapper
>>>>to webware (similar to the twisted one) ?
>>>
>>>I have zero WebWare experience.  But if you can point me to the "twisted 
>>>one" you refer to above, I might be able to offer a suggestion as to how 
>>>to port it.
>>
>>Actually, I just found it.  It looks sort of like the closest thing to 
>>doing that in PEAK would be to create an IRerunnableCGI adapter for 
>>either an Application or an AppServer.
>>
>>I get the impression it would look something like:
>>
>>class AppAsRerunnableCGI(protocols.Adapter):
>>
>>     protocols.advise(
>>         instancesProvide=[running.IRerunnableCGI],
>>         asAdapterForTypes=[Application],
>>     )
>>
>>     def runCGI(self,stdin,stdout,stderr,environ):
>>         self.subject.dispatchRawRequest(
>>             {
>>                   "format": "CGI",
>>                   "time": time.time(),
>>                   "environ": environ,
>>                   "input": stdin,       # XXX is this right?
>>             },
>>             stdout
>>         )
>>
>>The main parts I'm not sure about here are the input=stdin part and the 
>>directly passing 'stdout'.  Someone more familiar with Webware will 
>>hopefully pipe up on these aspects.
>
>Yep, that's pretty much what it comes down to.  In Webware the output 
>stream, though, is generally of type WebKit.ASStreamOut.ASStreamOut 
>(ack... that name shouldn't have slipped in there).  It has some extra 
>functions which control buffering.  Unfortunately, there's no good minimal 
>wrapper, but WebKit.ThreadedAppServer.TASASStreamOut (double ack) could be 
>easily modified to write to a file instead of a socket.

Hm.  So we need something like this:

class WebwareStream(ASStreamOut):

     def __init__(self, out):
         ASStreamOut.__init__(self)
         self._out = out

     def flush(self):
         debug=0
         result = ASStreamOut.flush(self)
         if result: ##a true return value means we can send
             self._out.write(self._buffer)
             self.pop(len(self._buffer)


and then runCGI will look like:

     def runCGI(self,stdin,stdout,stderr,environ):
         self.subject.dispatchRawRequest(
             {
                   "format": "CGI",
                   "time": time.time(),
                   "environ": environ,
                   "input": stdin,
             },
             WebwareStream(stdout)
         )

>Also, Webware has a lot of prints in it, so if you are actually outputing 
>a response to stdout, you should do a sys.stdout = stderr before running 
>Webware.  This is unfortunate as well, though not a big deal if you are 
>running Webware in its own process.

The only time 'stdout is sys.stdout' is for plain CGI requests, but 
somebody can always beef up the 'runCGI' above to save and restore 
sys.stdout around the call.


>Application also requires a server (typically AppServer), which has a few 
>methods you'd need to implement, though they are very minimal.

Yeah, ideally for PEAK integration I think you'd want to make Application 
use bindings for all the '_server', '_transactionClass', etc. stuff, and 
make '_server' a binding.Obtain(IWebwareAppServer).

More problematic for integration are things like calling the shutdown 
method, scheduler integration, and so on.




More information about the PEAK mailing list