扭曲:缓存实例列表

时间:2018-07-25 19:29:08

标签: python python-3.x twisted

我目前正在阅读各种扭曲的《开发人员指南》,并希望获得有关扩展提供示例之一的用例(即缓存对象实例)的一些信息/指南:

示例代码为:

cache.classes.py

from twisted.spread import pb

class MasterDuckPond(pb.Cacheable):
    def __init__(self, ducks):
        self.observers = []
        self.ducks = ducks

    def count(self):
        print "I have [%d] ducks" % len(self.ducks)

    def addDuck(self, duck):
        self.ducks.append(duck)
        for o in self.observers: o.callRemote('addDuck', duck)

    def removeDuck(self, duck):
        self.ducks.remove(duck)
        for o in self.observers: o.callRemote('removeDuck', duck)

    def getStateToCacheAndObserveFor(self, perspective, observer):
        self.observers.append(observer)
# you should ignore pb.Cacheable-specific state, like self.observers
        return self.ducks # in this case, just a list of ducks

    def stoppedObserving(self, perspective, observer):
        self.observers.remove(observer)

class SlaveDuckPond(pb.RemoteCache):
    # This is a cache of a remote MasterDuckPond

    def count(self):
        return len(self.cacheducks)

    def getDucks(self):
        return self.cacheducks

    def setCopyableState(self, state):
        print " cache - sitting, er, setting ducks"
        self.cacheducks = state

    def observe_addDuck(self, newDuck):
        print " cache - addDuck"
        self.cacheducks.append(newDuck)

    def observe_removeDuck(self, deadDuck):
        print " cache - removeDuck"
        self.cacheducks.remove(deadDuck)
pb.setUnjellyableForClass(MasterDuckPond, SlaveDuckPond)

cache_sender.py

#!/usr/bin/env python
# Copyright (c) Twisted Matrix Laboratories.
# See LICENSE for details.

from twisted.spread import pb, jelly
from twisted.python import log
from twisted.internet import reactor
from cache_classes import MasterDuckPond

class Sender:
    def __init__(self, pond):
        self.pond = pond

    def phase1(self, remote):
        self.remote = remote
        d = remote.callRemote("takePond", self.pond)
        d.addCallback(self.phase2).addErrback(log.err)

    def phase2(self, response):
        self.pond.addDuck("ugly duckling")
        self.pond.count()
        reactor.callLater(1, self.phase3)

    def phase3(self):
        d = self.remote.callRemote("checkDucks")
        d.addCallback(self.phase4).addErrback(log.err)

    def phase4(self, dummy):
        self.pond.removeDuck("one duck")
        self.pond.count()
        self.remote.callRemote("checkDucks")
        d = self.remote.callRemote("ignorePond")
        d.addCallback(self.phase5)

    def phase5(self, dummy):
        d = self.remote.callRemote("shutdown")
        d.addCallback(self.phase6)

    def phase6(self, dummy):
        reactor.stop()

    def main():
        master = MasterDuckPond(["one duck", "two duck"])
        master.count()
        sender = Sender(master)
        factory = pb.PBClientFactory()
        reactor.connectTCP("localhost", 8800, factory)
        deferred = factory.getRootObject()
        deferred.addCallback(sender.phase1)
        reactor.run()

if __name__ == '__main__':
main()

cache_receiver.py:

#!/usr/bin/env python
# Copyright (c) Twisted Matrix Laboratories.
# See LICENSE for details.

from twisted.application import service, internet
from twisted.internet import reactor
from twisted.spread import pb
import cache_classes

class Receiver(pb.Root):
    def remote_takePond(self, pond):
        self.pond = pond
        print "got pond:", pond # a DuckPondCache
        self.remote_checkDucks()

    def remote_checkDucks(self):
        print "[%d] ducks: " % self.pond.count(), self.pond.getDucks()

    def remote_ignorePond(self):
        # stop watching the pond
        print "dropping pond"
        # gc causes __del__ causes 'decache' msg causes stoppedObserving
        self.pond = None

    def remote_shutdown(self):
        reactor.stop()
application = service.Application("copy_receiver")
internet.TCPServer(8800, pb.PBServerFactory(Receiver())).setServiceParent(
service.IServiceCollection(application))

此示例看起来非常简单,MasterDuckPond由发送方控制,而SlaveDuckPond是一个缓存,用于跟踪对主服务器的更改。

但是,我将如何更新/缓存整个实例对象列表?

1 个答案:

答案 0 :(得分:0)

请勿使用PB。在至少99%的用例中,该协议过于复杂(这意味着您将不得不比理解,实施和维护您的项目付出更多的努力)。它没有其他实现,而且可能永远也不会实现(这意味着您被Python和Twisted所困-并不是说这些事情很糟糕,但是还有很多其他事情可能也很好) )。维护级别是最低的(因此,如果您发现错误,则很少有人会帮助您修复它们,但这仅是您可以期望的-如果错误不是很琐碎的话,您甚至可能无法得到它)。

尝试使用HTTP。它可以做很多事情。如果将其与Capn,CBOR甚至JSON等数据格式结合使用,它甚至可以做更多的事情。