You are viewing a plain text version of this content. The canonical link for it is here.
Posted to mod_python-dev@quetz.apache.org by Jack Diederich <ja...@email.com> on 2003/04/11 10:29:42 UTC

re: psp internals

Grr, I sent this yesterday but I typo'd the list address.

1 - I have a dozen pop accounts, I can't remember why I
    subscribed to this list via webmail.  I would kill 
    for mutt right now (I wrote this even _before_ I messed
    up the mail addr)

2 - The scope of psp is ambitious, and as Grisha mentions
    in a later email large parts of it fall outside of
    mod_python's narrow (in the UNIX do one thing well sense)
    scope.

3 - Comments on the framework in general

3a quick python is not php is not python summary

python is alot more unix-y and hacker centric than php.
php users are just hacks.  Which is fine, it isn't written
for comp sci guys, it is written for non-programmers who
just want to get semething done.  I use php to prototype 
web UIs, but a programming language it is not.  The 
languages evolved for different purposes and the 
communities that used the languages shaped them all the 
way along.

So as others have pointed out, taking a python centric
approach is a good idea if you want python users to try it.
Something like psp could be a good bridge for php users to
try out python.

A good python-eque (and unixy) way to write the framework
is to write a bunch of tools with a final veneer labeled 'psp'
that brings them all together.  I was pretty appalled when
reading the mod_php source.  It looked like the whole language
was intentionally gimped so you would have to pay for the
acceleration engines.  And the monolithic nature of php
rubs me the wrong way too.  Some of this is being addressed
by PEAR.

3b

[the rest of this is more boring and more implementaion
oriented.  All opinions are mine, and are just opinions.
If there was one right way everyone would already be doing it]

The tools that are already written are apache, mod_python,
python, and the psp parser.

For large scale/stupid fast deployments you'll need some
kind of caching engine.  The easiest way would be to write
a python wrapper for an existing cross platform shared
memory package.  OSSPmm looks like a good choice.
http://www.ossp.org/pkg/lib/mm/
A drawback is that you need to allocate the segment before
you fork apache.  This is not the case with more platform
specific shared memory schemes.  I posted some patches for
2.7.x to do pre-fork importing of python but they were dropped
since no one really needed them and 3.x was ongoing.
I don't know how applicable they would be to apache 2.x

The best way would be to write a seperate caching server
that could communicate over unix sockets, tcp/ip sockets,
or shared memory (or all 3).

As a general comment on your proposed framework, it
looks like php and not python.  mod_python uses a dict
for headers_in because it is easy to use and pythonic.
print req.headers['agent'] # Mmm
print req.get_header('agent') # Ack-Thpt!

> response.write(string data):  Write data to the browser
> response.flush(void):  Flush the data buffer to the user
let the user build up an entire page in the response, and
then send it.  low level IO is rarely used, more frequently
you build half a page and then need to bail.

> response.set_header(string name, string value):  Set a Header Value
use a dict

> response.set_cookie(string name, cookie value): Set a cookie 
use a dict, assign means set, read means get
req.cookies['session_id'] # simple read
req.cookie_obs['session_id'].expiry # access the detailed obs

> request.get_var([string name]): Returns the form object
in general, avoid get_ and set_ functions when a dict will do
most web frameworks try very hard to hide where data comes
from from the user.  I would at least like to be able to
query the CGI params and POST params seperately.  A catch all
request.anyvars['page_id'] # find 'page_id' anywhere you can
request.url_params['page_id'] # just check the URL
request.forms['topform']['page_id'] # just check one form

> cookie : contains information about a cookie
works for me, see my cookie_obs['cookiename'] comment above

> form : contains information about a form variable
forms are really hard to do well, there are a dozen python
implementations out there.  steal one.

> session : This relays information about the current session to the user
sessions are hard.  make sure that the user can subclass
session and use his as the default instead of working around
what you deam important for a session.

> Session variables are set via overloaded properties.
> session.start(): Start a session and send the headers
headers should be sent at session.end() !
(IMO all output should be sent at session end)

> session.register_handlers(dict handlers):
session is state, handlers should go somewhere else

> session.lock([string name]): Lock the session, mark it read-only
> session.unlock([string name]): Unlock the session, mark it writable
locks are common enough that they should be
lock.aquire(session, 'my_critical_section_1') # per-session
lock.release(session, 'my_critical_section_1')
lock.aquire('global_lock') # flat namespace, global
if there is a server-side state mechanism and the users are
using the default lock/unlock it for them behind the scenes
in critical sections.  If they wrote their own state
they can do it themselves (using lock.*)

> session.encode(string data): Encrypt session data using standard 
>                              encryption functions
> session.decode(string data): Decrypt session data using standard 
>                              encryption functions.
This is hard and probably won't do what you think it does.
It definitely won't do what the user thinks it does.

> session.get_cookie(void): Gets the session cookie object
The default implementation could use cookies.  If the user
is using the default implementation hide this fact from him.

> session.clear():  Clear the session
I don't know what this means.


The best thing to do for session and across-page storage
is to provide data storage with explicit and limited garuntees.
S = Singleton() # might be session, where we keep stuff there
is only one of

S.global_cache
# A dict, if you put something in it isn't garunteed to stay
# there.  Good place for things you can calculate anytime
# but will use again and again

S.page_cache
# like global_cache, but only lasts for just this page hit

S.session
# garunteed storage for this session
# this either IS the session object, or the session object
# is a wrapper that keeps stuff here in between hits

S.global
# garunteed storage for life.
# not very useful for real apps (they'll use a Db)
# but might be handy for weekend users writing one-offs

Note that global_cache gives you some speedup even if it
is per-process.  Also a great place to invisibly drop in
your shared memory or caching server implementation later.


-jack

-- 
_______________________________________________
Sign-up for your own FREE Personalized E-mail at Mail.com
http://www.mail.com/?sr=signup