首页 新闻 赞助 找找看

感觉开源的Enyim.Caching.Memcached的实现是有问题的... 大家进来分析一下..

0
悬赏园豆:5 [已关闭问题]

 


public PooledSocket Acquire()
{
if (log.IsDebugEnabled)
log.Debug("Acquiring stream from pool.");

if (!this.IsAlive)
{
if (log.IsDebugEnabled)
log.Debug("Pool is dead, returning null.");

return null;
}

// every release signals the event, so even if the pool becomes full in the meantime
// the WaitOne will succeed, and more items will be in the pool than allowed,
// so reset the event when an item is inserted
this.itemReleasedEvent.Reset();--------------这边reset有意义吗?有兄弟知道吗?

PooledSocket retval = null;

// do we have free items?
if (this.freeItems.Dequeue(out retval))
{
try
{
retval.Reset();

if (log.IsDebugEnabled)
log.Debug("Socket was reset. " + retval.InstanceId);

Interlocked.Increment(ref this.workingCount);

return retval;
}
catch (Exception e)
{
log.Error("Failed to reset an acquired socket.", e);

this.MarkAsDead();

return null;
}
}
else
{
// free item pool is empty
if (log.IsDebugEnabled)
log.Debug("Could not get a socket from the pool.");

// we are not allowed to create more, so wait for an item to be released back into the pool
if (this.workingCount >= this.maxItems)
{
if (log.IsDebugEnabled)
log.Debug("Pool is full, wait for a release.");

// wait on the event
if (!itemReleasedEvent.WaitOne(this.connectionTimeout,true))
{
if (log.IsDebugEnabled)
log.Debug("Pool is still full, timeouting.");

// everyone is working
throw new TimeoutException();
}----------------------当获取信号量的时候...代码会接着往下走,也就是说,并不是从已有的队列中去取一个socket出来..而又去createsocket一个出来...不知道是写的太烂,还是我没理解清楚?
}

if (log.IsDebugEnabled)
log.Debug("Creating a new item.");

try
{
// okay, create the new item
retval = this.CreateSocket();

Interlocked.Increment(ref this.workingCount);
}
catch (Exception e)
{
log.Error("Failed to create socket.", e);
this.MarkAsDead();

return null;
}
}

if (log.IsDebugEnabled)
log.Debug("Done.");

return retval;
}

ITAres的主页 ITAres | 初学一级 | 园豆:107
提问于:2008-11-12 10:33
< >
分享
其他回答(1)
0

没有看出来问题在哪里,你认为是哪里有问题呢?

丁学 | 园豆:18730 (专家六级) | 2008-11-12 12:25
0

你的代码写了那么多调试用的语句,看着有些乱,整个代码好像是从socket池里取一个socket。

1、先看socket池是不是处于活动状态,如果socket池已经死了就返回null

2、this.itemReleasedEvent.Reset();看样子是重置一个socket释放的信号量,后面会wait它,你可以找一下什么地方set的,应该是一个不用的socket释放的时候set,这样后面发现池已满的时候可以等待一段时间,等有别的socket释放。

3、然后就从空闲的socket里取出一个返回。

4、如果取不出来说明空闲socket队列是空的,那么判断已有的socket有没有达到池的上线,如没有达到就创建一个新的socket返回。

5、如果已有的socket已经达到池的上线,就等待itemReleasedEvent信号量一定的时间,如果在这段时间内有不用的Socket释放,就还创建一个新的,否则就抛出超时的错误。

整个逻辑你简化代码后就看的清楚了

        public PooledSocket Acquire()
        {
            if (!this.IsAlive)
            {
                return null;
            }
            this.itemReleasedEvent.Reset();
            PooledSocket retval = null;
            if (this.freeItems.Dequeue(out retval))
            {
                try
                {
                    retval.Reset();
                    Interlocked.Increment(ref this.workingCount);
                    return retval;
                }
                catch (Exception e)
                {
                    this.MarkAsDead();
                    return null;
                }
            }
            else
            {
                if (this.workingCount >= this.maxItems)
                {
                    if (!itemReleasedEvent.WaitOne(this.connectionTimeout,true))
                    {
                        throw new TimeoutException();
                    }
                }
                try
                {
                    retval = this.CreateSocket();
                    Interlocked.Increment(ref this.workingCount);
                }
                catch (Exception e)
                {
                    return null;
                }
            }
            return retval;
}


你可能感觉等到有空闲的socket释放了,为什么还创建一个新的socket,那么它的池不就没用了吗,其实一个已经释放的socket是没法直接的重用,因为一个socket有local endpoint和remote endpoint,要把一个已经连接到a主机的socket又要连到b主机得用反射清空一些东西才行,具体我也不太清楚,你可以查下资料,一般做socket server的时候才会考虑socket池,你可以查下winsock的acceptex函数,他可以让一个socket重用,我以前的帖子贴过用法。其实它这个池在空闲socket池没空的时候还是有作用的,对吧。

蛙蛙王子 | 园豆:265 (菜鸟二级) | 2008-11-12 13:34
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册