Mercurial > cosocket
changeset 86:408738c3cd5d
Added a handle_tick function to coroutine dispatchers.
author | Atul Varma <varmaa@toolness.com> |
---|---|
date | Fri, 01 May 2009 15:37:57 -0700 |
parents | 7e3b3eb57ec2 |
children | 43d37495e9d4 |
files | cosocket.py openwebchat.py |
diffstat | 2 files changed, 47 insertions(+), 15 deletions(-) [+] |
line wrap: on
line diff
--- a/cosocket.py Fri May 01 14:18:06 2009 -0700 +++ b/cosocket.py Fri May 01 15:37:57 2009 -0700 @@ -5,9 +5,32 @@ import types import traceback import time +import weakref + +coroutine_dispatchers = [] + +def loop(timeout): + start_time = time.time() + while 1: + asyncore.loop(timeout = timeout, count = 1) + curr_time = time.time() + time_elapsed = curr_time - start_time + if time_elapsed > timeout: + start_time = curr_time + new_coroutine_dispatchers = [] + for ref in coroutine_dispatchers: + dispatcher = ref() + if dispatcher: + new_coroutine_dispatchers.append(ref) + try: + dispatcher.handle_tick(time_elapsed) + except: + dispatcher.handle_error() + coroutine_dispatchers[:] = new_coroutine_dispatchers class _AsyncChatCoroutineDispatcher(asynchat.async_chat): def __init__(self, coroutine, conn = None): + coroutine_dispatchers.append(weakref.ref(self)) asynchat.async_chat.__init__(self, conn) self.set_terminator(None) self.__coroutine = coroutine @@ -58,6 +81,23 @@ except Exception: self.log_info(traceback.format_exc(), 'error') + def get_coroutine_stack_frames(self): + return [coroutine.gi_frame + for coroutine in self.__coroutine_stack] + + def get_formatted_coroutine_traceback(self): + lines = ['Coroutine traceback (most recent call last):'] + for frame in self.get_coroutine_stack_frames(): + name = frame.f_code.co_name + filename = frame.f_code.co_filename + lineno = frame.f_lineno + lines.append('File "%s", line %d, in coroutine %s' % + (filename, lineno, name)) + return '\n'.join(lines) + + def handle_tick(self, time_elapsed): + pass + def handle_close(self): if self.__coroutine: # Pass an exception back into the coroutine to kick @@ -73,7 +113,9 @@ print '%s: %s' % (type, message) def handle_error(self): - self.log_info(traceback.format_exc(), 'error') + self.log_info(traceback.format_exc() + + self.get_formatted_coroutine_traceback(), + 'error') def handle_connect(self): self.continue_from_yield() @@ -96,26 +138,16 @@ self.continue_from_yield(data) class CoroutineSocketServer(asyncore.dispatcher): - TIMEOUT = 1.0 - - def __init__(self, addr, coroutineFactory, timeout_func = None): + def __init__(self, addr, coroutineFactory): asyncore.dispatcher.__init__(self) - self.__timeout_func = timeout_func self.__coroutineFactory = coroutineFactory self.create_socket(socket.AF_INET, socket.SOCK_STREAM) self.set_reuse_addr() self.bind(addr) self.listen(1) - def run(self): - start_time = time.time() - while 1: - asyncore.loop(timeout = self.TIMEOUT, count = 1) - curr_time = time.time() - time_elapsed = curr_time - start_time - if self.__timeout_func and time_elapsed > self.TIMEOUT: - start_time = curr_time - self.__timeout_func(time_elapsed) + def run(self, timeout): + loop(timeout) def handle_accept(self): conn, addr = self.accept()
--- a/openwebchat.py Fri May 01 14:18:06 2009 -0700 +++ b/openwebchat.py Fri May 01 15:37:57 2009 -0700 @@ -77,7 +77,7 @@ self._server_coroutine) def run(self): - self._server.run() + self._server.run(timeout = 5.0) def _until_http_response_sent(self, msg = '', mimetype = 'text/plain', length = None, code = 200,