丢失Coldfusion数组中的项目

时间:2011-06-29 06:42:10

标签: coldfusion memcached spymemcached

这让我发疯了。我们已经尝试构建CF memcached包装器。我们有一个像这样的memcached.cfc组件:

<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启动失败,表示位置idx的application.memcached.m数组中没有项目。

怎么会发生这种情况? CF阵列是使用弱引用还是其他什么?当阵列填充20个客户端时,阵列应该始终保持满是吗?

每个新客户端都会产生一个新线程,所以一旦我们失去了对客户端的引用,现在就可以关闭它,并且该线程永远存在于内存中。拜托,我错过了什么?

3 个答案:

答案 0 :(得分:1)

也许您的应用范围会被删除。您应该为此指定适当的超时。无论是否调用OnApplication进行调试,您还应记录此信息。

答案 1 :(得分:1)

这个memcached CFC什么时候被使用?每个请求? “i”和“idx”变量缺乏变量范围可能很好与它有关。这里有几篇我写的文章,简单地演示了为什么这是必不可少的。

http://duncan99.wordpress.com/2009/03/12/the-importance-of-var-scoping/

http://duncan99.wordpress.com/2009/03/16/the-importance-of-var-scoping-part-2/

答案 2 :(得分:0)

答案可能相当简单 - 这个类的任何实例化都会立即使应用程序范围内的数组无效,这使得这个类很难管理。此外,虽然间谍memcached驱动程序本身表现为单例,而数组(java.util.vector)是线程安全的,但此实现没有任何其他内容 - 不是应用程序范围,绝对不是cfc实例。

假设您可以在getCache()函数中消除idx的超出范围值(我假设您已经这样做了,如果没有,请在函数中抛出try / catch块并报告抛出异常时的idx) ),您可以通过在构造函数和getCache()方法周围使用具有相同名称的独占cflock来解决症状,而无需实际解决原因。这种方式即使您有类的随机实例化,当某些东西试图访问它时,您将永远无法将阵列吹出,并且在重新创建它时您将无法尝试访问它。这根本不是最佳解决方案,如果您遇到高并发性,您会发现响应时间略有提升(相当可以忽略不计,但根据您服务的请求数/秒数,它肯定会对最大吞吐量产生影响。< / p>