[英]Django, Borg pattern, API calls, caching results
我正在使用來自其他網站的API,該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
這樣的全局變量,並期望它仍然包含定價信息嗎?
謝謝!
不過,每次PriceStore初始化時,我似乎都在點擊他們的API。 誰能發現我的問題?
是的,很容易發現:
def __init__(self):
self.__dict__ = self.__shared_state
self.lastUpdate = None
self.lastUpdate = None
絕對保證緊接着調用self.update()
會發現self.lastUpdate
的值為None
- 你只是強迫它如此!
刪除__init__
中的self.lastUpdate = None
,例如,使用a
lastUpdate = None
在類體層,例如在__shared_state = {}
賦值之后,並且與該賦值具有相同的對齊。 這將使事情按照你的意願運作。
您的主要問題是,當您創建新的PriceStore時,您將self.lastUpdate設置為None(在倒數第二行)。 因此,雖然它們都共享國家,但每個新對象都會破壞國家。
而是這樣做:
class PriceStore():
__shared_state = {'lastUpdate': None}
您可能面臨的另一個問題是,根據您的Django的部署方式,您可能正在使用多個進程。 每個人都有自己的共享狀態副本。
在__init__
設置self.lastUpdate = None
。 不要那樣做。
具體來說,請考慮以下代碼:
A = PriceStore()
# some time later
B = PriceStore()
現在A.lastUpdate ==無,你不想要的! 相反,試試吧
if "lastUpdate" not in self.__dict__:
self.lastUpdate = None
這樣你永遠不會覆蓋它。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.