omniORB异常处理(翻译)

红薯 发布于 2009/07/20 12:29
阅读 729
收藏 0

4.7 系统异常处理器

除了CORBA::TRANSIENT的某些情况,所有调用过程中发生的系统异常都默认地被传递给应用程序代 码。一些应用程序或许希望捕获代理对象中的异常以便于应用层逻辑无需处理这些错误。例如,当CORBA::COMM_FAILURE异常被捕获时,应用程 序也许只想重新激发调用直到成功为止,这在服务对象是持久的而且具有幂等操作(idempotent operation)时非常有用。omniORB提供了一些函数来创建异常处理器,当ORB运行库抛出异常时,代理对象就可以自行调用这些代码来进行处 理。应用程序可以为CORBA::TRANSIENT、CORBA::COMM_FAILURE和CORBA::SystemException创建异常 处理器,其中CORBA::SystemException的处理程序用来应对其它两个无法处理的异常。可以为单个代理对象创建异常处理器,也可以为地址 空间中的所有代理对象创建。
omniORB 4.0的一个新特性就是用异常次级代码/次要代码(exception minor code)来反映系统异常时的环境。文件include/omniORB4/minorCode.h里定义了omniORB用到的所有异常次级代码,涵盖 了CORBA标准以及omniORB本身定义的。如果编译器支持命名空间,这些代码存在于omni命名空间中,否则为全局定义。

应用程序可以利用异常次级代码来根据不同情况予以调整,例如:
try {
...
}
catch (CORBA::TRANSIENT& ex) {
  if (ex.minor() == omni::TRANSIENT_ConnectFailed) {
  // retry with a different object reference...
  }
  else {
  // print an error message...
  }
}

4.7.2 CORBA::TRANSIENT
TRANSIENT异常会在很多情况下出现,下面就是一个例子:
1. 客户端调用对象
2. 对象回应一个LOCATION_FORWARD消息
3. 客户端获得新地址并予以尝试
4. 时间流逝...
5. 客户端利用缓冲中上次获得的地址重新尝试
6. 与对象的连接失败
7. ORB实时运行库清空地址缓冲并抛出TRANSIENT异常,次级代码为TRANSIENT_FailedOnForwarded

在 这个例子中,默认的TRANSIENT异常处理器使用对象的原始地址重新尝试调用,如果接收到另一个LOCATION_FORWARD消息获得相同或不同 的地址而且对这个重定向地址的尝试又失败,TRANSIENT异常又被抛出,现象周而复始。在得到重复的异常后,异常处理器进入之前将根据指数后退算法加 入延时。
在其它情况下,默认的TRANSIENT异常处理器只是将异常传递给调用者。
应用程序可以自行创建处理程序以取代默认做法。下面是相关API的定义:

namespace omniORB {
   typedef CORBA::Boolean (*transientExceptionHandler_t)(void* cookie,CORBA::ULong n_retries,const CORBA::TRANSIENT& ex);
   void installTransientExceptionHandler(void* cookie,transientExceptionHandler_t fn);
   void installTransientExceptionHandler(CORBA::Object_ptr obj,void* cookie,transientExceptionHandler_t fn);
}

被重载函数installTransientExceptionHandler()用来创建对CORBA::TRANSIENT的处理程序,有2种方式:
1. 指定目标对象创建,带了一个cookie参数表示目标对象,参数cookie是ORB调用异常处理函数时提供的不透明指针(opaque pointer).
2. 除了第一种方式涉及的对象外,为所有对象创建

异 常处理器被调用时有三个参数,cookie通过是installTransientExceptionHandler()函数注册的,参数 n_retiries是代理对象为同一个corba调用进入这个异常处理器的次数,参数ex是被捕获的异常对象。异常处理函数在处理完毕后应返回一个 boolean值,如果返回TRUE(1)代理对象将重新尝试调用,如果返回FALSE(0)异常CORBA::TRANSIENT将被抛给应用程序。
下面的示例代码将演示如何为所有对象或一个对象创建简单的异常处理器:
CORBA::Boolean my_transient_handler1 (void* cookie,CORBA::ULong retries,const CORBA::TRANSIENT& ex)
{
  cerr << "transient handler 1 called." << endl;
  return 1; // retry immediately.
}
CORBA::Boolean my_transient_handler2 (void* cookie,CORBA::ULong retries,const CORBA::TRANSIENT& ex)
{
  cerr << "transient handler 2 called." << endl;
  return 1; // retry immediately.
}
static Echo_ptr myobj;
void installhandlers()
{
  omniORB::installTransientExceptionHandler(0,my_transient_handler1);
  // All proxy objects will call my_transient_handler1 from now on.
  omniORB::installTransientExceptionHandler(myobj,0,my_transient_handler2);
  // The proxy object of myobj will call my_transient_handler2 from now on.
}

4.7.3 CORBA::COMM_FAILURE
如 果ORB曾经成功地与目标对象通讯但后续调用失败了(上面提及的TRANSIENT异常条件没有发生),ORB将抛出一个 CORBA::COMM_FAILURE异常。代理对象将默认把这个异常抛给应用程序。应用程序可以创建自己的异常处理器来替代默认的行为。相关API如 下:
class omniORB {
public:
  typedef CORBA::Boolean (*commFailureExceptionHandler_t)(void* cookie,CORBA::ULong n_retries,const CORBA::COMM_FAILURE& ex);
  static void installCommFailureExceptionHandler(void* cookie,commFailureExceptionHandler_t fn);
  static void installCommFailureExceptionHandler(CORBA::Object_ptr obj,void* cookie,commFailureExceptionHandler_t fn);
}
这些函数与处理CORBA::TRANSIENT的相应函数具有相同功能.

4.7.4 CORBA::SystemException
当发生CORBA::TRANSIENT和CORBA::COMM_FAILURE之外的系统异常时,代理对象默认将异常抛给应用程序。应用程序可以创建自己的异常处理器来替代默认的行为。相关API如下:
class omniORB {
public:
   typedef CORBA::Boolean (*systemExceptionHandler_t)(void* cookie,CORBA::ULong n_retries,const CORBA::SystemException& ex);
   static void installSystemExceptionHandler(void* cookie,systemExceptionHandler_t fn);
   static void installSystemExceptionHandler(CORBA::Object_ptr obj,void* cookie,systemExceptionHandler_t fn);
}
这些函数与处理CORBA::TRANSIENT的相应函数具有相同功能.

 译者注:采用这个处理机制,就可以避免在每次CORBA调用时都编写大量的异常捕获处理代码,例如对于偶尔问题需要重新调用的情况就可以统一处理。

 有关异常次级代码的中文意义可以参考Sun公司的相关Java文档
http://202.102.240.73/java/javaweb/linuxjava/cjdk1_2-doc-zh/jdk1.2/zh/docs/guide/idl/jidlExceptions.html

有关异常对象的意义可以参考Sun公司的Java文档
http://gceclub.sun.com.cn/Java_Docs/jdk6/html/zh_CN/api/org/omg/CORBA/class-use/SystemException.html

 一个有关omniORB判定网络连接状态的讨论,它所在thread也可以看看
http://www.nabble.com/timeout-detection-%28client-side%29-to13854764.html#a13877683

加载中
返回顶部
顶部