您的示例設置的方式,很難看到您如何確實存在您描述的問題。如果第二個請求在第一個發出的LoadSharedMemory
調用返回之前進入Twisted服務器,那麼第二個請求將在等待處理之前等待。當它最終被處理時,SomeSharedMemory
將被初始化並且不會有重複。
不過,我想也許它的情況是LoadSharedMemory
是異步的,並返回一個Deferred
,讓你的代碼真的看起來更像是這樣的:
def handleRequest(request):
if SomeSharedMemory is None:
d = initSharedMemory()
d.addCallback(lambda ignored: handleRequest(request))
else:
d = PickSomething(SomeSharedMemory)
return d
在這種情況下,完全有可能是第二個請求可能會抵達,而initSharedMemory
是關閉它的事情。那麼你最終會有兩個任務嘗試初始化該狀態。
當然,要做的事情是注意到你擁有的第三種狀態。不僅有un-初始化和初始化 - ed,而且初始化 - ing。所以也代表這個狀態。我會隱藏它的initSharedMemory
函數內部保持請求處理程序簡單,因爲它已經是:
initInProgress = None
def initSharedMemory():
global initInProgress
if initInProgress is None:
initInProgress = _reallyInit()
def initialized(result):
global initInProgress, SomeSharedMemory
initInProgress = None
SomeSharedMemory = result
initInProgress.addCallback(initialized)
d = Deferred()
initInProgress.chainDeferred(d)
return d
這是一個有點毛,因爲全局的無處不在。這裏有一個稍微乾淨的版本:
from twisted.internet.defer import Deferred, succeed
class SharedResource(object):
def __init__(self, initializer):
self._initializer = initializer
self._value = None
self._state = "UNINITIALIZED"
self._waiting = []
def get(self):
if self._state == "INITIALIZED":
# Return the already computed value
return succeed(self._value)
# Create a Deferred for the caller to wait on
d = Deferred()
self._waiting.append(d)
if self._state == "UNINITIALIZED":
# Once, run the setup
self._initializer().addCallback(self._initialized)
self._state = "INITIALIZING"
# Initialized or initializing state here
return d
def _initialized(self, value):
# Save the value, transition to the new state, and tell
# all the previous callers of get what the result is.
self._value = value
self._state = "INITIALIZED"
waiting, self._waiting = self._waiting, None
for d in waiting:
d.callback(value)
SomeSharedMemory = SharedResource(initializeSharedMemory)
def handleRequest(request):
return SomeSharedMemory.get().addCallback(PickSomething)
三種狀態,它們之間很好的明確的過渡,沒有全局狀態更新(至少如果你給SomeSharedMemory一些非全局範圍內),並handleRequest
不知道任何的這只是要求一個價值,然後使用它。
當你說'SomeSharedMemory'時,你實際上並不是指任何形式的[Shared Memory](http://en.wikipedia.org/wiki/Shared_memory),是嗎? – MattH