Ticket #7274: resources.py

File resources.py, 3.2 KB (added by Daniel Sank, 8 years ago)

Definitions of the classes used in the client and server

Line 
1import twisted.spread.pb as pb
2import twisted.cred.portal as portal
3
4from twisted.internet import reactor
5from twisted.internet.defer import inlineCallbacks
6from twisted.cred import credentials
7from zope.interface import implements
8
9class Cacheable(pb.Cacheable):
10    """I'm a cacheable object which notifies observers when data is added"""
11    def __init__(self):
12        self.observers = {}
13   
14    def add(self, x):
15        for p in self.observers:
16            self.observers[p].callRemote("add", x)
17   
18    def getStateToCacheAndObserveFor(self, perspective, observer):
19            self.observers[perspective] = observer
20            return None
21
22
23class RemoteCache(pb.RemoteCache):
24    """I find out about data added to the Cacheable"""
25    def __init__(self):
26            print("RemoteCache %d initialized"%(id(self),))
27   
28    def setCopyableState(self, state):
29        print("RemoteCache: in setCopyableState my id is %d"%(id(self),))
30   
31    def observe_add(self, obj):
32        msg = "RemoteCache: while responding to observe_add I think my id is"
33        print("%s %d"%(msg, id(self)))
34   
35    def dummy(self):
36        msg = "RemoteCache.dummy: id="
37        print("%s%d"%(msg, id(self)))
38
39
40pb.setUnjellyableForClass(Cacheable, RemoteCache)
41
42
43class Server(object):
44    implements(portal.IRealm)
45       
46    def __init__(self):
47        self.thing = Cacheable()
48        self.users = set()
49   
50    def requestAvatar(self, avatarID, mind, *interfaces):
51        assert pb.IPerspective in interfaces
52        p = Perspective(avatarID, mind, self)
53        self.users.add(p)
54        return pb.IPerspective, p, lambda a=p:a.detached()
55   
56    def start(self):
57        for p in self.users:
58            p.mind.callRemote("take", self.thing)
59   
60    def update(self):
61        self.thing.add("foobar")
62
63
64class Perspective(pb.Avatar):
65    def __init__(self, name, mind, server):
66        self.name = name
67        self.mind = mind
68        self.server = server
69   
70    def detached(self):
71        self.mind = None
72   
73    def perspective_start(self):
74        self.server.start()
75   
76    def perspective_update(self):
77        self.server.update()
78
79
80class Client(pb.Referenceable):
81   
82    def __init__(self, reactor):
83            self.reactor = reactor
84   
85    def connect(self):
86        factory = pb.PBClientFactory()
87        reactor.connectTCP("localhost", 8800, factory)
88        def1 = factory.login(credentials.UsernamePassword("alice", "1234"),
89                             client=self)
90        def1.addCallback(self.connected)
91   
92    def connected(self, perspective):
93        self.perspective = perspective
94        self.reactor.callLater(1.0, self.start)
95   
96    def start(self):
97        self.perspective.callRemote("start")
98   
99    def update(self):
100        self.perspective.callRemote("update")
101        self.reactor.callLater(1, self.showId)
102   
103    def remote_take(self, d):
104        self.d = d
105        print("Client received RemoteCache: id=%d"%(id(d),))
106        self.reactor.callLater(2.0, self.update)
107   
108    def showId(self):
109        print("Client: The RemoteCache's id is %d"%id(self.d))
110        self.reactor.callLater(1, self.d.dummy)