changeset 12:1ffa6554ff3a

coroutines can now yield other coroutines, which are called in a nested manner.
author Atul Varma <varmaa@toolness.com>
date Sat, 18 Apr 2009 12:45:10 -0700
parents 8574ff006a28
children 65482f4e2555
files cosocket.py example.py
diffstat 2 files changed, 26 insertions(+), 10 deletions(-) [+]
line wrap: on
line diff
--- a/cosocket.py	Sat Apr 18 10:12:18 2009 -0700
+++ b/cosocket.py	Sat Apr 18 12:45:10 2009 -0700
@@ -1,6 +1,7 @@
 import socket
 import asyncore
 import asynchat
+import types
 
 class _AsyncChatCoroutineDispatcher(asynchat.async_chat):
     def __init__(self, coroutine, conn = None):
@@ -8,6 +9,7 @@
         self.set_terminator(None)
         self.__coroutine = coroutine
         self.__data = []
+        self.__coroutine_stack = []
         if conn:
             self.__process_next_instruction()
 
@@ -15,9 +17,18 @@
         try:
             instruction = self.__coroutine.send(feedback)
         except StopIteration:
-            self.close()
+            if self.__coroutine_stack:
+                self.__coroutine = self.__coroutine_stack.pop()
+                self.__process_next_instruction()
+            else:
+                self.close()
         else:
-            instruction.execute(self)
+            if type(instruction) == types.GeneratorType:
+                self.__coroutine_stack.append(self.__coroutine)
+                self.__coroutine = instruction
+                self.__process_next_instruction()
+            else:
+                instruction.execute(self)
 
     def handle_connect(self):
         self.__process_next_instruction()
--- a/example.py	Sat Apr 18 10:12:18 2009 -0700
+++ b/example.py	Sat Apr 18 12:45:10 2009 -0700
@@ -1,6 +1,6 @@
 from cosocket import *
 
-def lame_http_server_coroutine(addr):
+def example_http_server_coroutine(addr):
     request = yield until_received(terminator = '\r\n\r\n')
     msg = 'hello %s.' % addr[0]
     yield until_sent('HTTP/1.1 200 OK\r\n' +
@@ -8,17 +8,22 @@
                      'Content-Type: text/plain\r\n\r\n' +
                      msg)
 
-def lame_http_client_coroutine(addr):
+def _example_nested_coroutine():
+    chunk = yield until_received(bytes = 20)
+    print 'first chunk : %s' % repr(chunk)
+    chunk = yield until_received(bytes = 20)
+    print 'second chunk: %s' % repr(chunk)
+
+def example_http_client_coroutine(addr):
     yield until_sent('GET / HTTP/1.1\r\n\r\n')
     response_headers = yield until_received(terminator = '\r\n\r\n')
-    response = yield until_received(bytes = 20)
-    print 'first response: %s' % repr(response)
-    response = yield until_received(bytes = 20)
-    print 'second response: %s' % repr(response)
+    yield _example_nested_coroutine()
+    chunk = yield until_received(bytes = 20)
+    print 'third chunk : %s' % repr(chunk)
 
 if __name__ == '__main__':
     server = CoroutineSocketServer(('127.0.0.1', 8071),
-                                   lame_http_server_coroutine)
+                                   example_http_server_coroutine)
     client = CoroutineSocketClient(('www.google.com', 80),
-                                   lame_http_client_coroutine)
+                                   example_http_client_coroutine)
     server.run()