Mercurial > cosocket
changeset 13:65482f4e2555
Added a really simple channel communication system, somewhat similar to that of Stackless.
author | Atul Varma <varmaa@toolness.com> |
---|---|
date | Sun, 19 Apr 2009 12:55:38 -0700 |
parents | 1ffa6554ff3a |
children | 545927beb490 |
files | channels.py cosocket.py example.py |
diffstat | 3 files changed, 48 insertions(+), 14 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/channels.py Sun Apr 19 12:55:38 2009 -0700 @@ -0,0 +1,22 @@ +_channels = {} + +class until_message_sent(object): + def __init__(self, channel_name, message): + self.channel_name = channel_name + self.message = message + + def execute(self, dispatcher): + if self.channel_name in _channels: + for receiver in _channels[self.channel_name]: + receiver.return_from_yield(self.message) + _channels[self.channel_name] = [] + dispatcher.return_from_yield() + +class until_message_received(object): + def __init__(self, channel_name): + self.channel_name = channel_name + + def execute(self, dispatcher): + if self.channel_name not in _channels: + _channels[self.channel_name] = [] + _channels[self.channel_name].append(dispatcher)
--- a/cosocket.py Sat Apr 18 12:45:10 2009 -0700 +++ b/cosocket.py Sun Apr 19 12:55:38 2009 -0700 @@ -11,34 +11,34 @@ self.__data = [] self.__coroutine_stack = [] if conn: - self.__process_next_instruction() + self.return_from_yield() - def __process_next_instruction(self, feedback = None): + def return_from_yield(self, message = None): try: - instruction = self.__coroutine.send(feedback) + instruction = self.__coroutine.send(message) except StopIteration: if self.__coroutine_stack: self.__coroutine = self.__coroutine_stack.pop() - self.__process_next_instruction() + self.return_from_yield() else: self.close() else: if type(instruction) == types.GeneratorType: self.__coroutine_stack.append(self.__coroutine) self.__coroutine = instruction - self.__process_next_instruction() + self.return_from_yield() else: instruction.execute(self) def handle_connect(self): - self.__process_next_instruction() + self.return_from_yield() def initiate_send(self): asynchat.async_chat.initiate_send(self) if ((not self.ac_out_buffer) and (len(self.producer_fifo) == 0) and self.connected): - self.__process_next_instruction() + self.return_from_yield() def collect_incoming_data(self, data): # TODO: Enforce some maximum data length. @@ -48,7 +48,7 @@ self.set_terminator(None) data = ''.join(self.__data) self.__data = [] - self.__process_next_instruction(data) + self.return_from_yield(data) class CoroutineSocketServer(asyncore.dispatcher): def __init__(self, addr, coroutineFactory):
--- a/example.py Sat Apr 18 12:45:10 2009 -0700 +++ b/example.py Sun Apr 19 12:55:38 2009 -0700 @@ -1,12 +1,24 @@ from cosocket import * +import channels + +def _make_http_response(msg): + return ('HTTP/1.1 200 OK\r\n' + + 'Content-Length: %d\r\n' % len(msg) + + 'Content-Type: text/plain\r\n\r\n' + + msg) 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' + - 'Content-Length: %d\r\n' % len(msg) + - 'Content-Type: text/plain\r\n\r\n' + - msg) + request_line = yield until_received(terminator = '\r\n') + request_headers = yield until_received(terminator = '\r\n\r\n') + req_parts = request_line.split() + if req_parts[1] == '/listen': + ip = yield channels.until_message_received('global') + yield until_sent(_make_http_response('send from %s.' % ip)) + elif req_parts[1] == '/send': + yield channels.until_message_sent('global', addr[0]) + yield until_sent(_make_http_response('sent.')) + else: + yield until_sent(_make_http_response('hello %s.' % addr[0])) def _example_nested_coroutine(): chunk = yield until_received(bytes = 20)