2011-06-29 73 views
0

這讓我瘋狂。我們試圖構建一個CF memcached包裝器。我們有一個memcached.cfc成分是這樣的:在Coldfusion陣列中丟失物品

<cfset this.m = arraynew(1)> 

<cffunction name="init" access="public" output="false"> 
    <cfif not isdefined("application.memcached") 
    .... 
      <cfscript> 
      setup(); 
       </cfscript> 
     ... 
      <cfset application.memcached = this> 
      </cfif> 
    <cfreturn application.memcached> 
</cffunction> 


<cffunction name="setup" access="private" output="false"> 
    <cftry> 
     <cfset this.m = arraynew(1)> 
     <cfloop from="1" to="#this.poolSize#" index="i"> 
      <cfset this.m[i] = createClient()> 
     </cfloop> 
     <cflog application="no" file="memcached" text="Successfully set up #this.poolSize# new memcache clients"> 
     <cfcatch> 
      <cflog application="no" file="memcached" text="Exception in setup() while setting up the pool: type: #cfcatch.type#, message: #cfcatch.message#, detail: #cfcatch.detail#"> 
     </cfcatch> 
    </cftry> 
</cffunction> 


<cffunction name="createClient" access="private" output="false"> 
    <cfset var AU = createObject("java", "net.spy.memcached.AddrUtil").init()> 
    <cfset var c = createObject("java", "net.spy.memcached.MemcachedClient").init(AU.getAddresses("127.0.0.1:11211"))> 
    <cfreturn c> 
</cffunction> 

<cffunction name="getCache" access="public" returntype="any" output="false"> 
    <cfset idx = ceiling(rand() * 20)> 
    <cfreturn application.memcached.m[idx]> 
</cffunction> 

奇怪的是,30分鐘左右的運行之後,getCache開始出現問題說有在application.memcached沒有項目。 m數組在idx位置。

這怎麼可能發生? CF數組是否使用弱引用或其他?當然,一旦數組填充了20個客戶端,數組應該始終保持滿狀態。

每個新客戶生成一個新的線程,所以一旦我們失去了參考客戶現在有辦法將其關閉,並且線程生活在那裏永遠服用內存。請問,我錯過了什麼?

+0

順便說一句,這是一個很長一段時間我最後實現了一個CFC ..但我認爲你可以調用一個函數。我不知道,雖然:) – duedl0r

+1

你需要varscope的「I」你的設置功能和你的getCache函數中的'idx'。 – duncan

回答

1

也許您的應用範圍被刪除。你應該爲此指定一個適當的超時時間。您也應該記錄這是否OnApplication被調用或不是爲了調試目的。

+0

謝謝!我認爲應用程序的範圍一直存在,直到Coldfusion重新啓動:(我會考慮的! –

+0

哦,好的..所以你應該肯定看看Application.cfc。你可以用它做一些有趣的事情.. – duedl0r

0

答案很可能是一些相當簡單 - 事實上,這個類的任何實例將立即失效的應用範圍陣列使這是一個相當麻煩的類來管理。此外,雖然間諜memcached驅動程序本身表現爲單例,並且數組(java.util.vector)是線程安全的,但此實現沒有任何其他內容 - 不是應用程序範圍,絕對不是cfc實例。

假設您可以消除getCache()函數中的idx越界值(我假設您已經這樣做了,如果沒有,則在函數中拋出try/catch塊並報告異常時的idx拋出),您可以通過在構造函數和getCache()方法周圍使用具有相同名稱的獨佔cflock來實際解決症狀,而無需實際解決原因。這種方式即使你有類的隨機實例化,但當某些東西試圖訪問它時,你永遠無法將該陣列吹出,並且在重新創建時你將無法嘗試訪問它。這不是一個最佳的解決方案在所有,如果遇到高併發,你會發現在響應時間略微升高(相當微不足道的,但取決於你有多少個請求/秒的服務,絕對可以對最大吞吐量的影響。