ICE Manual(Documentation for Ice 3.5)---The Ice Run Time in Detail(Location Transparency)

来源:互联网 发布:淘宝开店装饰教程pdf 编辑:程序博客网 时间:2024/05/19 20:45
Ice run time 的一个有用的特性是位置透明性(location transparent):客户无需知道Ice 对象的实现的位置;对某个对象的调用会被自动引导到正确的目标,不管这个对象的实现是在本地地址空间中,在同一台机器上的另一个地址空间中,还是在一台远地机器上的另一个地址空间中。位置透明性十分重要,因为有了它,我们能够改变对象实现的位置,而不会破坏客户程序,同时,通过使用IceGrid,像域名和端口号这样的信息可以放在应用的外部,不用出现在串化代理中。如果调用跨越了地址空间的界线(或者更准确地说,跨越了通信器的界线), Ice run time 会通过适当的传输机制分派请求。但是,如果调用所使用的代理和负责处理该调用的servant 处在同一个通信器中(所谓的并置

调用),在缺省情况下, Ice run time 不会通过在代理中指定的传输机制发送调用。相反,在Ice run time 中,并置的调用会“走捷径”,直接被分派。


之所以要这样做,原因是效率:例如,如果并置的调用是通过TCP/IP发送的,那么这些调用仍将通过操作系统内核发送(使用底板而不是网络),并且需要负担全部这样的开销:创建TCP/IP 连接、把请求整编成包、陷入和陷出内核,等等。通过优化并置的请求,大部分这样的开销都可以避免,让并置的调用几乎和本地函数调用一样快。出于效率上的考虑,并置的调用不完全是位置透明的,也就是说,在某些方面,并置调用的语义与跨越地址空间界线的调用不同。特别地,并置调用与普通调用在以下一些方面有所不同:

• 并置的调用会在发出调用的线程中分派,而不是由从服务器的线程池中取出的另外一个线程分派。
• 对象适配器的“扣留”状态会被忽略:即使目标对象的适配器处在“扣留”状态,并置的调用也会被正常处理。
• 对于并置的调用,类和异常不会被切断。相反,接收者所接收到的类或异常的类型总是发送者所发送的派生类型。
• 如果并置的调用抛出的异常不在操作的异常规范中,在客户中引发的就是这个异常,而不是UnknownUserException (这只适用于C++ 映射)。
• 异步方法调用(AMI) 和异步方法分派(AMD) 不能用于并置的调用。
• 对于并置的调用,类工厂会被忽略。
• 调用超时会被忽略。
在实践中,这些差异通常并没有关系。在使用并置的调用时,最有可能让你惊奇的是,分派是在发出调用的线程中进行的,也就是说,并置的调用的行为就像是本地的同步过程调用。例如,如果发出调用的线程获取了一个锁,操作实现也想获取,就有可能发生问题:这会造成死锁,除非你使用递归互斥体。

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

One of the useful features of the Ice run time is that it is location transparent: the client does not need to know where the implementation of an Ice object resides; an invocation on an object automatically is directed to the correct target, whether the object is implemented in the local address space, in another address space on the same machine, or in another address space on a remote machine. Location transparency is important because it allows us to change the location of an object implementation without breaking client programs and, by using IceGrid, addressing information such as host names and port numbers can be externalized so they do not appear in stringified proxies.

For invocations that cross address space boundaries (or more accurately, cross communicator boundaries), the Ice run time dispatches requests via the appropriate transport. However, for a proxy invocation in which the proxy and the servant that processes the invocation share the same communicator (so-called collocated invocations), the Ice run time, by default, does not send the invocation via the transport specified in the proxy. Instead, collocated invocations take a short-cut inside the Ice run time and are dispatched directly.

Note that if the proxy and the servant do not use the same communicator, the invocation is not collocated, even though caller and callee are in the same address space.

The reason for this is if collocated invocations were sent via TCP/IP, for example, invocations would still be sent via the operating system kernel (using the back plane instead of a network) and would incur the full cost of creating TCP/IP connections, marshaling requests into packets, trapping in and out of the kernel, and so on. By optimizing collocated requests, much of this overhead can be avoided, so collocated invocations are almost as fast as a local function call.

For efficiency reasons, collocated invocations are not completely location transparent, that is, a collocated call has semantics that differ in some ways from calls that cross address-space boundaries. Specifically, collocated invocations differ from ordinary invocations in the following respects:

  • Collocated invocations are dispatched in the calling thread instead of being dispatched using the server's concurrency model.
  • The object adapter holding state is ignored: collocated invocations proceed normally even if the target object's adapter is in the holding state.
  • For collocated invocations, classes and exceptions are never sliced. Instead, the receiver always receives a class or exception as the derived type that was sent by the sender.
  • If a collocated invocation throws an exception that is not in an operation's exception specification, the original exception is raised in the client instead of UnknownUserException. (This applies to the C++ mapping only.)
  • Class factories are ignored for collocated invocations.
  • Timeouts on invocations are ignored.
  • If an operation implementation uses an in parameter that is passed by reference as a temporary variable, the change affects the value of the in parameter in the caller (instead of modifying a temporary copy of the parameter on the callee side only).
  • Asynchronous semantics are not supported for collocated invocations.

In practice, these differences rarely matter. The most likely cause of surprises with collocated invocations is dispatch in the calling thread, that is, a collocated invocation behaves like a local, synchronous procedure call. This can cause problems if, for example, the calling thread acquires a lock that an operation implementation tries to acquire as well: unless you use recursive mutexes, this will cause deadlock.

The Ice run time uses the following semantics to determine whether a proxy is eligible for the collocated optimization:

  • For an indirect proxy, collocation optimization is used if the proxy's adapter ID matches the adapter ID or replica group ID of an object adapter in the same communicator.
  • For a well-known proxy, the Ice run time queries each object adapter to determine if the servant is local.
  • For a direct proxy, the Ice run time performs an endpoint search using the proxy's endpoints.

When an endpoint search is required, the Ice run time compares each of the proxy's endpoints against the endpoints of the communicator's object adapters. Only the transport, address and port are considered; other attributes of an endpoint, such as timeout settings, are not considered during this search. If a match is found, the invocation is dispatched using collocation optimization. Normally this search is executed only once, during the proxy's first invocation, although the proxy's connection caching setting influences this behavior.

Collocation optimization is enabled by default, but you can disable it for all proxies by setting the property Ice.Default.CollocationOptimized=0. You can also disable the optimization for an individual proxy using the factory methodice_collocationOptimized(false). Finally, for proxies created from a property using propertyToProxy, the property name.CollocationOptimized configures the default setting for the proxy.