Exception in thread Thread-8:
Traceback (most recent call last):
File "/usr/lib/python2.6/threading.py", line 525, in
__bootstrap_inner
self.run()
File "./server.py", line 53, in run
func()
File "./server.py", line 203, in index
self.finish()
File "/home/creotiv/tornado-app/branches/andrew/lib/tornado/
request.py", line 298, in finish
self.flush(include_footers=True)
File "/home/creotiv/tornado-app/branches/andrew/lib/tornado/
request.py", line 272, in flush
self.request.write(headers + chunk)
File "/home/creotiv/tornado-app/branches/andrew/lib/tornado/
httpserver.py", line 425, in write
self.connection.write(chunk)
File "/home/creotiv/tornado-app/branches/andrew/lib/tornado/
httpserver.py", line 263, in write
self.stream.write(chunk, self._on_write_complete)
File "/home/creotiv/tornado-app/branches/andrew/lib/tornado/
iostream.py", line 111, in write
self._check_closed()
File "/home/creotiv/tornado-app/branches/andrew/lib/tornado/
iostream.py", line 223, in _check_closed
raise IOError("Stream is closed")
IOError: Stream is closed
ERROR:root:Exception in I/O handler for fd 24
Traceback (most recent call last):
File "/home/creotiv/tornado-app/branches/andrew/lib/tornado/
ioloop.py", line 195, in start
self._handlers[fd](fd, events)
File "/home/creotiv/tornado-app/branches/andrew/lib/tornado/
iostream.py", line 161, in _handle_events
self.io_loop.update_handler(self.socket.fileno(), self._state)
File "/home/creotiv/tornado-app/branches/andrew/lib/tornado/
ioloop.py", line 132, in update_handler
self._impl.modify(fd, events | self.ERROR)
IOError: [Errno 9] Bad file descriptor
in thread i run this method:
def get(self):
self.set_header("Content-Type", "text/html;
charset=UTF-8")
#c.type = '13a'
self.render('test.html')
self.write('1')
self.finish()
Thread class is:
class PThread(threading.Thread):
def run(self):
global KillThread, ppool
logging.error("Thread "+self.name+" in work")
while True:
if KillThread:
logging.info("Thread "+self.name+" killed")
break
func = ppool.get()
if callable(func):
func()
else:
raise Exception, "It's not a function"
break
Where ppool is Queue.Queue()
Does anyone know what can cause this errors?
set it to 32K or something
--m
Any ideas?
have you added the @tornado.web.asynchronous decorator on your get()
method?
in the get()/post() I added the handler to a queue and returned
@tornado.web.asynchronous
def get(self):
taskQueue.add(('get',self));
def get_defered(self):
self.write('hello world'); # this is where the logic went
and a thread pool of 4 daemon threads was constantly doing
while True:
method, handler = taskQueue.get();
if method == 'get':
handler.get_defered();
elif method == 'post':
handler.post_defered();
I looked at your example.. and how i see it's work in the same way as
mine. And i think you might have the same error.
Try ab -c 1000 -n 1000 and look at your logs.
ab -n 1000 -c 1000 -t 10
> I made some wrapper for controller methods that run them in threads.
calling tornado functions from multiple threads will cause problems
like file descriptors getting closed unexpectedly and data structures
to get corrupted. all work in tornado is done in the context of a
single thread. it's single-threaded and event-driven, not
multi-threaded.
if the controller functions are cheap, then to use multiple cores,
just run multiple tornado instances.
if the controller functions are expensive, create a thread pool in
process or separate threaded daemon process and use ipc-like
communication mechanisms to have tornado dispatch to the pool, and be
notified when work is done.
the controller methods don't expect to be executed from different
threads, they expect to all be executed in the context of one (the
same) thread.
> So each controller methods executing in Thread context.
but there's only one HttpServer instance, so that gets confused when
called from different threads.
> And i don't understand what closing sockets. Cause one request can't
> close socket cause socket used for many requests. How i understand the
> code of Tornado. For each Tornado Process created IOStream wich work
> with one nonblocking socket that handle many requests.
> If you tell me what close stream of tornado process, i'll be very glad
> (ofcourse if this is not big problem for you)
>
what's being closed is a file descriptor, which represents one client
and can be read from and written to. the socket, in effect, creates a
file descriptor when a connection request from a client is accepted.
in tornado, only a single file descriptor is "active" at a particular
time. adding threads and dispatching controller methods to them does
not give each thread its own copy of the appropriate file descriptor;
instead, each controller method stomps over the state of all of the
rest of them. this isn't something to fix, though. in fact- this is a
good thing- you can get rid of 90% of the code you posted. the app
abstraction and the routes and the queue and the dispatching and all
of that is already done by tornado, and it already handles
concurrency- just not with threads.
On 5 янв, 04:19, Jonah Benton <jo...@jonah.com> wrote:
* the db operation may take a long time
* the db driver does not offer asynchronous notifications
the former probably has to be solved with caching- keeping results of
the expensive operation in memcached or something.
friendfeed and other folks don't seem to be concerned about blocking
drivers for short database operations. for long ones, this is really
about the drivers needing to offer an asynchronous callback interface.
the general solution here is complicated and should get into the
drivers, but for simple cases, a few query/result set types, one could
write a buffer/bridge layer.
a more architecturally-heavy approach is to put the data layer behind
its own http server, something threaded like cherrypy or web.py.
tornado talks to this using its non-blocking http client. the data
server bridges http verbs to whatever crud operations are needed on
the db, and returns json to tornado. this is similar to what people
are doing with couchdb, which does http and json natively. i imagine
the pattern will spread to other persistence engines.
Thank for your replies, they real help me)
> ...
>
> продолжение »
Have fun,
Mike
--
________________________________________________
Mike C. Fletcher
Designer, VR Plumber, Coder
http://www.vrplumber.com
http://blog.vrplumber.com
def _add_io_state(self, state):
if not self._state & state:
self._state = self._state | state
+ if self.socket:
self.io_loop.update_handler(self.socket.fileno(),
self._state)
+ else:
+ logging.error("_add_io_state() line 240 iostrem.py
FAILED")
+ self.close()
With this code server work even after some sockets fail. Will test
farther to see real problem of this.