[pypy-dev] Greenlet and socket

Olivier Dormond olivier.dormond at gmail.com
Mon Dec 19 15:05:24 CET 2005


Hi everyone,

Armin just told me that some dev was ongoing about getting a socket
implementation
using some basic coroutines like principle. I'm really interested by
this and I've even
written a veeery simple test programme using the greenlet that makes
using sockets
in an synchronous way, the simplest one, interract as if they were in
separate threads.

Is this new wonderfull implementation going along providing something that looks
like the following ? That would really be a tremendous feature to have
in a high-level
language :-)

Cheers,

     Olivier


#!/usr/bin/env python

from select import select
from socket import *
from py.magic import greenlet

iwt = []
owt = []
ewt = []

class greensocket(object):
    def __init__(self, family, type=SOCK_STREAM, proto=0):
        self._family = family
        self._socket = socket(family, type, proto)
        self._socket.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)

    def __getattr__(self, attr):
        return getattr(self._socket, attr)

    def accept(self):
        global iwt
        if not self in iwt:
            iwt.append(self)
        self._green = greenlet.getcurrent()
        greenlet.getcurrent().parent.switch()
        iwt.remove(self)
        s, addr = self._socket.accept()
        sock = greensocket(self._family)
        sock._socket = s
        return sock, addr

    def close(self):
        global iwt
        try:
            iwt.remove(self)
        except ValueError:
            pass
        self._socket.close()

    def recv(self, buffersize, flags=0):
        global iwt
        if not self in iwt:
            iwt.append(self)
        self._green = greenlet.getcurrent()
        greenlet.getcurrent().parent.switch()
        iwt.remove(self)
        return self._socket.recv(buffersize, flags)

    def switch(self, *args):
        self._green.switch(*args)

@greenlet
def printer():
    s = greensocket(AF_INET, SOCK_STREAM)
    s.bind(('0.0.0.0', 10000))
    s.listen(1)
    client, address = s.accept()
    while 1:
        line = client.recv(1024)
        line = line.strip()
        print "client says:", line
        client.sendall("done\n")

@greenlet
def computer():
    s = greensocket(AF_INET, SOCK_STREAM)
    s.bind(('0.0.0.0', 10001))
    s.listen(1)
    client, address = s.accept()
    while 1:
        line = client.recv(1024)
        line = line.strip()
        print "computing:", line
        client.sendall("result: "+`eval(line)`+"\n")

def main_loop():
    while 1:
        rs, ws, es = select(iwt, owt, ewt)
        for r in rs:
            r.switch()
        for w in ws:
            w.switch()
        for e in es:
            e.switch()

print "switching on the printer"
printer.switch()

print "switching on the computer"
computer.switch()

print "switching on the main loop"
main_loop()



More information about the Pypy-dev mailing list