annotate cosocket.py @ 95:57681224a62a

Attempted to factor out the trampoline into a separate object, and modified the way coroutine instructions are done.
author Atul Varma <varmaa@toolness.com>
date Fri, 01 May 2009 23:41:52 -0700
parents abb3952c2209
children 68598f164855
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
23
1683a8fc76b0 Exception tracebacks in coroutines are now much more helpful.
Atul Varma <varmaa@toolness.com>
parents: 22
diff changeset
1 import sys
0
fb5e84a8eb8a Origination.
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
2 import socket
1
f1159b9ec823 Initial implementation of coroutine-based server.
Atul Varma <varmaa@toolness.com>
parents: 0
diff changeset
3 import asyncore
f1159b9ec823 Initial implementation of coroutine-based server.
Atul Varma <varmaa@toolness.com>
parents: 0
diff changeset
4 import asynchat
12
1ffa6554ff3a coroutines can now yield other coroutines, which are called in a nested manner.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
5 import types
18
69efb6cdc127 Added some error-handling code, though the channel code is raising exceptions in it at the moment I think.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
6 import traceback
85
7e3b3eb57ec2 Added the ability for a server to have a timeout function that gets called once per second.
Atul Varma <varmaa@toolness.com>
parents: 23
diff changeset
7 import time
86
408738c3cd5d Added a handle_tick function to coroutine dispatchers.
Atul Varma <varmaa@toolness.com>
parents: 85
diff changeset
8 import weakref
90
0b8c3a21335c Added support for logging.
Atul Varma <varmaa@toolness.com>
parents: 88
diff changeset
9 import logging
86
408738c3cd5d Added a handle_tick function to coroutine dispatchers.
Atul Varma <varmaa@toolness.com>
parents: 85
diff changeset
10
93
3be28af79baf Fixed a really bad bug in timeout detection.
Atul Varma <varmaa@toolness.com>
parents: 90
diff changeset
11 DEFAULT_LOOP_TIMEOUT = 1.0
87
43d37495e9d4 Added timeout functionality.
Atul Varma <varmaa@toolness.com>
parents: 86
diff changeset
12 DEFAULT_TIMEOUT = 90.0
88
ce5060140af5 Added maximum data length checking.
Atul Varma <varmaa@toolness.com>
parents: 87
diff changeset
13 DEFAULT_MAX_DATA = 65536
86
408738c3cd5d Added a handle_tick function to coroutine dispatchers.
Atul Varma <varmaa@toolness.com>
parents: 85
diff changeset
14
87
43d37495e9d4 Added timeout functionality.
Atul Varma <varmaa@toolness.com>
parents: 86
diff changeset
15 time_map = {}
43d37495e9d4 Added timeout functionality.
Atul Varma <varmaa@toolness.com>
parents: 86
diff changeset
16
93
3be28af79baf Fixed a really bad bug in timeout detection.
Atul Varma <varmaa@toolness.com>
parents: 90
diff changeset
17 def loop(timeout = DEFAULT_LOOP_TIMEOUT):
86
408738c3cd5d Added a handle_tick function to coroutine dispatchers.
Atul Varma <varmaa@toolness.com>
parents: 85
diff changeset
18 start_time = time.time()
408738c3cd5d Added a handle_tick function to coroutine dispatchers.
Atul Varma <varmaa@toolness.com>
parents: 85
diff changeset
19 while 1:
408738c3cd5d Added a handle_tick function to coroutine dispatchers.
Atul Varma <varmaa@toolness.com>
parents: 85
diff changeset
20 asyncore.loop(timeout = timeout, count = 1)
408738c3cd5d Added a handle_tick function to coroutine dispatchers.
Atul Varma <varmaa@toolness.com>
parents: 85
diff changeset
21 curr_time = time.time()
408738c3cd5d Added a handle_tick function to coroutine dispatchers.
Atul Varma <varmaa@toolness.com>
parents: 85
diff changeset
22 time_elapsed = curr_time - start_time
408738c3cd5d Added a handle_tick function to coroutine dispatchers.
Atul Varma <varmaa@toolness.com>
parents: 85
diff changeset
23 if time_elapsed > timeout:
408738c3cd5d Added a handle_tick function to coroutine dispatchers.
Atul Varma <varmaa@toolness.com>
parents: 85
diff changeset
24 start_time = curr_time
93
3be28af79baf Fixed a really bad bug in timeout detection.
Atul Varma <varmaa@toolness.com>
parents: 90
diff changeset
25 funcs_to_call = []
3be28af79baf Fixed a really bad bug in timeout detection.
Atul Varma <varmaa@toolness.com>
parents: 90
diff changeset
26 for func in time_map:
3be28af79baf Fixed a really bad bug in timeout detection.
Atul Varma <varmaa@toolness.com>
parents: 90
diff changeset
27 time_map[func] -= time_elapsed
3be28af79baf Fixed a really bad bug in timeout detection.
Atul Varma <varmaa@toolness.com>
parents: 90
diff changeset
28 if time_map[func] <= 0:
3be28af79baf Fixed a really bad bug in timeout detection.
Atul Varma <varmaa@toolness.com>
parents: 90
diff changeset
29 funcs_to_call.append(func)
3be28af79baf Fixed a really bad bug in timeout detection.
Atul Varma <varmaa@toolness.com>
parents: 90
diff changeset
30 for func in funcs_to_call:
3be28af79baf Fixed a really bad bug in timeout detection.
Atul Varma <varmaa@toolness.com>
parents: 90
diff changeset
31 del time_map[func]
3be28af79baf Fixed a really bad bug in timeout detection.
Atul Varma <varmaa@toolness.com>
parents: 90
diff changeset
32 for func in funcs_to_call:
3be28af79baf Fixed a really bad bug in timeout detection.
Atul Varma <varmaa@toolness.com>
parents: 90
diff changeset
33 try:
3be28af79baf Fixed a really bad bug in timeout detection.
Atul Varma <varmaa@toolness.com>
parents: 90
diff changeset
34 func()
3be28af79baf Fixed a really bad bug in timeout detection.
Atul Varma <varmaa@toolness.com>
parents: 90
diff changeset
35 except:
3be28af79baf Fixed a really bad bug in timeout detection.
Atul Varma <varmaa@toolness.com>
parents: 90
diff changeset
36 logging.error(traceback.format_exc())
1
f1159b9ec823 Initial implementation of coroutine-based server.
Atul Varma <varmaa@toolness.com>
parents: 0
diff changeset
37
95
57681224a62a Attempted to factor out the trampoline into a separate object, and modified the way coroutine instructions are done.
Atul Varma <varmaa@toolness.com>
parents: 94
diff changeset
38 class _Trampoline(object):
57681224a62a Attempted to factor out the trampoline into a separate object, and modified the way coroutine instructions are done.
Atul Varma <varmaa@toolness.com>
parents: 94
diff changeset
39 def __init__(self, coroutine, handler):
57681224a62a Attempted to factor out the trampoline into a separate object, and modified the way coroutine instructions are done.
Atul Varma <varmaa@toolness.com>
parents: 94
diff changeset
40 self.__handler = handler
2
f6f9cc0385be Clients can now be coroutines too.
Atul Varma <varmaa@toolness.com>
parents: 1
diff changeset
41 self.__coroutine = coroutine
12
1ffa6554ff3a coroutines can now yield other coroutines, which are called in a nested manner.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
42 self.__coroutine_stack = []
95
57681224a62a Attempted to factor out the trampoline into a separate object, and modified the way coroutine instructions are done.
Atul Varma <varmaa@toolness.com>
parents: 94
diff changeset
43
57681224a62a Attempted to factor out the trampoline into a separate object, and modified the way coroutine instructions are done.
Atul Varma <varmaa@toolness.com>
parents: 94
diff changeset
44 def __log_error(self):
57681224a62a Attempted to factor out the trampoline into a separate object, and modified the way coroutine instructions are done.
Atul Varma <varmaa@toolness.com>
parents: 94
diff changeset
45 logging.error(traceback.format_exc() +
57681224a62a Attempted to factor out the trampoline into a separate object, and modified the way coroutine instructions are done.
Atul Varma <varmaa@toolness.com>
parents: 94
diff changeset
46 self.get_formatted_coroutine_traceback())
57681224a62a Attempted to factor out the trampoline into a separate object, and modified the way coroutine instructions are done.
Atul Varma <varmaa@toolness.com>
parents: 94
diff changeset
47
57681224a62a Attempted to factor out the trampoline into a separate object, and modified the way coroutine instructions are done.
Atul Varma <varmaa@toolness.com>
parents: 94
diff changeset
48 def __close_coroutine(self, coroutine):
57681224a62a Attempted to factor out the trampoline into a separate object, and modified the way coroutine instructions are done.
Atul Varma <varmaa@toolness.com>
parents: 94
diff changeset
49 try:
57681224a62a Attempted to factor out the trampoline into a separate object, and modified the way coroutine instructions are done.
Atul Varma <varmaa@toolness.com>
parents: 94
diff changeset
50 coroutine.close()
57681224a62a Attempted to factor out the trampoline into a separate object, and modified the way coroutine instructions are done.
Atul Varma <varmaa@toolness.com>
parents: 94
diff changeset
51 except Exception:
57681224a62a Attempted to factor out the trampoline into a separate object, and modified the way coroutine instructions are done.
Atul Varma <varmaa@toolness.com>
parents: 94
diff changeset
52 self.__log_error()
57681224a62a Attempted to factor out the trampoline into a separate object, and modified the way coroutine instructions are done.
Atul Varma <varmaa@toolness.com>
parents: 94
diff changeset
53
57681224a62a Attempted to factor out the trampoline into a separate object, and modified the way coroutine instructions are done.
Atul Varma <varmaa@toolness.com>
parents: 94
diff changeset
54 def get_formatted_coroutine_traceback(self):
57681224a62a Attempted to factor out the trampoline into a separate object, and modified the way coroutine instructions are done.
Atul Varma <varmaa@toolness.com>
parents: 94
diff changeset
55 if not self.__coroutine:
57681224a62a Attempted to factor out the trampoline into a separate object, and modified the way coroutine instructions are done.
Atul Varma <varmaa@toolness.com>
parents: 94
diff changeset
56 return ""
57681224a62a Attempted to factor out the trampoline into a separate object, and modified the way coroutine instructions are done.
Atul Varma <varmaa@toolness.com>
parents: 94
diff changeset
57 lines = ['Coroutine traceback (most recent call last):']
57681224a62a Attempted to factor out the trampoline into a separate object, and modified the way coroutine instructions are done.
Atul Varma <varmaa@toolness.com>
parents: 94
diff changeset
58 frames = [coroutine.gi_frame
57681224a62a Attempted to factor out the trampoline into a separate object, and modified the way coroutine instructions are done.
Atul Varma <varmaa@toolness.com>
parents: 94
diff changeset
59 for coroutine in self.__coroutine_stack]
57681224a62a Attempted to factor out the trampoline into a separate object, and modified the way coroutine instructions are done.
Atul Varma <varmaa@toolness.com>
parents: 94
diff changeset
60 frames.append(self.__coroutine.gi_frame)
57681224a62a Attempted to factor out the trampoline into a separate object, and modified the way coroutine instructions are done.
Atul Varma <varmaa@toolness.com>
parents: 94
diff changeset
61 for frame in frames:
57681224a62a Attempted to factor out the trampoline into a separate object, and modified the way coroutine instructions are done.
Atul Varma <varmaa@toolness.com>
parents: 94
diff changeset
62 name = frame.f_code.co_name
57681224a62a Attempted to factor out the trampoline into a separate object, and modified the way coroutine instructions are done.
Atul Varma <varmaa@toolness.com>
parents: 94
diff changeset
63 filename = frame.f_code.co_filename
57681224a62a Attempted to factor out the trampoline into a separate object, and modified the way coroutine instructions are done.
Atul Varma <varmaa@toolness.com>
parents: 94
diff changeset
64 lineno = frame.f_lineno
57681224a62a Attempted to factor out the trampoline into a separate object, and modified the way coroutine instructions are done.
Atul Varma <varmaa@toolness.com>
parents: 94
diff changeset
65 lines.append('File "%s", line %d, in coroutine %s' %
57681224a62a Attempted to factor out the trampoline into a separate object, and modified the way coroutine instructions are done.
Atul Varma <varmaa@toolness.com>
parents: 94
diff changeset
66 (filename, lineno, name))
57681224a62a Attempted to factor out the trampoline into a separate object, and modified the way coroutine instructions are done.
Atul Varma <varmaa@toolness.com>
parents: 94
diff changeset
67 return '\n'.join(lines)
57681224a62a Attempted to factor out the trampoline into a separate object, and modified the way coroutine instructions are done.
Atul Varma <varmaa@toolness.com>
parents: 94
diff changeset
68
57681224a62a Attempted to factor out the trampoline into a separate object, and modified the way coroutine instructions are done.
Atul Varma <varmaa@toolness.com>
parents: 94
diff changeset
69 def close_coroutine_stack(self):
57681224a62a Attempted to factor out the trampoline into a separate object, and modified the way coroutine instructions are done.
Atul Varma <varmaa@toolness.com>
parents: 94
diff changeset
70 if self.__coroutine:
57681224a62a Attempted to factor out the trampoline into a separate object, and modified the way coroutine instructions are done.
Atul Varma <varmaa@toolness.com>
parents: 94
diff changeset
71 # Pass an exception back into the coroutine to kick
57681224a62a Attempted to factor out the trampoline into a separate object, and modified the way coroutine instructions are done.
Atul Varma <varmaa@toolness.com>
parents: 94
diff changeset
72 # it out of whatever yielding state it's in.
57681224a62a Attempted to factor out the trampoline into a separate object, and modified the way coroutine instructions are done.
Atul Varma <varmaa@toolness.com>
parents: 94
diff changeset
73 self.__close_coroutine(self.__coroutine)
57681224a62a Attempted to factor out the trampoline into a separate object, and modified the way coroutine instructions are done.
Atul Varma <varmaa@toolness.com>
parents: 94
diff changeset
74 self.__coroutine = None
57681224a62a Attempted to factor out the trampoline into a separate object, and modified the way coroutine instructions are done.
Atul Varma <varmaa@toolness.com>
parents: 94
diff changeset
75 while self.__coroutine_stack:
57681224a62a Attempted to factor out the trampoline into a separate object, and modified the way coroutine instructions are done.
Atul Varma <varmaa@toolness.com>
parents: 94
diff changeset
76 self.__close_coroutine(self.__coroutine_stack.pop())
1
f1159b9ec823 Initial implementation of coroutine-based server.
Atul Varma <varmaa@toolness.com>
parents: 0
diff changeset
77
22
425776983cf2 Removed the weakref mechanism from channels.py and instead turned until_message_received() into a generator rather than an object. Added a return_value() instruction to cosocket.
Atul Varma <varmaa@toolness.com>
parents: 21
diff changeset
78 def close_coroutine_and_return_to_caller(self, message):
425776983cf2 Removed the weakref mechanism from channels.py and instead turned until_message_received() into a generator rather than an object. Added a return_value() instruction to cosocket.
Atul Varma <varmaa@toolness.com>
parents: 21
diff changeset
79 self.__close_coroutine(self.__coroutine)
425776983cf2 Removed the weakref mechanism from channels.py and instead turned until_message_received() into a generator rather than an object. Added a return_value() instruction to cosocket.
Atul Varma <varmaa@toolness.com>
parents: 21
diff changeset
80 if self.__coroutine_stack:
425776983cf2 Removed the weakref mechanism from channels.py and instead turned until_message_received() into a generator rather than an object. Added a return_value() instruction to cosocket.
Atul Varma <varmaa@toolness.com>
parents: 21
diff changeset
81 self.__coroutine = self.__coroutine_stack.pop()
425776983cf2 Removed the weakref mechanism from channels.py and instead turned until_message_received() into a generator rather than an object. Added a return_value() instruction to cosocket.
Atul Varma <varmaa@toolness.com>
parents: 21
diff changeset
82 self.continue_from_yield(message)
425776983cf2 Removed the weakref mechanism from channels.py and instead turned until_message_received() into a generator rather than an object. Added a return_value() instruction to cosocket.
Atul Varma <varmaa@toolness.com>
parents: 21
diff changeset
83 else:
425776983cf2 Removed the weakref mechanism from channels.py and instead turned until_message_received() into a generator rather than an object. Added a return_value() instruction to cosocket.
Atul Varma <varmaa@toolness.com>
parents: 21
diff changeset
84 self.__coroutine = None
425776983cf2 Removed the weakref mechanism from channels.py and instead turned until_message_received() into a generator rather than an object. Added a return_value() instruction to cosocket.
Atul Varma <varmaa@toolness.com>
parents: 21
diff changeset
85
95
57681224a62a Attempted to factor out the trampoline into a separate object, and modified the way coroutine instructions are done.
Atul Varma <varmaa@toolness.com>
parents: 94
diff changeset
86 def continue_from_yield(self, message = None, exception_info = None):
1
f1159b9ec823 Initial implementation of coroutine-based server.
Atul Varma <varmaa@toolness.com>
parents: 0
diff changeset
87 try:
23
1683a8fc76b0 Exception tracebacks in coroutines are now much more helpful.
Atul Varma <varmaa@toolness.com>
parents: 22
diff changeset
88 if exception_info:
1683a8fc76b0 Exception tracebacks in coroutines are now much more helpful.
Atul Varma <varmaa@toolness.com>
parents: 22
diff changeset
89 instruction = self.__coroutine.throw(*exception_info)
18
69efb6cdc127 Added some error-handling code, though the channel code is raising exceptions in it at the moment I think.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
90 else:
69efb6cdc127 Added some error-handling code, though the channel code is raising exceptions in it at the moment I think.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
91 instruction = self.__coroutine.send(message)
1
f1159b9ec823 Initial implementation of coroutine-based server.
Atul Varma <varmaa@toolness.com>
parents: 0
diff changeset
92 except StopIteration:
12
1ffa6554ff3a coroutines can now yield other coroutines, which are called in a nested manner.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
93 if self.__coroutine_stack:
1ffa6554ff3a coroutines can now yield other coroutines, which are called in a nested manner.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
94 self.__coroutine = self.__coroutine_stack.pop()
21
b77e679ce993 Renamed return_from_yield() to continue_from_yield().
Atul Varma <varmaa@toolness.com>
parents: 19
diff changeset
95 self.continue_from_yield()
12
1ffa6554ff3a coroutines can now yield other coroutines, which are called in a nested manner.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
96 else:
18
69efb6cdc127 Added some error-handling code, though the channel code is raising exceptions in it at the moment I think.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
97 self.__coroutine = None
95
57681224a62a Attempted to factor out the trampoline into a separate object, and modified the way coroutine instructions are done.
Atul Varma <varmaa@toolness.com>
parents: 94
diff changeset
98 self.__handler.handle_coroutine_complete()
18
69efb6cdc127 Added some error-handling code, though the channel code is raising exceptions in it at the moment I think.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
99 except Exception, e:
69efb6cdc127 Added some error-handling code, though the channel code is raising exceptions in it at the moment I think.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
100 if self.__coroutine_stack:
69efb6cdc127 Added some error-handling code, though the channel code is raising exceptions in it at the moment I think.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
101 self.__coroutine = self.__coroutine_stack.pop()
23
1683a8fc76b0 Exception tracebacks in coroutines are now much more helpful.
Atul Varma <varmaa@toolness.com>
parents: 22
diff changeset
102 self.continue_from_yield(exception_info = sys.exc_info())
18
69efb6cdc127 Added some error-handling code, though the channel code is raising exceptions in it at the moment I think.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
103 else:
95
57681224a62a Attempted to factor out the trampoline into a separate object, and modified the way coroutine instructions are done.
Atul Varma <varmaa@toolness.com>
parents: 94
diff changeset
104 self.__log_error()
11
8574ff006a28 instructions are now objects.
Atul Varma <varmaa@toolness.com>
parents: 10
diff changeset
105 else:
12
1ffa6554ff3a coroutines can now yield other coroutines, which are called in a nested manner.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
106 if type(instruction) == types.GeneratorType:
1ffa6554ff3a coroutines can now yield other coroutines, which are called in a nested manner.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
107 self.__coroutine_stack.append(self.__coroutine)
1ffa6554ff3a coroutines can now yield other coroutines, which are called in a nested manner.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
108 self.__coroutine = instruction
21
b77e679ce993 Renamed return_from_yield() to continue_from_yield().
Atul Varma <varmaa@toolness.com>
parents: 19
diff changeset
109 self.continue_from_yield()
12
1ffa6554ff3a coroutines can now yield other coroutines, which are called in a nested manner.
Atul Varma <varmaa@toolness.com>
parents: 11
diff changeset
110 else:
95
57681224a62a Attempted to factor out the trampoline into a separate object, and modified the way coroutine instructions are done.
Atul Varma <varmaa@toolness.com>
parents: 94
diff changeset
111 instruction.execute(self.__handler)
18
69efb6cdc127 Added some error-handling code, though the channel code is raising exceptions in it at the moment I think.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
112
95
57681224a62a Attempted to factor out the trampoline into a separate object, and modified the way coroutine instructions are done.
Atul Varma <varmaa@toolness.com>
parents: 94
diff changeset
113 class _AsyncChatCoroutineDispatcher(asynchat.async_chat):
57681224a62a Attempted to factor out the trampoline into a separate object, and modified the way coroutine instructions are done.
Atul Varma <varmaa@toolness.com>
parents: 94
diff changeset
114 def __init__(self, coroutine, conn = None):
57681224a62a Attempted to factor out the trampoline into a separate object, and modified the way coroutine instructions are done.
Atul Varma <varmaa@toolness.com>
parents: 94
diff changeset
115 asynchat.async_chat.__init__(self, conn)
57681224a62a Attempted to factor out the trampoline into a separate object, and modified the way coroutine instructions are done.
Atul Varma <varmaa@toolness.com>
parents: 94
diff changeset
116 self.trampoline = _Trampoline(coroutine, self)
57681224a62a Attempted to factor out the trampoline into a separate object, and modified the way coroutine instructions are done.
Atul Varma <varmaa@toolness.com>
parents: 94
diff changeset
117 self.set_terminator(None)
57681224a62a Attempted to factor out the trampoline into a separate object, and modified the way coroutine instructions are done.
Atul Varma <varmaa@toolness.com>
parents: 94
diff changeset
118 self.__max_data = DEFAULT_MAX_DATA
57681224a62a Attempted to factor out the trampoline into a separate object, and modified the way coroutine instructions are done.
Atul Varma <varmaa@toolness.com>
parents: 94
diff changeset
119 self.__timeout = 0
57681224a62a Attempted to factor out the trampoline into a separate object, and modified the way coroutine instructions are done.
Atul Varma <varmaa@toolness.com>
parents: 94
diff changeset
120 self.__data = []
57681224a62a Attempted to factor out the trampoline into a separate object, and modified the way coroutine instructions are done.
Atul Varma <varmaa@toolness.com>
parents: 94
diff changeset
121 self.__data_len = 0
57681224a62a Attempted to factor out the trampoline into a separate object, and modified the way coroutine instructions are done.
Atul Varma <varmaa@toolness.com>
parents: 94
diff changeset
122 if conn:
57681224a62a Attempted to factor out the trampoline into a separate object, and modified the way coroutine instructions are done.
Atul Varma <varmaa@toolness.com>
parents: 94
diff changeset
123 self.trampoline.continue_from_yield()
57681224a62a Attempted to factor out the trampoline into a separate object, and modified the way coroutine instructions are done.
Atul Varma <varmaa@toolness.com>
parents: 94
diff changeset
124
57681224a62a Attempted to factor out the trampoline into a separate object, and modified the way coroutine instructions are done.
Atul Varma <varmaa@toolness.com>
parents: 94
diff changeset
125 def handle_coroutine_complete(self):
57681224a62a Attempted to factor out the trampoline into a separate object, and modified the way coroutine instructions are done.
Atul Varma <varmaa@toolness.com>
parents: 94
diff changeset
126 self.handle_close()
86
408738c3cd5d Added a handle_tick function to coroutine dispatchers.
Atul Varma <varmaa@toolness.com>
parents: 85
diff changeset
127
18
69efb6cdc127 Added some error-handling code, though the channel code is raising exceptions in it at the moment I think.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
128 def handle_close(self):
95
57681224a62a Attempted to factor out the trampoline into a separate object, and modified the way coroutine instructions are done.
Atul Varma <varmaa@toolness.com>
parents: 94
diff changeset
129 self.trampoline.close_coroutine_stack()
87
43d37495e9d4 Added timeout functionality.
Atul Varma <varmaa@toolness.com>
parents: 86
diff changeset
130 self.clear_timeout()
18
69efb6cdc127 Added some error-handling code, though the channel code is raising exceptions in it at the moment I think.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
131 self.close()
69efb6cdc127 Added some error-handling code, though the channel code is raising exceptions in it at the moment I think.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
132
69efb6cdc127 Added some error-handling code, though the channel code is raising exceptions in it at the moment I think.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
133 def log_info(self, message, type='info'):
90
0b8c3a21335c Added support for logging.
Atul Varma <varmaa@toolness.com>
parents: 88
diff changeset
134 try:
0b8c3a21335c Added support for logging.
Atul Varma <varmaa@toolness.com>
parents: 88
diff changeset
135 level = getattr(logging, type.upper())
0b8c3a21335c Added support for logging.
Atul Varma <varmaa@toolness.com>
parents: 88
diff changeset
136 except AttributeError:
0b8c3a21335c Added support for logging.
Atul Varma <varmaa@toolness.com>
parents: 88
diff changeset
137 level = logging.INFO
0b8c3a21335c Added support for logging.
Atul Varma <varmaa@toolness.com>
parents: 88
diff changeset
138 logging.log(level, message)
18
69efb6cdc127 Added some error-handling code, though the channel code is raising exceptions in it at the moment I think.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
139
69efb6cdc127 Added some error-handling code, though the channel code is raising exceptions in it at the moment I think.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
140 def handle_error(self):
86
408738c3cd5d Added a handle_tick function to coroutine dispatchers.
Atul Varma <varmaa@toolness.com>
parents: 85
diff changeset
141 self.log_info(traceback.format_exc() +
95
57681224a62a Attempted to factor out the trampoline into a separate object, and modified the way coroutine instructions are done.
Atul Varma <varmaa@toolness.com>
parents: 94
diff changeset
142 self.trampoline.get_formatted_coroutine_traceback(),
86
408738c3cd5d Added a handle_tick function to coroutine dispatchers.
Atul Varma <varmaa@toolness.com>
parents: 85
diff changeset
143 'error')
18
69efb6cdc127 Added some error-handling code, though the channel code is raising exceptions in it at the moment I think.
Atul Varma <varmaa@toolness.com>
parents: 16
diff changeset
144
2
f6f9cc0385be Clients can now be coroutines too.
Atul Varma <varmaa@toolness.com>
parents: 1
diff changeset
145 def handle_connect(self):
95
57681224a62a Attempted to factor out the trampoline into a separate object, and modified the way coroutine instructions are done.
Atul Varma <varmaa@toolness.com>
parents: 94
diff changeset
146 self.trampoline.continue_from_yield()
2
f6f9cc0385be Clients can now be coroutines too.
Atul Varma <varmaa@toolness.com>
parents: 1
diff changeset
147
1
f1159b9ec823 Initial implementation of coroutine-based server.
Atul Varma <varmaa@toolness.com>
parents: 0
diff changeset
148 def initiate_send(self):
f1159b9ec823 Initial implementation of coroutine-based server.
Atul Varma <varmaa@toolness.com>
parents: 0
diff changeset
149 asynchat.async_chat.initiate_send(self)
f1159b9ec823 Initial implementation of coroutine-based server.
Atul Varma <varmaa@toolness.com>
parents: 0
diff changeset
150 if ((not self.ac_out_buffer) and
f1159b9ec823 Initial implementation of coroutine-based server.
Atul Varma <varmaa@toolness.com>
parents: 0
diff changeset
151 (len(self.producer_fifo) == 0) and
f1159b9ec823 Initial implementation of coroutine-based server.
Atul Varma <varmaa@toolness.com>
parents: 0
diff changeset
152 self.connected):
95
57681224a62a Attempted to factor out the trampoline into a separate object, and modified the way coroutine instructions are done.
Atul Varma <varmaa@toolness.com>
parents: 94
diff changeset
153 self.trampoline.continue_from_yield()
1
f1159b9ec823 Initial implementation of coroutine-based server.
Atul Varma <varmaa@toolness.com>
parents: 0
diff changeset
154
93
3be28af79baf Fixed a really bad bug in timeout detection.
Atul Varma <varmaa@toolness.com>
parents: 90
diff changeset
155 def __on_timeout(self):
3be28af79baf Fixed a really bad bug in timeout detection.
Atul Varma <varmaa@toolness.com>
parents: 90
diff changeset
156 self.log_info("Timeout expired (%ss)." % self.__timeout,
3be28af79baf Fixed a really bad bug in timeout detection.
Atul Varma <varmaa@toolness.com>
parents: 90
diff changeset
157 'error')
3be28af79baf Fixed a really bad bug in timeout detection.
Atul Varma <varmaa@toolness.com>
parents: 90
diff changeset
158 self.handle_close()
87
43d37495e9d4 Added timeout functionality.
Atul Varma <varmaa@toolness.com>
parents: 86
diff changeset
159
43d37495e9d4 Added timeout functionality.
Atul Varma <varmaa@toolness.com>
parents: 86
diff changeset
160 def clear_timeout(self):
43d37495e9d4 Added timeout functionality.
Atul Varma <varmaa@toolness.com>
parents: 86
diff changeset
161 self.__timeout = 0
93
3be28af79baf Fixed a really bad bug in timeout detection.
Atul Varma <varmaa@toolness.com>
parents: 90
diff changeset
162 if self.__on_timeout in time_map:
3be28af79baf Fixed a really bad bug in timeout detection.
Atul Varma <varmaa@toolness.com>
parents: 90
diff changeset
163 del time_map[self.__on_timeout]
87
43d37495e9d4 Added timeout functionality.
Atul Varma <varmaa@toolness.com>
parents: 86
diff changeset
164
43d37495e9d4 Added timeout functionality.
Atul Varma <varmaa@toolness.com>
parents: 86
diff changeset
165 def set_timeout(self, timeout):
43d37495e9d4 Added timeout functionality.
Atul Varma <varmaa@toolness.com>
parents: 86
diff changeset
166 self.__timeout = timeout
93
3be28af79baf Fixed a really bad bug in timeout detection.
Atul Varma <varmaa@toolness.com>
parents: 90
diff changeset
167 time_map[self.__on_timeout] = timeout
87
43d37495e9d4 Added timeout functionality.
Atul Varma <varmaa@toolness.com>
parents: 86
diff changeset
168
1
f1159b9ec823 Initial implementation of coroutine-based server.
Atul Varma <varmaa@toolness.com>
parents: 0
diff changeset
169 def collect_incoming_data(self, data):
f1159b9ec823 Initial implementation of coroutine-based server.
Atul Varma <varmaa@toolness.com>
parents: 0
diff changeset
170 self.__data.append(data)
88
ce5060140af5 Added maximum data length checking.
Atul Varma <varmaa@toolness.com>
parents: 87
diff changeset
171 self.__data_len += len(data)
ce5060140af5 Added maximum data length checking.
Atul Varma <varmaa@toolness.com>
parents: 87
diff changeset
172 if self.__max_data and self.__data_len > self.__max_data:
90
0b8c3a21335c Added support for logging.
Atul Varma <varmaa@toolness.com>
parents: 88
diff changeset
173 self.log_info("Max data reached (%s bytes)." % self.__max_data,
0b8c3a21335c Added support for logging.
Atul Varma <varmaa@toolness.com>
parents: 88
diff changeset
174 'error')
88
ce5060140af5 Added maximum data length checking.
Atul Varma <varmaa@toolness.com>
parents: 87
diff changeset
175 self.handle_close()
ce5060140af5 Added maximum data length checking.
Atul Varma <varmaa@toolness.com>
parents: 87
diff changeset
176
ce5060140af5 Added maximum data length checking.
Atul Varma <varmaa@toolness.com>
parents: 87
diff changeset
177 def set_max_data(self, amount):
ce5060140af5 Added maximum data length checking.
Atul Varma <varmaa@toolness.com>
parents: 87
diff changeset
178 self.__max_data = amount
1
f1159b9ec823 Initial implementation of coroutine-based server.
Atul Varma <varmaa@toolness.com>
parents: 0
diff changeset
179
f1159b9ec823 Initial implementation of coroutine-based server.
Atul Varma <varmaa@toolness.com>
parents: 0
diff changeset
180 def found_terminator(self):
88
ce5060140af5 Added maximum data length checking.
Atul Varma <varmaa@toolness.com>
parents: 87
diff changeset
181 if not (self.__max_data and self.__data_len > self.__max_data):
ce5060140af5 Added maximum data length checking.
Atul Varma <varmaa@toolness.com>
parents: 87
diff changeset
182 self.set_terminator(None)
ce5060140af5 Added maximum data length checking.
Atul Varma <varmaa@toolness.com>
parents: 87
diff changeset
183 data = ''.join(self.__data)
ce5060140af5 Added maximum data length checking.
Atul Varma <varmaa@toolness.com>
parents: 87
diff changeset
184 self.__data = []
ce5060140af5 Added maximum data length checking.
Atul Varma <varmaa@toolness.com>
parents: 87
diff changeset
185 self.__data_len = 0
95
57681224a62a Attempted to factor out the trampoline into a separate object, and modified the way coroutine instructions are done.
Atul Varma <varmaa@toolness.com>
parents: 94
diff changeset
186 self.trampoline.continue_from_yield(data)
1
f1159b9ec823 Initial implementation of coroutine-based server.
Atul Varma <varmaa@toolness.com>
parents: 0
diff changeset
187
7
d3ae3fc76711 Removed all use of the word 'Chatty'
Atul Varma <varmaa@toolness.com>
parents: 6
diff changeset
188 class CoroutineSocketServer(asyncore.dispatcher):
86
408738c3cd5d Added a handle_tick function to coroutine dispatchers.
Atul Varma <varmaa@toolness.com>
parents: 85
diff changeset
189 def __init__(self, addr, coroutineFactory):
3
9e819377ce9f Changed the way coroutine factories work.
Atul Varma <varmaa@toolness.com>
parents: 2
diff changeset
190 asyncore.dispatcher.__init__(self)
9e819377ce9f Changed the way coroutine factories work.
Atul Varma <varmaa@toolness.com>
parents: 2
diff changeset
191 self.__coroutineFactory = coroutineFactory
9e819377ce9f Changed the way coroutine factories work.
Atul Varma <varmaa@toolness.com>
parents: 2
diff changeset
192 self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
9e819377ce9f Changed the way coroutine factories work.
Atul Varma <varmaa@toolness.com>
parents: 2
diff changeset
193 self.set_reuse_addr()
9e819377ce9f Changed the way coroutine factories work.
Atul Varma <varmaa@toolness.com>
parents: 2
diff changeset
194 self.bind(addr)
9e819377ce9f Changed the way coroutine factories work.
Atul Varma <varmaa@toolness.com>
parents: 2
diff changeset
195 self.listen(1)
9e819377ce9f Changed the way coroutine factories work.
Atul Varma <varmaa@toolness.com>
parents: 2
diff changeset
196
93
3be28af79baf Fixed a really bad bug in timeout detection.
Atul Varma <varmaa@toolness.com>
parents: 90
diff changeset
197 def run(self, timeout = DEFAULT_LOOP_TIMEOUT):
86
408738c3cd5d Added a handle_tick function to coroutine dispatchers.
Atul Varma <varmaa@toolness.com>
parents: 85
diff changeset
198 loop(timeout)
3
9e819377ce9f Changed the way coroutine factories work.
Atul Varma <varmaa@toolness.com>
parents: 2
diff changeset
199
9e819377ce9f Changed the way coroutine factories work.
Atul Varma <varmaa@toolness.com>
parents: 2
diff changeset
200 def handle_accept(self):
9e819377ce9f Changed the way coroutine factories work.
Atul Varma <varmaa@toolness.com>
parents: 2
diff changeset
201 conn, addr = self.accept()
5
4ec829dc7d1d Renamed ChatInstructions to 'to_send()', 'to_receive()' for readability.
Atul Varma <varmaa@toolness.com>
parents: 4
diff changeset
202 coroutine = self.__coroutineFactory(addr)
11
8574ff006a28 instructions are now objects.
Atul Varma <varmaa@toolness.com>
parents: 10
diff changeset
203 _AsyncChatCoroutineDispatcher(coroutine, conn)
3
9e819377ce9f Changed the way coroutine factories work.
Atul Varma <varmaa@toolness.com>
parents: 2
diff changeset
204
11
8574ff006a28 instructions are now objects.
Atul Varma <varmaa@toolness.com>
parents: 10
diff changeset
205 class CoroutineSocketClient(_AsyncChatCoroutineDispatcher):
3
9e819377ce9f Changed the way coroutine factories work.
Atul Varma <varmaa@toolness.com>
parents: 2
diff changeset
206 def __init__(self, addr, coroutineFactory):
5
4ec829dc7d1d Renamed ChatInstructions to 'to_send()', 'to_receive()' for readability.
Atul Varma <varmaa@toolness.com>
parents: 4
diff changeset
207 coroutine = coroutineFactory(addr)
11
8574ff006a28 instructions are now objects.
Atul Varma <varmaa@toolness.com>
parents: 10
diff changeset
208 _AsyncChatCoroutineDispatcher.__init__(self, coroutine)
2
f6f9cc0385be Clients can now be coroutines too.
Atul Varma <varmaa@toolness.com>
parents: 1
diff changeset
209 self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
f6f9cc0385be Clients can now be coroutines too.
Atul Varma <varmaa@toolness.com>
parents: 1
diff changeset
210 self.connect(addr)
f6f9cc0385be Clients can now be coroutines too.
Atul Varma <varmaa@toolness.com>
parents: 1
diff changeset
211
6
fdcb6f3e1a0f Separated out example code into a separate file.
Atul Varma <varmaa@toolness.com>
parents: 5
diff changeset
212 # Instructions that coroutines yield.
fdcb6f3e1a0f Separated out example code into a separate file.
Atul Varma <varmaa@toolness.com>
parents: 5
diff changeset
213
95
57681224a62a Attempted to factor out the trampoline into a separate object, and modified the way coroutine instructions are done.
Atul Varma <varmaa@toolness.com>
parents: 94
diff changeset
214 class CoroutineInstruction(object):
57681224a62a Attempted to factor out the trampoline into a separate object, and modified the way coroutine instructions are done.
Atul Varma <varmaa@toolness.com>
parents: 94
diff changeset
215 def __init__(self, *args, **kwargs):
57681224a62a Attempted to factor out the trampoline into a separate object, and modified the way coroutine instructions are done.
Atul Varma <varmaa@toolness.com>
parents: 94
diff changeset
216 self.__args = args
57681224a62a Attempted to factor out the trampoline into a separate object, and modified the way coroutine instructions are done.
Atul Varma <varmaa@toolness.com>
parents: 94
diff changeset
217 self.__kwargs = kwargs
1
f1159b9ec823 Initial implementation of coroutine-based server.
Atul Varma <varmaa@toolness.com>
parents: 0
diff changeset
218
11
8574ff006a28 instructions are now objects.
Atul Varma <varmaa@toolness.com>
parents: 10
diff changeset
219 def execute(self, dispatcher):
95
57681224a62a Attempted to factor out the trampoline into a separate object, and modified the way coroutine instructions are done.
Atul Varma <varmaa@toolness.com>
parents: 94
diff changeset
220 self.dispatcher = dispatcher
57681224a62a Attempted to factor out the trampoline into a separate object, and modified the way coroutine instructions are done.
Atul Varma <varmaa@toolness.com>
parents: 94
diff changeset
221 self.do_execute(*self.__args, **self.__kwargs)
11
8574ff006a28 instructions are now objects.
Atul Varma <varmaa@toolness.com>
parents: 10
diff changeset
222
95
57681224a62a Attempted to factor out the trampoline into a separate object, and modified the way coroutine instructions are done.
Atul Varma <varmaa@toolness.com>
parents: 94
diff changeset
223 class until_received(CoroutineInstruction):
57681224a62a Attempted to factor out the trampoline into a separate object, and modified the way coroutine instructions are done.
Atul Varma <varmaa@toolness.com>
parents: 94
diff changeset
224 def do_execute(self,
57681224a62a Attempted to factor out the trampoline into a separate object, and modified the way coroutine instructions are done.
Atul Varma <varmaa@toolness.com>
parents: 94
diff changeset
225 terminator = None,
57681224a62a Attempted to factor out the trampoline into a separate object, and modified the way coroutine instructions are done.
Atul Varma <varmaa@toolness.com>
parents: 94
diff changeset
226 bytes = None,
57681224a62a Attempted to factor out the trampoline into a separate object, and modified the way coroutine instructions are done.
Atul Varma <varmaa@toolness.com>
parents: 94
diff changeset
227 timeout = DEFAULT_TIMEOUT,
57681224a62a Attempted to factor out the trampoline into a separate object, and modified the way coroutine instructions are done.
Atul Varma <varmaa@toolness.com>
parents: 94
diff changeset
228 max_data = DEFAULT_MAX_DATA):
57681224a62a Attempted to factor out the trampoline into a separate object, and modified the way coroutine instructions are done.
Atul Varma <varmaa@toolness.com>
parents: 94
diff changeset
229 self.dispatcher.set_timeout(timeout)
57681224a62a Attempted to factor out the trampoline into a separate object, and modified the way coroutine instructions are done.
Atul Varma <varmaa@toolness.com>
parents: 94
diff changeset
230 if terminator:
57681224a62a Attempted to factor out the trampoline into a separate object, and modified the way coroutine instructions are done.
Atul Varma <varmaa@toolness.com>
parents: 94
diff changeset
231 max_data = 0
57681224a62a Attempted to factor out the trampoline into a separate object, and modified the way coroutine instructions are done.
Atul Varma <varmaa@toolness.com>
parents: 94
diff changeset
232 self.dispatcher.set_terminator(terminator)
57681224a62a Attempted to factor out the trampoline into a separate object, and modified the way coroutine instructions are done.
Atul Varma <varmaa@toolness.com>
parents: 94
diff changeset
233 elif bytes:
57681224a62a Attempted to factor out the trampoline into a separate object, and modified the way coroutine instructions are done.
Atul Varma <varmaa@toolness.com>
parents: 94
diff changeset
234 self.dispatcher.set_terminator(bytes)
57681224a62a Attempted to factor out the trampoline into a separate object, and modified the way coroutine instructions are done.
Atul Varma <varmaa@toolness.com>
parents: 94
diff changeset
235 else:
57681224a62a Attempted to factor out the trampoline into a separate object, and modified the way coroutine instructions are done.
Atul Varma <varmaa@toolness.com>
parents: 94
diff changeset
236 raise ValueError('Must specify terminator or bytes')
57681224a62a Attempted to factor out the trampoline into a separate object, and modified the way coroutine instructions are done.
Atul Varma <varmaa@toolness.com>
parents: 94
diff changeset
237 self.dispatcher.set_max_data(max_data)
22
425776983cf2 Removed the weakref mechanism from channels.py and instead turned until_message_received() into a generator rather than an object. Added a return_value() instruction to cosocket.
Atul Varma <varmaa@toolness.com>
parents: 21
diff changeset
238
95
57681224a62a Attempted to factor out the trampoline into a separate object, and modified the way coroutine instructions are done.
Atul Varma <varmaa@toolness.com>
parents: 94
diff changeset
239 class until_sent(CoroutineInstruction):
57681224a62a Attempted to factor out the trampoline into a separate object, and modified the way coroutine instructions are done.
Atul Varma <varmaa@toolness.com>
parents: 94
diff changeset
240 def do_execute(self, content, timeout = DEFAULT_TIMEOUT):
57681224a62a Attempted to factor out the trampoline into a separate object, and modified the way coroutine instructions are done.
Atul Varma <varmaa@toolness.com>
parents: 94
diff changeset
241 self.dispatcher.set_timeout(timeout)
57681224a62a Attempted to factor out the trampoline into a separate object, and modified the way coroutine instructions are done.
Atul Varma <varmaa@toolness.com>
parents: 94
diff changeset
242 self.dispatcher.push(content)
22
425776983cf2 Removed the weakref mechanism from channels.py and instead turned until_message_received() into a generator rather than an object. Added a return_value() instruction to cosocket.
Atul Varma <varmaa@toolness.com>
parents: 21
diff changeset
243
95
57681224a62a Attempted to factor out the trampoline into a separate object, and modified the way coroutine instructions are done.
Atul Varma <varmaa@toolness.com>
parents: 94
diff changeset
244 class return_value(CoroutineInstruction):
57681224a62a Attempted to factor out the trampoline into a separate object, and modified the way coroutine instructions are done.
Atul Varma <varmaa@toolness.com>
parents: 94
diff changeset
245 def do_execute(self, value):
57681224a62a Attempted to factor out the trampoline into a separate object, and modified the way coroutine instructions are done.
Atul Varma <varmaa@toolness.com>
parents: 94
diff changeset
246 self.dispatcher.trampoline.close_coroutine_and_return_to_caller(value)