资源预览内容
第1页 / 共49页
第2页 / 共49页
第3页 / 共49页
第4页 / 共49页
第5页 / 共49页
第6页 / 共49页
第7页 / 共49页
第8页 / 共49页
第9页 / 共49页
第10页 / 共49页
亲,该文档总共49页,到这儿已超出免费预览范围,如果喜欢就下载吧!
资源描述
可移植对象适配器Stillwatersrundeep.流静水深流静水深,人静心深人静心深Wherethereislife,thereishope。有生命必有希望。有生命必有希望11.3.1 基本的请求调度n基本调度如下: (1) 首先,服务器应用程序以某种方式为CORBA对象到处一个对象引用。客户机可能通过命名服务或者交易服务或者从另一个请求接收它来获得到处对象引用。对象引用从逻辑上“指向”目标CORBA对象,像C+指针指向它底层的C+对象一样。 (2) 其次,在应用程序的控制下,客户程序ORB使用对象引用来决定对象驻留在何处和如何访问它,然后它向服务器ORB发送请求。 (3) 再次,服务器ORB接收请求并将其调度给拥有该目标对象的POA。 (4) 最后,POA通过调用具体化该目标对象的伺服程序来继续执行该调度。11.3.2 关键的POA实体n有三种关键实体涉及到POA 对象引用 POA负责创建对象引用。 对象标识符 在POA主机的作用域内,每一个对象通过调用一个octet序列的对象标识符进行识别。当POA创建一个新的CORBA对象时,典型情况是,它就将对象标识符嵌入在对象引用的对象密钥部分。 伺服程序 引用程序直接通过POA可以创建并注册伺服程序来具体化对象。同样,应用程序可以向POA提供伺服程序管理器对象,当需要执行一个请求时,POA就能创建伺服程序。应用程序甚至可以提供一个默认的伺服程序。与POA策略有关,在任何给定的时间,单个的伺服程序可以用POA注册来具体化一个和多个的CORBA对象。 POA通过目标对象的对象标识符与合适的伺服程序之间的映射来调度请求。一个伺服程序也可以通过对一个伺服程序的_this调用隐式创建一个新的CORBA对象,并为其注册一个伺服程序。11.4 POA策略nPOA规范的关键特性就是一个应用程序可以包含多个POA实例。每一个POA实例代表具有相似性能的一组对象。这些性能通过POA创建时所指定的POA策略来控制。所有应用程序至少有一个POA,也就是Root POA,它具有标准的策略集。n策略是用来定义POA性能的对象,该对象在策略内部创建。向POA和POAManager接口一样,CORBA规范指出,在标准的PortableServer模块中定义POA策略接口。n像所有的策略接口一样,POA策略类从CORBA:Policy接口派生出来。nPolicy接口及相关的类型提供的管理操作 (1) 通过基本的Policy接口,利用policy_type只读属性可以确定策略的实际派生类型。 PolicyType是由OMG控制的一个标志值,这样可以确保所有的标准接口都有一个唯一的标志 (2) copy操作可以克隆(clone) 一个Policy对象。返回的引用指向目标Policy对象的一个全新的拷贝。POA策略(3) destory操作用来撤消目标Policy对象。(4) PoicyList用来将指向各种派生Policy对象的引用分组来形成策略集。POA创建操作接收一个PolicyList类型的参数,这个参数可以将策略设置成新的POA。n策略对象是局部约束对象。也就是任何试图将它们的引用作为参数传递给标准的CORBA操作或通过ORB:object_to_string将它们转换成字符串的操作都将产生CORBA:MARCHAL异常。11.4.1 CORBA对象生存期范围n假如一个客户程序向一个当前没有运行或没有激活的目标对象发出一个请求,如果必要的话,ORB工具就会为该对象激活一个服务器进程,然后激活对象本身。服务器进程和目标对象的任何激活对发出请求的客户来说都是透明的。n持久对象:生存期超过创建或激活它们的某一特定进程的CORBA对象。n除了持久对象外,其它的对象的生命周期由进程的生命周期甚至于创建它们的对象适配器来决定。11.4.2 对象标识符nPOA通过它的对象标识符识别每一个对象。对象标识符被赋值为ObjectId类型,这个类型在PortableServer模块中定义为octet的一个序列。n一个程序可以显示的提供自己的对象标识符,也可以让POA为它创建对象标识符。n对象标识符和对象引用的主要区别是在命名一个对象的POA作用域外,对象标识符是无意义的。n在单个POA的作用域内,所有对象标识符必须是唯一的。n如果使用具有SYSTEM_ID策略值的POA,POA就会自动生成唯一的ID。如果使用具有USER_ID策略值的POA,POA就会通过产生异常来防止两个相同的ID。n对象标识符由IdAssignmentPolicy来控制11.4.3 对象到伺服程序之间的映射n一个只有少量几个暂态对象的应用程序在开始监听请求前,可能会为每个对象创建各自的伺服程序并使用POA注册它们。拥有多个持久CORBA对象的应用程序可能只需要一个伺服程序来具体化所有的这些对象。n对象标识符映射到用UNIQUE_ID策略值创建的POA中的下伺服程序。 当调用一个请求时,POA先提取出ObjectId,通常ObjectId嵌入在目标对象的对象引用中,然后使用该ObjectId在激活的对象映射中查找目标对象的伺服程序。在激活的对象映射中的每一个条目由一个ObjectId和一个指向一个伺服程序的指针的关联组成。保留ObjectId对伺服程序关联的每一个POA都有它自己的激活的对象映射。对于UNIQUE_ID,POA实现的规则是每一个对象标识符映射到一个不同的伺服程序。而在一个MULTIPLE_ID中,多个对象标识符可以映射到一个伺服程序。 对于Root POA,标准的对象标识符的唯一策略值是 UNIQUE_ID。Root POA要求一个独立的伺服程序来具体化每一个对象。11.4.4 策略工厂操作 n通过调用POA的策略工厂操作可以创建策略。POA接口为每个类型都提供了一个独立的策略工厂操作。n每一个策略工厂操作都一同样的方式工作:向新的策略对象传递所需的值,然后操作返回对象引用。最终,必须调用返回对象中的destroy操作来撤销它。11.5 POA创建n为了让POA策略有效,在创建时就将它们应用于POA。通过调用另一个POA的create_POA可以创建一个POA。因为所有的服务器应用程序都有一个Root POA,所以它的create_POA操作起到了创建其它POA的起始点的作用。n使用另一个POA创建的POA就成了正在创建的POA的子POA。但是,这对子POA的策略没有影响,策略并不继承符父POA。相反,如果没有策略值传递给create_POA操作,则使用默认值。n在IDL定义时需要注意: POAManager允许应用程序控制一个POA中的请求流。 create_POA操作有三个参数。POA的名称、指向为要创建的POA控制请求流的POAManager的一个引用,为空将创建一个新的、创建POA策略列表。 create_POA 操作可能会产生两个异常。同名AdapterAlreadyExists异常。策略未知或不一致InvalidPolicyPOA创建nPOA策略的创建: CORBA:PolicyList policy_list PortableServer:POA_var child_poa=root_poa-create_POA(“child”,PortableServer:POAManager:_nil(), policy_list) (1) 先初始化ORB和从Root POA获得一个引用的一般调用序列 (2) 创建一个CORBA:PolicyList序列,默认为空 (3) 调用Root POA的create_POA,传递字符串“child”作为新的POA的名字,同时传递的参数还有一个空的POAManager引用和空的策略列表。 也可以创建一分层的POA。例如: PortableServer:POA_var poa_A=root_poa-create_POA(“A”,) PortableServer:POA_var poa_B=poa_A-create_POA(“B”,) PortableServer:POA_var poa_C=poa_B-create_POA(“C”,)11.6 Server IDL类型nnative类型 native类型的目的是允许IDL标识符可以被说明为没有IDL定义的一种类型,但是这种类型可由每种语言映射来单独进行定义。 在C+中,Servant类型映射到一个指向ServantBase类的指针。 ServantBase可视为所有框架的基类,也就是所有应用程序伺服类的基类。 ServantBase提供_default_POA函数, _default_POA函数的ServantBase实现返回一个指向Root POA的引用。当调用一个伺服程序的_this函数来隐式创建并激活一个新的暂态CORBA时, _default_POA提供POA引用。11.7 对象创建和激活n11.7.1 对象创建 POA提供两种不用创建伺服程序就可以创建CORBA对象的操作。 create_refernce和create_refernce_with_id都需要一个RepositoryId参数来识别新对象支持的大多数派生的IDL接口。 create_refernce操作要求POA具有一个值为SYSTEM_ID的IdAssignmentPolicy值,以便POA为新的对象生成ObjectId。如果没有,将会引发WrongPolicy异常。使用create_refernce_with_id时,应用程序提供Object_Id。这个Object_Id在应用程序域内表示对象的身份。 Object create_refernce(in CORBA:RepositoryId intf) raises(WrongPolicy); Object create_refernce_with_id(in ObjectId oid, CORBA:RepositoryId intf) raises(WrongPolicy);对象创建和激活n11.7.2 伺服程序注册 激活一个对象的最简单方法之一就是使用POA对象激活操作。使用这些操作,应用程序开发人员显式提供一个伺服程序来具体化将被激活的对象,并且根据POA的IdAssignmentPolicy,POA赋值一个ObjectId或应用程序开发人员提供一个ObjectId。 根据目标POA的策略,选择使用active_object或activate_object_with_id。 active_object操作要求目标POA具有值为SYSTEM_ID的一个IdAssignmentPolicy和值为RETAIN的一个ServerRetentionPolicy值。 activate_object_with_id操作要求目标POA具有RETAIN的一个ServerRetentionPolicy值。 如果POA的IdUniquenessPolicy设置为UNIQUE_ID并且为一个参数传递Servant已经存在于POA的激活对象映射中,它们俩都将引发ServantAlreadyActive异常。对象创建和激活n11.7.3 伺服程序管理器 具有USE_SERVANT_MANAGER策略的POA允许它们创建伺服程序来支持这些类型的应用程序,这些伺服程序参与确定对象对伺服程序关联的过程。 伺服程序管理器有两种类型。 (1) 对于ServantRetention策略值是RETAIN的POA,伺服程序管理器对象必须支持ServantActivator接口。 (2) 对于策略值是NON_RETAIN的POA,伺服程序管理器必须支持ServantLocator接口。 伺服程序激活器(Servant Activators) ServantActivator接口提供incarnate和etherealize操作 incarnate操作用来实现或是创建一个伺服程序的一个合适的实例并返回它,或者产生一个异常。 etherealize函数的功能刚好与incarnate函数相反。它允许应用程序清除它们的伺服程序。 对象创建和激活n伺服程序定位器(Servant Locators) 对于使用USE_SERVANT_MANAGER和NON_ RETAIN策略的POA,伺服程序管理器必须支持ServantLoactor接口。此接口提供了preinvoke和postinvoke操作。 preinvoke函数用来获得一个要调度给请求的伺服程序。在请求返回后,POA调用postinvoke来让ServantLocator执行伺服程序清除或其后调用函数。直到POA涉及之前,由postinvoke返回的伺服程序只用于单个的请求。n伺服程序管理器注册 因为伺服程序本身是CORBA对象,所以需要通过POA用它们的对象引用来注册它们,为伺服程序管理器创建一个对象引用的最容易的方法是隐式在Root POA注册它的伺服程序。 PortableServer:ServantManage_var mgr_ref=manager_impl._this(); poa-set-servant_manager(mgr_ref);对象创建和激活n11.7.4 默认的伺服程序 POA的RequestProcessingPolicy之为USE_DEFAULT_SERVANT时,就表示使用默认的伺服程序。 ProtableServer:Current接口 在一个请求调度的过程中,服务器ORB可以让一个应用程序获得目标对象的ObjectId和正在调度请求的POA的一个引用。这些操作由ProtableServer:Current接口提供。 get_POA函数用来获得一个引用 get_object_id函数用来获得目标对象的ObjectId11.8 引用、ObjectId和伺服程序nservant_to_id操作返回与目标伺服程序关联的ObjectId。nservant_to_reference操作返回伺服程序正在进行具体化的对象的对象引用。nreference_to_servant操作返回指向对象引用所具化的对象的伺服程序。nreference_to_id操作在传递给它的对象引用参数中返回对象IDnid_to_reference操作为由对象ID参数代表的对象返回一个对象引用。nid_to_servant操作返回与确定的对象ID相关联的伺服程序。11.9 对象失效n最终,所有的CORBA对象必须失效。n因为激活一个CORBA对象需要设置一个对象对伺服程序的关联,所以为了使一个对象失效,就需要中断这种对象与伺服程序的关联。通过调用拥有该对象的POA上的deactivate_object就可以达到这个目的。n在调用这个函数时,要将对象的ObjectId作为唯一的参数进行传递。一旦没有对该ObjectId其它的有效请求,最终POA会在它的激活对象映射中删除ObjectId与伺服程序的关联。11.10 请求流控制n资源管理的另一个方面与一个服务器程序可以处理的应用程序的请求率有关。每一个POA具有一个相关的POAManager,从本质上说POAManager起到一个让你控制对POA的请求流的水龙头或阀门的作用。nPOAManager接口提供的四周操作与POAManager对象的四种状态相对应。 (1) 可以调用activate操作来让目标POAManager转换到active状态并且让请求流通向POA或它所控制的POA。(2) 可以调用hold_reauests操作来将目标POAManager的状态改变到holding状态。在这种状态下, POAManager将所有向POA或向它控制下的POA所做的请求进行排队。(3) 可以调用discard_request操作来将目标POAManager的状态改变为discarding状态,在这种状态下, POAManager将每个进入的请求丢弃,不排队并且不将它传送给目标POA;相反,他会将CORBA:TRANSIENT异常返回给客户。(4) 可以调用deactivate操作将目标POAManager的状态改为inactive状态。在这种状态下的POAManager不再处理请求并且不能被重新激活。11.11 ORB事件处理n任何一个作为服务器程序的CORBA应用程序必须接收并处理事件,比如来自客户要求的连接和它们的后继的请求。就事件处理而论,服务器引用程序可以分为两类。 (1) 在一些应用程序中,只有ORB需要接收并处理这样的事件。这些应用程序可以仅将控制主线程交给ORB,这样它就可以处理请求并调度它们给对象适配器和伺服程序。这样的应用程序可以说是执行blocking事件处理,因为应用程序main将被阻阻塞,直到ORB关闭它的事件处理并将控制返回给main。 (2) 在另一些应用程序中,ORB只是必须执行事件处理的几种组件中的一个。比如,一个具有图形用户接口(GUI)的CORBA应用程序除了让ORB处理输入的请求外,还必须让GUI处理窗口事件。所以这些类型的应用程序执行non_blocking事件处理。它们将控制主线程交给各种事件处理子系统的每一个,而不允许它们中的任何一个阻塞有效的事件周期。 就像POAManager对象允许你控制POA的请求流一样,ORB提供各种操作允许你控制整个应用程序的请求流和事件处理,也包含所有的对象适配器。ORB事件处理n11.11.1 阻塞事件处理 ORB:run操作将阻塞,直到ORB停止运行。从执行你的应用程序main的线程中调用run,可以让ORB接管主线程来执行它的工作。ORB保持对主线程的控制,并且在调用ORB:shutdown和ORB完全停止运行后才返回。从任何其它线程中调用run,只能等到ORB停止后,才可以阻塞那个线程。n11.11.2 非阻塞事件处理 当ORB接管主线程时,ORB:run操作可以让应用程序运行。但是对于其它事件循环共享主线程的应用程序,将主线长的控制交给ORB是不可接收的。n11.11.3 应用程序停止运行 当你想关闭应用程序时,调用ORB:shutdown。他只含有唯一的boolean参数,这个参数告诉应用程序阻塞是否要等待所有关闭的活动结束才进行或者在所有关闭的工作完成前它就返回。ORB事件处理n服务器应用程序通常有三种方式关闭 (1) 应用程序可以使用一种超时的方法。 (2) 用户可以通过向正在运行的应用程序发送一个信号来强制执行关闭。 (3) 另一种方法可能是调用由应用程序CORBA对象提供的一些shutdown操作。11.12 POA激活n像伺服程序一样,POA可以按要求创建,这种方法用于很少调用POA的对象的应用程序。当接到一个向还没有创建的子代POA真的对象所做的请求时或应用程序使用一个已经命名但还没有创建的POA的POA:find_POA操作来搜索POA的层次结构时,POA就会激活应用程序必须通过激活它的子代POA的每个POA来注册一个AdapterActivator。n适配器激活器是一个普通的CORBA对象,所以它们可以通过伺服程序来具体化。一个适配器激活将的C+伺服程序从POA_PortableServer:AdapterActivator框架中派生出来。在此伺服类中唯一的有意义的成员函数是unknown_adapter函数。他包含一个指向将被激活的POA的父POA的引用以及新的POA名字。11.13 POA析构n最终,POA必须被撤消,通常是由于ORB的关闭和服务器应用程序进程的结束。但是在应用程序关闭时并没有撤消。例如,一个打算保持运行的应用程序可能追踪一个给定POA拥有的所有对象,然后在它以前所创建的所有对象都撤消后,撤消该POA。n使用POA:destory操作可以撤消POA。11.14 应用POA策略n在应用程序中的POA数量以及为每个POA选择的策略与几个因素有关。其中的一些因素如下: (1) 你的应用程序打算支持的对象的数量 (2) 请求的期望率和持续时间 (3) 你的对象所需要的潜在的持久存储 (4) 应用程序所运行的计算机和操作系统提供的资源和服务水平 (5) 应用程序必须包括的或者是有相互影响的任何非CORBA软件 (6) 应用程序运行的部分域的一些特征,尤其是将对象重新定位在域中其它服务器上的能力是否理想应用POA策略n11.4.1 多线程问题 应用程序必须做出的基本的选择是它们是单线程还是多线程。这个选择依赖于下面的几个细节:(1) 所使用的操作系统或C+语言运行时是否提供足够的多线程支持(2) 你的ORB实现对线程的要求(3) 调试多线程应用程序所使用的工具(4) 你的创建和维护多线程应用程序的专业知识和经验水平(5) 在你的应用程序中使用的任何第三方库在对线程环境下正确工作的能力。应用POA策略n11.14.2 ObjectId赋值 决定一个POA的值为USER_ID还是SYSTEM_ID的IdAssignmentPolocy的一个简单规则为:为暂态对象使用系统赋值的对象标识符,而对持久对象使用用户赋值的标识符。典型情况是使用值为UESR_ID的IdAssignmentPolocy,同时使用值为PERSISTENT的LifespanPolicy,因为创建对象的ObjectId通常包含一些你在何处存储对象创建状态的指示。如果应用程序使用文件系统路径名或数据库的键值作为持久对象的ObjectIds。对于暂态对象,将POA赋值为ObjectIds是最简单的方法,因为通常你的应用程序并不直接使用生成的标识符。n11.14.3 激活 只能将USER_ID和PERSISTENT一块使用;将IMPLICIT_ACTIVATION和SYSTEM_ID一起使用。 建议: 支持ServantRetentionPolicy值为 RETAIN,IdAssignmentPolicy的值为 SYSTEM_ID,IDUniquenessPolicy的值为NIQUE_ID,LifespanPolicy的值为TRANSIENT的POA使用IMPLICIT_ACTIVATION。这是因为对一个伺服程序使用_this函数来隐式创建并激活暂态对象可非常方便地创建Policy对象,伺服程序管理器,迭代器以及其它暂态对象,对拥有持久对象的POA使用默认的NO_IMPLICITACTIVATION。应用POA策略n11.14.4 时空折衷 POA请求需要时间和空间有两个主要方面: (1) POA定位域目录对象ObjectId相关联的一个伺服程序需要时间和空间资源。这主要包括在激活对象映射中的查找,调用一个伺服程序管理器所需要的时间和确定是否使用一个默认伺服程序所需的时间。 (2) 伺服程序确定对一个给定的请求应具体化哪一个对象需要的时间和空间。n11.14.5 关于生命范围的考虑 面向服务的应用程序通常具有两个特征:(1) 它们由长命的对象组成,这些长命的对象通过管理工具创建和撤消。(2) 它们对象的状态完全存储在持久存储中。应用POA策略n面向会话的应用程序 面向会话的应用程序:客户创建它们打算使用的对象,使用这些对象,然后撤消它们。 与面向服务器的应用程序相比,它拥有的大多数对象是通过对象工厂中的请求创建的。通常这个工厂本身是面向服务的持久对象并且在命名服务和交易服务中公告。客户首先使用这些服务来寻找必须的工厂,然后,它们想改工厂做出请求以创建它们需要的会话对象。它是一个暂态的。n持久对象 即使拥有它们的服务器应用程序当前并不在执行并且必须启动,但支持持久的CORBA对象的一个ORB实现必须能够定位他们并将请求传递给它们。这也就隐式说明拥有持久对象的应用程序不能孤立的操作。相反,这样的服务器撤消必须使用ORB实现仓库进行注册以让ORB来跟踪它们拥有的对象并且当请求调用这些对象时能够激活它们。应用POA策略n暂态对象 与持久对象不同,暂态对象不需要对定位和激活有效的支持。这样持久它们就非常适合于处理短期的或局部的活动。 策略值不是TRANSIENT的POA还有几种有意义的用途,他不同于Root POA。(1)因为Root POA的ThreadPolicy的值为ORB_CTRL_MODEL,所以一个应用程序想让它的暂态对象所做的所有请求顺序调度的话,需要一个具有SINGLE_THREADMODEL值的POA。(2)一个应用程序可以要求一个拥有暂态对象的POA,它的IdAssignmentPolicy值为USE_ID而不是Root POA所具有的SYSTEM_ID。(3) 它可以用于策略值不是UNIQUE_ID和RETAIN的拥有暂态对象的OA。对象生命周期n对象生命周期处理以下的问题(1) 对象的持久(2) 对象的析构(3) 对象的拷贝(4) 对象的移动生命周期服务主要是一系列建议而非实现规范。12.3 对象工厂nOMG生命周期规范建议CORBA应用程序使用工厂模型来创建对象。一个工厂是一个提供一种和多种操作来创建其它对象的CORBA对象。为了创建一个新的对象,客户程序调用工厂中的一个操作;操作的实现创建了一个新的CORBA对象并向客户返回新对象的一个引用。在分布式系统中,工厂操作扮演着C+中构造函数的角色。差别是:工厂操作可以在一个可能的远程地址空间创建一个CORBA对象,而C+构造函数总是在本地地址空间创建一个C+对象。还有,可对一个已经存在的对象调用工厂操作。但只能对一个还没有存在的对象调用构造函数。n工厂的设计选项 (1) 组合式工厂使用单个的工厂来创建两种类型的设备。 (2) 组合的汇集和工厂它是上面的变体,该选择方案是将工厂操作添加到控制接口,而不是使用一个独立的工厂对象。 (3) 纯汇集和工厂工厂负责创建对象,控制器只是一个这些设备的引用的汇集。 (4) 成批工厂定义一个操作,此操作完成成批对象的创建。12.4 撤消、拷贝以及移动对象n撤消一个对象,客户程序可以调用remove操作。客户程序调用此函数后,该设备就永久的消失了。n对象的拷贝可以使用copy函数,copy函数的目的是客户程序可以调用一个对象以获得一个指向新对象的引用,这个新对象在某些方面是原始对象的一个拷贝。n移动一个对象可以使用move操作。Move操作的目的是在物理上将一个对象从一个位置移动到另一个位置而不让指向移动的对象的引用失效。12.5 伺服程序的无用存储单元回收n无用单元回收是由一个程序实现的不再使用的资源的自动删除。(1) 客户程序意外行为的处理remove或destory(2) 通过关机进行无用单元的回收(3) 使用回收模型进行无用单元回收(4)使用超时进行无用单元回收n显式保持激活 通过向每个接口添加一个ping操作,可以让客户机负责保持伺服程序的激活。默认情况下,在一定的空闲周期后,伺服程序将作为无用存储单元回收。n每个对象逆向保持激活 如果从服务器到客户机的ping操作失败,服务器程序就收回相对应的伺服程序。伺服程序的无用存储单元回收n每个客户逆向保持激活n如果ping操作的一个调用失败,服务器程序就只撤消由该客户创建的所有的伺服程序。n检测客户的断连 一些ORB提供了专用的扩展,这样当与一个客户的连接断开时,服务器代码就可以检测到。服务器代码可以将此作为一个触发器使用以撤消该客户撤消创建的伺服程序。n分布式引用计数 用increment和decrement回收来进行引用计数。
网站客服QQ:2055934822
金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号