def blockOn(d): """ Wait for a Deferred to fire, and return its result directly. This function must be called from a non-reactor greenlet. @return: The result of the Deferred. @raise: The exception that the Deferred was fired with. """ current = greenlet.getcurrent() synchronous = [] def cb(result): if greenlet.getcurrent() is current: synchronous.append(result) else: current.switch(result) def eb(failure): if greenlet.getcurrent() is current: synchronous.append(failure) else: failure.throwExceptionIntoGenerator(current) d.addCallbacks(cb, eb) if synchronous: if isinstance(synchronous[0], Failure): synchronous[0].raiseException() return synchronous[0] return MAIN.switch()
def wait(seconds, clock=None): """ Wait a number of seconds before returning control to the calling greenlet. @param seconds: Number of seconds to wait. @type seconds: C{int} @param clock: The clock with which to schedule the return to this greenlet. @type clock: L{twisted.internet.interfaces.IReactorTime} provider. """ if clock is None: from twisted.internet import reactor as clock thisGreenlet = greenlet.getcurrent() clock.callLater(seconds, thisGreenlet.switch) return MAIN.switch()
def gConnectTCP(host, port, reactor=None): """ Return a L{GreenletTransport} connected to the given host and port. This function must NOT be called from the reactor's greenlet. """ from corotwine.defer import blockOn current = greenlet.getcurrent() assert current is not MAIN, \ "Don't run gConnectTCP from the reactor greenlet." if reactor is None: from twisted.internet import reactor d = Deferred() f = ClientFactory() f.protocol = lambda: _GreenletClientProtocol(d, current) reactor.connectTCP(host, port, f) return blockOn(d)
I/O support for greenlets on Twisted. See L{corotwine.examples} for examples of using the API in this module. By the way, I have a niggling suspicion that it's a really bad idea to use C{transport} from multiple greenlets. """ from twisted.internet.defer import Deferred from twisted.internet.protocol import Protocol, Factory, ClientFactory from twisted.internet.error import ConnectionLost, ConnectionDone from twisted.protocols.basic import LineReceiver from corotwine import greenlet MAIN = greenlet.getcurrent() READING, WRITING = range(2) __all__ = ["MAIN", "LineBuffer", "gListenTCP", "gConnectTCP"] class LineBuffer(object): """ A line-buffering wrapper for L{GreenletTransport}s (or any other object with C{read} and C{write} methods). Call L{readLine} to get the next line, call L{writeLine} to write a line. """ def __init__(self, transport, delimiter="\r\n"): """ @param transport: The transport from which to read bytes and to which
def eb(failure): if greenlet.getcurrent() is current: synchronous.append(failure) else: failure.throwExceptionIntoGenerator(current)
def cb(result): if greenlet.getcurrent() is current: synchronous.append(result) else: current.switch(result)
See L{corotwine.examples} for examples of using the API in this module. By the way, I have a niggling suspicion that it's a really bad idea to use C{transport} from multiple greenlets. """ from twisted.internet.defer import Deferred from twisted.internet.protocol import Protocol, Factory, ClientFactory from twisted.internet.error import ConnectionLost, ConnectionDone from twisted.protocols.basic import LineReceiver from corotwine import greenlet MAIN = greenlet.getcurrent() READING, WRITING = range(2) __all__ = ["MAIN", "LineBuffer", "gListenTCP", "gConnectTCP"] class LineBuffer(object): """ A line-buffering wrapper for L{GreenletTransport}s (or any other object with C{read} and C{write} methods). Call L{readLine} to get the next line, call L{writeLine} to write a line. """ def __init__(self, transport, delimiter="\r\n"): """