Django,Borg模式,API调用,缓存结果

时间:2010-07-28 20:21:39

标签: python django api caching

我正在使用来自其他网站的API,该网站会返回我的用户用来购买虚拟商品的几个“价格点网址”。

我应该将这些结果缓存至少一个小时,因为它们不会更改系统上的价格点。 (我们希望保存我们的带宽和带宽。)

在Python中查找单例后,我发现了borg模式,看起来更酷,所以这就是我所做的:

def fetchPrices():
    #uses urllib2.urlopen() to fetch prices
    #parses results with ElementTree
    return prices

class PriceStore():
    __shared_state = {}

    def update(self):
        if self.lastUpdate is not None and (datetime.now() - self.lastUpdate).seconds >= 3600:
            self.prices = fetchPrices()
            self.lastUpdate = datetime.now()
        elif self.lastUpdate is not None:
            return
        else:
            self.lastUpdate = datetime.now() - timedelta(hours=1)
            self.update()

    def __init__(self):
        self.__dict__ = self.__shared_state
        self.lastUpdate = None
        self.update()

我们的想法是以下列方式使用它:

store = PriceStore()
url = store.prices['2.9900']['url']

如果现有信息超过一小时,商店应该正确初始化并且只获取新的价格信息。

每次PriceStore初始化时,我似乎都在点击他们的API。谁能发现我的问题?我可以在django中使用像__shared_state这样的全局变量,并期望它仍然包含定价信息吗?

谢谢!

3 个答案:

答案 0 :(得分:4)

  

我好像正在使用他们的API   每次PriceStore都是   尽管如此。谁能发现   我的问题?

是的,很容易发现:

def __init__(self):
    self.__dict__ = self.__shared_state
    self.lastUpdate = None

self.lastUpdate = None 绝对保证以后对self.update()的调用会发现self.lastUpdate的值为None - 您只是强迫它如此!

删除self.lastUpdate = None中的__init__,例如,使用

lastUpdate = None

class body 级别,例如在__shared_state = {}赋值之后,与该赋值具有相同的对齐方式。 会让事情按照你的意愿运作。

答案 1 :(得分:1)

您的主要问题是,当您创建新的PriceStore时,您将self.lastUpdate设置为None(在倒数第二行)。因此,虽然它们都共享国家,但每个新对象都会破坏国家。

而是这样做:

class PriceStore():
    __shared_state = {'lastUpdate': None}

您可能面临的另一个问题是,根据您的Django的部署方式,您可能正在使用多个进程。每个人都有自己的共享状态副本。

答案 2 :(得分:0)

__init__中设置self.lastUpdate = None。不要那样做。

具体来说,请考虑以下代码:

A = PriceStore()

# some time later

B = PriceStore()

现在A.lastUpdate ==无,你不想要的!相反,尝试

if "lastUpdate" not in self.__dict__:
    self.lastUpdate = None

这样你永远不会覆盖它。