Re: wepy

2006-04-20 Thread Mike Looijmans

import sys
sys.stdout.write(open('penguin.png', 'rb').read())



NO. NO. NO.

sys.stdout is a global variable. If you want sys.stdout.write() to end 
up in the user's terminal, your web server will be able to either serve 
only one request at a time, or must be forced into running separate 
processes for each concurrent request (which will not happen on windows 
and many other supported platforms).


We made that mistake with cgipython, and we won't make it again. Learn 
from the mistakes of others, as you do not have the time to make them 
all yourself.


Mike



Re: wepy

2006-04-20 Thread Fırat KÜÇÜK




import sys
sys.stdout.write(open('penguin.png', 'rb').read())




NO. NO. NO.

sys.stdout is a global variable. If you want sys.stdout.write() to end 
up in the user's terminal, your web server will be able to either 
serve only one request at a time, or must be forced into running 
separate processes for each concurrent request (which will not happen 
on windows and many other supported platforms).


We made that mistake with cgipython, and we won't make it again. Learn 
from the mistakes of others, as you do not have the time to make them 
all yourself.


Mike



Hi,
but i replaced sys.stdout with a StdOut class. is it problem too?

Fırat KÜÇÜK



Re: wepy

2006-04-20 Thread Fırat KÜÇÜK

Mike Looijmans yazmış:


Fırat KÜÇÜK wrote:


Hi,
we have been started a project called wepy! it is a modpython based 
PHP and

Python mix. Here are the some samples about wepy:



It would help a lot if you'd share with us exactly what you are trying 
to accomplish here. Your examples look a lot like the python CGI 
handler in mod_python.


A fully implemented modpython based PHP already exists and is 
built-in into mod_python as PSP. So it would help us help you if you 
told us what is is your project does (or will do) that isn't already 
in there.




Hi,

* can use PHP Session files
* familar global variables such as SERVER, GET, POST, COOKIE ...
* Code and design should be separated (cheetah can be used for this.)
 so coders can write scripts without %, ?, [[

will a new flavor for modpython.









Re: wepy

2006-04-20 Thread Mike Looijmans
Your code is perfectly thread safe, yes. But the assignment to 
sys.stdout IS NOT. There is only one sys.stdout, and all threads use the 
same one.


Example (two threads):

##Thread 1:
- initializes request from client 1
- sets sys.stdout to StdOut(request ...) object
- writes hello1  to sys.stdout
##Thread 2
- initializes request from client 2
- sets sys.stdout to StdOut(request ...) object
- writes hello2  to sys.stdout
##Thread 1
- writes world1 to sys.stdout
- terminates, and sends sys.stdout.buffer to client
##Thread 2
- writes world2 to sys.stdout
- terminates, and sends sys.stdout.buffer to client

Now look at what will happen with your code and a threading apache:
Client 1 will receive hello2 world1
Client 2 will receive hello2 world1world2

Explanation:

##Thread 1:
- initializes request from client 1
- sets sys.stdout to StdOut(request ...) object
- writes hello1  to sys.stdout
(sys.stdout.buffer == hello1 )
##Thread 2
- initializes request from client 2
- sets sys.stdout to StdOut(request ...) object
(and thus replaces the buffer that thread 1 put there, its contents are 
lost)

- writes hello2  to sys.stdout
(sys.stdout.buffer == hello2 )
##Thread 1
- writes world1 to sys.stdout
(sys.stdout.buffer == hello2 world1)
- terminates, and sends sys.stdout.buffer to client
##Thread 2
- writes world2 to sys.stdout
(sys.stdout.buffer == hello2 world1world2)
- terminates, and sends sys.stdout.buffer to client


Mike Looijmans
Philips Natlab / Topic Automation

Fırat KÜÇÜK wrote:

Mike Looijmans yazmış:


Yes,

the problem is not whatever class or method you use to send the output 
to the client, but the problem is the use of the global sys.stdout 
variable. The is only one such object in your system. If there are two 
threads each handling a request, there is no telling to which one the 
sys.stdout.write or print statement will send its output. To prevent 
this, you'd have to mutex access to it, and leads to being able to 
handle only one request at a time.


On many unix flavors, apache defaults to 'forking', which runs each 
request in a separate process. In these circumstances, you will not 
detect this problem. On other platforms, or if you modify the 
httpd.conf file, apache uses threading or even a mix of threading and 
forking.


Important note: Since print sends to sys.stdout, using print is just 
as bad a method to send output to the client as sys.stdout.write.


The only solution is to use the context in your handler, i.e.
WRITE(hello world\n)

or the more obvious (like in publisher and PSP):
req.write(Hello world\n)

Anything that makes use of globals to send back data to the client 
will not work, so wepi.write is also out of the question (if wepi is 
a module).


--
Mike Looijmans
Philips Natlab / Topic Automation


Fırat KÜÇÜK wrote:





import sys
sys.stdout.write(open('penguin.png', 'rb').read())







NO. NO. NO.

sys.stdout is a global variable. If you want sys.stdout.write() to 
end up in the user's terminal, your web server will be able to 
either serve only one request at a time, or must be forced into 
running separate processes for each concurrent request (which will 
not happen on windows and many other supported platforms).


We made that mistake with cgipython, and we won't make it again. 
Learn from the mistakes of others, as you do not have the time to 
make them all yourself.


Mike



Hi,
but i replaced sys.stdout with a StdOut class. is it problem too?

Fırat KÜÇÜK






Hi,


###[StdOut 
class]###


class StdOut:
   replaces sys.stdout

   buffer = 

   # --[overidden 
methods]-


   ### [__init__ method]---
   def __init__(self, req, headers_object):
   self.req = req
   self.headers = headers_object

   # -[public 
methods]-


   ### [write method]---
   def write(self, text): self.buffer += str(text)



this is my sys.stdout replacement class and write method use buffer.

and finally after execution of .py file

# send buffer
req.write(sys.stdout.buffer)

I think this is thread safe method for sending data.
print or sys.stdout.write indirectly use req.write method.


# send buffer
req.write(sys.stdout.buffer)






Re: wepy

2006-04-20 Thread Fırat KÜÇÜK

Mike Looijmans yazmış:

Your code is perfectly thread safe, yes. But the assignment to 
sys.stdout IS NOT. There is only one sys.stdout, and all threads use 
the same one.


Example (two threads):

##Thread 1:
- initializes request from client 1
- sets sys.stdout to StdOut(request ...) object
- writes hello1  to sys.stdout
##Thread 2
- initializes request from client 2
- sets sys.stdout to StdOut(request ...) object
- writes hello2  to sys.stdout
##Thread 1
- writes world1 to sys.stdout
- terminates, and sends sys.stdout.buffer to client
##Thread 2
- writes world2 to sys.stdout
- terminates, and sends sys.stdout.buffer to client

Now look at what will happen with your code and a threading apache:
Client 1 will receive hello2 world1
Client 2 will receive hello2 world1world2

Explanation:

##Thread 1:
- initializes request from client 1
- sets sys.stdout to StdOut(request ...) object
- writes hello1  to sys.stdout
(sys.stdout.buffer == hello1 )
##Thread 2
- initializes request from client 2
- sets sys.stdout to StdOut(request ...) object
(and thus replaces the buffer that thread 1 put there, its contents 
are lost)

- writes hello2  to sys.stdout
(sys.stdout.buffer == hello2 )
##Thread 1
- writes world1 to sys.stdout
(sys.stdout.buffer == hello2 world1)
- terminates, and sends sys.stdout.buffer to client
##Thread 2
- writes world2 to sys.stdout
(sys.stdout.buffer == hello2 world1world2)
- terminates, and sends sys.stdout.buffer to client


Mike Looijmans
Philips Natlab / Topic Automation

Fırat KÜÇÜK wrote:


Mike Looijmans yazmış:


Yes,

the problem is not whatever class or method you use to send the 
output to the client, but the problem is the use of the global 
sys.stdout variable. The is only one such object in your system. If 
there are two threads each handling a request, there is no telling 
to which one the sys.stdout.write or print statement will send its 
output. To prevent this, you'd have to mutex access to it, and leads 
to being able to handle only one request at a time.


On many unix flavors, apache defaults to 'forking', which runs each 
request in a separate process. In these circumstances, you will not 
detect this problem. On other platforms, or if you modify the 
httpd.conf file, apache uses threading or even a mix of threading 
and forking.


Important note: Since print sends to sys.stdout, using print is just 
as bad a method to send output to the client as sys.stdout.write.


The only solution is to use the context in your handler, i.e.
WRITE(hello world\n)

or the more obvious (like in publisher and PSP):
req.write(Hello world\n)

Anything that makes use of globals to send back data to the client 
will not work, so wepi.write is also out of the question (if wepi 
is a module).


--
Mike Looijmans
Philips Natlab / Topic Automation


Fırat KÜÇÜK wrote:





import sys
sys.stdout.write(open('penguin.png', 'rb').read())








NO. NO. NO.

sys.stdout is a global variable. If you want sys.stdout.write() to 
end up in the user's terminal, your web server will be able to 
either serve only one request at a time, or must be forced into 
running separate processes for each concurrent request (which will 
not happen on windows and many other supported platforms).


We made that mistake with cgipython, and we won't make it again. 
Learn from the mistakes of others, as you do not have the time to 
make them all yourself.


Mike



Hi,
but i replaced sys.stdout with a StdOut class. is it problem too?

Fırat KÜÇÜK






Hi,


###[StdOut 
class]###


class StdOut:
   replaces sys.stdout

   buffer = 

   # --[overidden 
methods]-


   ### [__init__ method]---
   def __init__(self, req, headers_object):
   self.req = req
   self.headers = headers_object

   # -[public 
methods]-


   ### [write method]---
   def write(self, text): self.buffer += str(text)



this is my sys.stdout replacement class and write method use buffer.

and finally after execution of .py file

# send buffer
req.write(sys.stdout.buffer)

I think this is thread safe method for sending data.
print or sys.stdout.write indirectly use req.write method.


# send buffer
req.write(sys.stdout.buffer)






Hi,
Yes i understood. so we should use an alias or directly req.write for it.
or print operator have to overload.

thanks.