changeset 98:06aa973a54c3

Made server and client objects into coroutines.
author Atul Varma <varmaa@toolness.com>
date Sat, 02 May 2009 00:47:23 -0700
parents 0d3dd2ab36cd
children b9cdccd5fbe4
files cosocket.py openwebchat.py
diffstat 2 files changed, 34 insertions(+), 34 deletions(-) [+]
line wrap: on
line diff
--- a/cosocket.py	Sat May 02 00:14:59 2009 -0700
+++ b/cosocket.py	Sat May 02 00:47:23 2009 -0700
@@ -111,13 +111,12 @@
             else:
                 self.__handler.handle_coroutine_instruction(instruction)
 
-class _AsyncChatCoroutineDispatcher(asynchat.async_chat):
+class AsyncChatCoroutine(asynchat.async_chat):
     def __init__(self, coroutine, conn = None):
         asynchat.async_chat.__init__(self, conn)
         self.trampoline = _Trampoline(coroutine, self)
         self.set_terminator(None)
-        if conn:
-            self.trampoline.continue_from_yield()
+        self.trampoline.continue_from_yield()
 
     def handle_coroutine_instruction(self, instruction):
         self.__instruction = instruction
@@ -145,6 +144,9 @@
                       self.trampoline.get_formatted_coroutine_traceback(),
                       'error')
 
+    def handle_accept(self):
+        self.__instruction.handle_accept()
+
     def handle_connect(self):
         self.__instruction.handle_connect()
 
@@ -168,30 +170,6 @@
     def found_terminator(self):
         self.__instruction.found_terminator()
 
-class CoroutineSocketServer(asyncore.dispatcher):
-    def __init__(self, addr, coroutineFactory):
-        asyncore.dispatcher.__init__(self)
-        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, timeout = DEFAULT_LOOP_TIMEOUT):
-        loop(timeout)
-
-    def handle_accept(self):
-        conn, addr = self.accept()
-        coroutine = self.__coroutineFactory(addr)
-        _AsyncChatCoroutineDispatcher(coroutine, conn)
-
-class CoroutineSocketClient(_AsyncChatCoroutineDispatcher):
-    def __init__(self, addr, coroutineFactory):
-        coroutine = coroutineFactory(addr)
-        _AsyncChatCoroutineDispatcher.__init__(self, coroutine)
-        self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
-        self.connect(addr)
-
 # Instructions that coroutines yield.
 
 class CoroutineInstruction(object):
@@ -206,6 +184,27 @@
     def handle_timeout(self):
         self.dispatcher.handle_close()
 
+class until_connection_accepted(CoroutineInstruction):
+    def do_execute(self, bind_addr):
+        if not self.dispatcher.socket:
+            self.dispatcher.create_socket(socket.AF_INET,
+                                          socket.SOCK_STREAM)
+            self.dispatcher.set_reuse_addr()
+            self.dispatcher.bind(bind_addr)
+            self.dispatcher.listen(1)
+
+    def handle_accept(self):
+        data = self.dispatcher.accept()
+        self.dispatcher.trampoline.continue_from_yield(data)
+
+class until_connected(CoroutineInstruction):
+    def do_execute(self, addr):
+        self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
+        self.connect(addr)
+
+    def handle_connect(self):
+        self.dispatcher.trampoline.continue_from_yield()
+
 class until_received(CoroutineInstruction):
     def do_execute(self,
                    terminator = None,
--- a/openwebchat.py	Sat May 02 00:14:59 2009 -0700
+++ b/openwebchat.py	Sat May 02 00:47:23 2009 -0700
@@ -80,11 +80,7 @@
         self._is_keep_alive = is_keep_alive
         self._num_connections = 0
         self._convs = conversations
-        self._server = CoroutineSocketServer(addr,
-                                             self._server_coroutine)
-
-    def run(self):
-        self._server.run()
+        AsyncChatCoroutine(self._server_coroutine(addr))
 
     def _until_http_response_sent(self, msg = '', mimetype = 'text/plain',
                                   length = None, code = 200,
@@ -128,7 +124,12 @@
             block = infile.read(self.BLOCK_SIZE)
             yield until_sent(block)
 
-    def _server_coroutine(self, addr):
+    def _server_coroutine(self, bind_addr):
+        while 1:
+            conn, addr = yield until_connection_accepted(bind_addr)
+            AsyncChatCoroutine(self._connection_coroutine(addr), conn)
+
+    def _connection_coroutine(self, addr):
         self._num_connections += 1
         try:
             if self._is_keep_alive:
@@ -324,4 +325,4 @@
                                conversations = Conversations(),
                                is_keep_alive = args.is_keep_alive)
     logging.info("Starting server with configuration: %s" % args)
-    server.run()
+    loop()