twisted_integration.py :  » Web-Services » RPyC » rpyc-3.0.7 » rpyc » utils » Python Open Source

Home
Python Open Source
1.3.1.2 Python
2.Ajax
3.Aspect Oriented
4.Blog
5.Build
6.Business Application
7.Chart Report
8.Content Management Systems
9.Cryptographic
10.Database
11.Development
12.Editor
13.Email
14.ERP
15.Game 2D 3D
16.GIS
17.GUI
18.IDE
19.Installer
20.IRC
21.Issue Tracker
22.Language Interface
23.Log
24.Math
25.Media Sound Audio
26.Mobile
27.Network
28.Parser
29.PDF
30.Project Management
31.RSS
32.Search
33.Security
34.Template Engines
35.Test
36.UML
37.USB Serial
38.Web Frameworks
39.Web Server
40.Web Services
41.Web Unit
42.Wiki
43.Windows
44.XML
Python Open Source » Web Services » RPyC 
RPyC » rpyc 3.0.7 » rpyc » utils » twisted_integration.py
"""
rpyc-twisted integration, based on code originally contributed by noam raphael

Note: rpyc normally works in blocking (synchornous) fashion, for instance,
getting an attribute of an object (foo.bar.baz). the twistedish solution
would be using @inlineCallbacks and `yield (yield foo.bar).baz`... which is
rather less pythonistic.  

function calls, however, can be made asynchronous easily with the async() 
wrapper, so these will play nicely with twisted.

all in all, the integration with twisted is limited and rather fake. 
working with rpyc might block the reactor -- a bad thing -- but a necessary 
evil if we wish to combine the two methodologies.

if you find a better solution, please tell me.
"""
import socket
import rpyc
from rpyc.core import SocketStream,Channel
import twisted.internet.protocol as tip
from twisted.internet import reactor
from twisted.python import log


class TwistedSocketStream(SocketStream):
    def __init__(self, transport):
        SocketStream.__init__(self, transport.socket)
        self.transport = transport
        self._buffer = ""
    def push(self, data):
        self._buffer += data
    
    def poll(self, timeout):
        if self._buffer:
            return True
        self.sock.setblocking(True)
        try:
            return SocketStream.poll(self, timeout)
        finally:
            try:
                self.sock.setblocking(False)
            except socket.error:
                pass
    
    def read(self, count):
        if count <= len(self._buffer):
            data = self._buffer[:count]
            self._buffer = self._buffer[count:]
        else:
            self.sock.setblocking(True)
            try:
                data2 = SocketStream.read(self, count - len(self._buffer))
            finally:
                try:
                    self.sock.setblocking(False)
                except socket.error:
                    pass
            data = self._buffer + data2
            self._buffer = ""
        #log.msg("%s.read(%r)" % (self, data))
        return data
    
    def write(self, data):
        #log.msg("%s.write(%r)" % (self, data))
        self.sock.setblocking(True)
        try:
            SocketStream.write(self, data)
        finally:
            self.sock.setblocking(False)


class TwistedRpycProtocol(tip.Protocol):
    def __init__(self):
        self.stream = None
        self.conn = None
    def connectionMade(self):
        self.stream = TwistedSocketStream(self.transport)
        self.conn = rpyc.Connection(self.factory.service, Channel(self.stream), 
            config = self.factory.config, _lazy = True)
        self.conn._init_service()
        if self.factory.logging:
            log.msg("%s: connected %s" % (self, self.conn))
        if self.factory.on_connected is not None:
            reactor.callLater(0, self.factory.on_connected, self.conn)
    def connectionLost(self, reason=None):
        if self.conn:
            if self.factory.logging:
                log.msg("%s: closing connection %s" % (self, self.conn))
            c = self.conn
            self.conn = None
            c.close(_catchall = True)
    def dataReceived(self, data):
        self.stream.push(data)
        self.conn.poll_all()


class RpycClientFactory(tip.ClientFactory):
    protocol = TwistedRpycProtocol
    def __init__(self, service, on_connected = None, config = {}, logging = False):
        self.service = service
        self.config = config
        self.on_connected = on_connected
        self.logging = logging


RpycServerFactory = RpycClientFactory


www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.