Ice笔记---Ice Run Time详述(二)
Servant定位器
之前介绍了ASM表(servant活动映射表)的作用。不过他也会有一些限制,因为如果是使用适配器的ASM来把Ice对象映射到servents,那么会有一些影响:(1)每个Ice对象都有一个不同的servant代表。(2)所有Ice对象的所有servants都永久性的出在内存中。如果有大量的上servant对象的话,那么服务器将会承受大的压力,或许是内存不够,或许是初始化所有servants的时间很长。
1. locator综述
Servant定位器是一种本地对象,我们负责实现它,并把它息道对象适配器上。适配器一旦有了servant定位器,它可以和平常一样查询ASM,对servant进行定位。如果ASM上能找到相对应的servant,请求就会分派给这个servant。如果找不到的话,对象适配器就会回调servant定位器,它为该请求提供servant。Servant定位器会做一下事情中的一件:
--初始化一个servant,把它传给Ice run time,这种情况下,请求会被分派到这个新实例化的servant。
--servant定位器告诉Ice run time,他没有找到相应的servant。这种情况下,客户会受到ObjectNotExistException的异常。
采用这种简单的机制,我们的服务器能让我们访问数量不限的Ice对象:服务器不必为每一个现有的Ice对象实例化一个单独的servant。提供数据库访问的服务器常常使用servant定位器:数据库中的条目数通常远远大于服务器在内存中能够存储的条目数。用于进程控制或网络管理的服务器也常常会使用servant定位器。
2. Servant定位器接口
module Ice {
local interface ServantLocator {
Object locate( Current curr,out LocalObject cookie);
void finished( Current curr,Object servant,LocalObject cookie);
void deactivate();
};
};
ServantLocator是一个本地接口。为了创建实际的servant定位器实现,我们必须定义一个从Ice::ServantLocator派生的类,并实现locate,finised以及deactivate操作。
locate:只要有请求到达,而且他在ASM中没有对应的条目,Ice run time就会调用locate。
finished:一旦请求完成,Ice run time就会调用finished,把完成了操作的servant、该请求的Current对象以及locate在一开始创建的cookie传给它。这意味着,每一个locate都会有一个对应的finished。
Deactivate:当servant定位器所属的对象适配器接解除**时,Ice run time会调用deactivate操作。
3. 针对Servant定位器的线程保证
在必要时,我们必须使用互斥原语,在locate和finished中对共享数据进行保护。
4. Servant定位器的注册
对象适配器不会自动的了解到一个servant定位器,我们要显式地向对象适配器注册servant定位器。
module Ice {
local interface ObjectAdapter {
// ...
void addServantLocator(ServantLocator locator,
string category);
ServantLocator findServantLocator(string category);
// ...
};
};
由上可以看出对象适配器允许我们增加和查找servant定位器。以下是servant定位器的简单功能流程示意图:
5. 使用cookies
有时,我们需要在locate与finished之间传递信息。例如,locate的实现可以根据负载或可用性,从多种数据库后端选取一种;同时,为了适当执行结束工作,finished的实现可能需要知道locate使用的是哪一种数据库;在操作调用完成之后,Ice run time会把这个cookie的值传给finished。
Cookie必须从Ice::LocalObject派生,可以容纳任何对我们的实现有用的状态和成员函数。