~certify-web-dev/twisted/certify-trunk

« back to all changes in this revision

Viewing changes to twisted/spread/publish.py

  • Committer: Bazaar Package Importer
  • Author(s): Moshe Zadka
  • Date: 2002-03-08 07:14:16 UTC
  • Revision ID: james.westby@ubuntu.com-20020308071416-oxvuw76tpcpi5v1q
Tags: upstream-0.15.5
ImportĀ upstreamĀ versionĀ 0.15.5

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
 
 
2
# Twisted imports
 
3
from twisted.python import defer
 
4
 
 
5
# sibling imports
 
6
import jelly
 
7
import banana
 
8
import flavors
 
9
 
 
10
# System Imports
 
11
import time
 
12
import copy
 
13
 
 
14
class Publishable(flavors.Cacheable):
 
15
    """An object whose cached state persists across sessions.
 
16
    """
 
17
    def __init__(self, publishedID):
 
18
        self.republish()
 
19
        self.publishedID = publishedID
 
20
 
 
21
    def republish(self):
 
22
        """Set the timestamp to current and (TODO) update all observers.
 
23
        """
 
24
        self.timestamp = time.time()
 
25
 
 
26
    def view_getStateToPublish(self, perspective):
 
27
        '(internal)'
 
28
        return self.getStateToPublishFor(perspective)
 
29
    
 
30
    def getStateToPublishFor(self, perspective):
 
31
        """Implement me to special-case your state for a perspective.
 
32
        """
 
33
        return self.getStateToPublish()
 
34
 
 
35
    def getStateToPublish(self):
 
36
        """Implement me to return state to copy as part of the publish phase.
 
37
        """
 
38
        raise NotImplementedError("%s.getStateToPublishFor" % self.__class__)
 
39
 
 
40
    def getStateToCacheAndObserveFor(self, perspective, observer):
 
41
        """Get all necessary metadata to keep a clientside cache.
 
42
        """
 
43
        if perspective:
 
44
            pname = perspective.perspectiveName
 
45
            sname = perspective.getService().serviceName
 
46
        else:
 
47
            pname = "None"
 
48
            sname = "None"
 
49
 
 
50
        return {"remote": flavors.ViewPoint(perspective, self),
 
51
                "publishedID": self.publishedID,
 
52
                "perspective": pname,
 
53
                "service": sname,
 
54
                "timestamp": self.timestamp}
 
55
 
 
56
class RemotePublished(flavors.RemoteCache):
 
57
    """The local representation of remote Publishable object.
 
58
    """
 
59
    isActivated = 0
 
60
    _wasCleanWhenLoaded = 0
 
61
    def getFileName(self, ext='pub'):
 
62
        return ("%s-%s-%s.%s" %
 
63
                (self.service, self.perspective, str(self.publishedID), ext))
 
64
    
 
65
    def setCopyableState(self, state):
 
66
        self.__dict__.update(state)
 
67
        self._activationListeners = []
 
68
        try:
 
69
            data = open(self.getFileName()).read()
 
70
        except IOError:
 
71
            print "** Didn't find the file."
 
72
            recent = 0
 
73
        else:
 
74
            newself = jelly.unjelly(banana.decode(data))
 
75
            print '** Found the file.'
 
76
            recent = (newself.timestamp == self.timestamp)
 
77
            print '** ', newself.timestamp, self.timestamp, recent
 
78
        if recent:
 
79
            self._cbGotUpdate(newself.__dict__)
 
80
            self._wasCleanWhenLoaded = 1
 
81
        else:
 
82
            self.remote.callRemote('getStateToPublish').addCallbacks(self._cbGotUpdate)
 
83
 
 
84
    def __getstate__(self):
 
85
        other = copy.copy(self.__dict__)
 
86
        # Remove PB-specific attributes
 
87
        del other['broker']
 
88
        del other['luid']
 
89
        # remove my own runtime-tracking stuff
 
90
        del other['_activationListeners']
 
91
        del other['isActivated']
 
92
        return other
 
93
 
 
94
    def _cbGotUpdate(self, newState):
 
95
        self.__dict__.update(newState)
 
96
        self.isActivated = 1
 
97
        # send out notifications
 
98
        for listener in self._activationListeners:
 
99
            listener(self)
 
100
        self._activationListeners = []
 
101
        self.activated()
 
102
        open(self.getFileName(), "wb").write(banana.encode(jelly.jelly(self)))
 
103
 
 
104
    def activated(self):
 
105
        """Implement this method if you want to be notified when your
 
106
        publishable subclass is activated.
 
107
        """
 
108
        
 
109
    def callWhenActivated(self, callback):
 
110
        """Externally register for notification when this publishable has received all relevant data.
 
111
        """
 
112
        if self.isActivated:
 
113
            callback(self)
 
114
        else:
 
115
            self._activationListeners.append(callback)
 
116
 
 
117
def whenReady(d):
 
118
    """
 
119
    Wrap a deferred returned from a pb method in another deferred that
 
120
    expects a RemotePublished as a result.  This will allow you to wait until
 
121
    the result is really available.
 
122
 
 
123
    Idiomatic usage would look like:
 
124
 
 
125
        publish.whenReady(serverObject.getMeAPublishable()).addCallback(lookAtThePublishable)
 
126
    """
 
127
    d2 = defer.Deferred()
 
128
    d.addCallbacks(_pubReady, d2.armAndErrback,
 
129
                   callbackArgs=(d2,))
 
130
    return d2
 
131
 
 
132
def _pubReady(result, d2):
 
133
    '(internal)'
 
134
    result.callWhenActivated(d2.armAndCallback)