1 <!DOCTYPE HTML PUBLIC
"-//W3C//DTD HTML 3.2 Final//EN">
7 <TITLE>Using the TAO::Transport::Current Feature
</TITLE>
9 <META HTTP-EQUIV=
"Content-Type" CONTENT=
"text/html; charset=iso-8859-1">
10 <META HTTP-EQUIV=
"Content-Style-Type" CONTENT=
"text/css">
12 <LINK REL=
"STYLESHEET" HREF=
"transport_current.css">
16 <BODY TEXT =
"#000000" LINK=
"#000fff" VLINK=
"#ff0f0f" BGCOLOR=
"#ffffff">
20 <H1 ALIGN=
"CENTER">Using the TAO::Transport::Current Feature
</H1>
24 Object Computing Inc.
<BR>
30 <A HREF=
"mailto:iliyan@ociweb.com">Iliyan Jeliazkov
</A>
31 <A HREF=
"mailto:mesnier_p@ociweb.com">Phil Mesnier
</A>
32 and
<A HREF=
"mailto:<john_c@ociweb.com">Ciju John
</A>
39 <H3>Scope and Context
</H3><P>
41 <P>In TAO, it is just too hard to obtain statistical or pretty much any operational information about the network transport which the ORB is using. While this is a direct corollary of the CORBA's design paradigm which mandates hiding all this hairy stuff behind non-transparent abstractions, it also precludes effective ORB and network monitoring.
45 The Transport::Current feature intends to fill this gap by defining a
46 framework for developing a wide range of solutions to this problem. It also provides a basic implementation for the most common case - the IIOP transport.
50 By definition, transport-specific information is available in
51 contexts where the ORB has selected a Transport:
</P>
54 <LI>Within Client-side interception points;
</LI>
55 <LI>Within Server-side interception points;
</LI>
56 <LI>Inside a Servant up-call
</LI>
60 The implementation is based on a generic service-oriented
61 framework, implementing the TAO::Transport::Current interface. It is
62 an optional service, which can be dynamically loaded. This service makes
63 the Transport::Current interface available through
64 orb-
>resolve_initial_references() . The basic idea is that whenever a Transport is
65 chosen by the ORB, the Transport::Current (or a derivative) will have access
66 to that instance and be able to provide some useful information.
74 Programmer's Reference
78 Consider the following IDL interface, describing a Factory for
79 producing TAO::Transport::Traits instance, which represents
80 transport-specific data.
85 #include
<TimeBase.pidl
>
89 /// A type used to represent counters
90 typedef unsigned long long CounterT;
94 /// Used to signal that a call was made within improper invocation
95 /// context. Also, this exception is thrown if no Transport has
96 /// been selected for the current thread, for example in a
97 /// collocated invocation.
103 // The primary interface, providing access to Transport
104 // information, available to the current thread.
106 local interface Current
108 /// Transport ID, unique within the process.
109 readonly attribute long id raises (NoContext);
111 /// Bytes sent/received through the transport.
112 readonly attribute CounterT bytes_sent raises (NoContext);
113 readonly attribute CounterT bytes_received raises (NoContext);
115 /// Messages (requests and replies) sent/received using the current
117 readonly attribute CounterT messages_sent raises (NoContext);
118 readonly attribute CounterT messages_received raises (NoContext);
120 /// The absolute time (miliseconds) since the transport has been
122 readonly attribute TimeBase::TimeT open_since raises (NoContext);
129 As an example of a specialized Transport::Current is the Transport::IIOP::Current, which derives from Transport::Current and has an interface, described in the following IDL:
135 /// Provide a forward reference for the SSLIOP::Current
148 // The primary interface, providing access to IIOP-specific
149 // transport information, if it is indeed an IIOP (-like) transport
150 // that has been selected.
152 local interface Current : TAO::Transport::Current
155 readonly attribute string remote_host raises (NoContext);
157 /// Remote port Using long (signed) type to better accomodate
158 /// the Java mapping, which has no support for unsigned values
159 readonly attribute long remote_port raises (NoContext);
162 readonly attribute string local_host raises (NoContext);
165 readonly attribute long local_port raises (NoContext);
167 /// If this is a
"secure" transport, this method will give you
168 /// the corresponding SSLIOP::Current
169 readonly attribute ::SSLIOP::Current ssliop_current raises (NoContext);
183 The TAO::Transport::Current can be used as a base interface for a more specialized TAO::Transport::X::Current. It is not required, however that a more specialized Current inherits from it.
187 Typical, generic usage is shown in the
188 $TAO_ROOT/orbsvcs/tests/Transport_Current/Framework test:
193 // Get the Current object.
194 ::CORBA::Object_var tcobject =
195 orb-
>resolve_initial_references (
"TAO::Transport::Current"
196 ACE_ENV_SINGLE_ARG_DECL);
199 ::TAO::Transport::Current_var tc =
200 ::TAO::Transport::Current::_narrow (tcobject.in ()
201 ACE_ENV_SINGLE_ARG_DECL);
204 if (CORBA::is_nil (tc.in ()))
206 ACE_ERROR ((LM_ERROR,
207 ACE_TEXT (
"(%P|%t) client - ERROR: Could not resolve ")
208 ACE_TEXT (
"TAO::Transport::Current object.\n")));
210 ACE_TRY_THROW (CORBA::INTERNAL ());
216 Another example is available from the $TAO_ROOT/orbsvcs/tests/Transport_Current/IIOP test. This fragment shows how to obtain transport-specific information:
221 // Get the specific Current object.
222 CORBA::Object_var tcobject =
223 orb-
>resolve_initial_references (ACE_TEXT_ALWAYS_CHAR (
"TAO::Transport::IIOP::Current")
224 ACE_ENV_ARG_PARAMETER);
228 Transport::IIOP::Current_var tc =
229 Transport::IIOP::Current::_narrow (tcobject.in ()
230 ACE_ENV_SINGLE_ARG_DECL);
233 if (CORBA::is_nil (tc.in ()))
234 ACE_TRY_THROW (CORBA::INTERNAL ());
236 ::CORBA::String_var rhost (tc-
>remote_host (ACE_ENV_SINGLE_ARG_PARAMETER));
239 ::CORBA::String_var lhost (tc-
>local_host (ACE_ENV_SINGLE_ARG_PARAMETER));
242 ::CORBA::Long id = tc-
>id (ACE_ENV_SINGLE_ARG_PARAMETER);
245 ::TAO::CounterT bs = tc-
>bytes_sent (ACE_ENV_SINGLE_ARG_PARAMETER);
248 ::TAO::CounterT br = tc-
>bytes_received (ACE_ENV_SINGLE_ARG_PARAMETER);
251 ::TAO::CounterT rs = tc-
>messages_sent (ACE_ENV_SINGLE_ARG_PARAMETER);
254 ::TAO::CounterT rr = tc-
>messages_received (ACE_ENV_SINGLE_ARG_PARAMETER);
263 Configuration, Bootstrap, Initialization and Operation
267 To use the Transport Current features the framework must be loaded
268 through the Service Configuration framework. For example, using
273 dynamic TAO_Transport_Current_Loader Service_Object * TAO_TC:_make_TAO_Transport_Current_Loader()
""
277 The Transport_Current_Loader service uses an ORB initializer to register the
"TAO::Transport::Current" name in a way that allows it to be resolved via orb-
>resolve_initial_references(). The implementation is the TAO::Transport::Current_Impl class.
281 A transport-specific Traits_Factory objects are loaded like this:
286 dynamic TAO_Transport_IIOP_Current_Loader Service_Object * TAO_TC_IIOP:_make_TAO_Transport_IIOP_Current_Loader()
""
291 Note that any number of transport-specific Current interfaces may be available at any one time.
295 Whenever a Transport::Current method is invoked, a pointer to the currently selected Transport instance must be accessible through Thread Specific Storage (TSS). For each thread, this is managed by modifying the TAO classes, instances of which are created on the stack during request/response processing.
300 Implementation and Required Changes
304 The primary implementation is predicated upon usage of thread specific
305 storage (TSS) and the guarantees C++ provides for calling the
306 constructor and the destructor of automatic (stack-based)
307 objects. Some existing objects, used in TAO will have to be modified
308 and the necessary changes, both for client and the server side are
313 Client Side: Sending Requests or Replies
318 The Profile_Transport_Resolver instance contains the reference to the
319 Transport, which is the TAO implementation structure that is needed to extract
320 any protocol-specific information. An
321 instance of Profile_Transport_Resolver lives on the stack, starting
322 inside a call to Invocation_Adapter::invoke_remote_i(), or
323 LocateRequest_Invocation_Adapter::invoke(). In the case of collocated
324 invocations no such object is created.
328 It is then passed around the calls that follow, except for the calls
329 to the following Invocation_Base methods: send_request_interception(),
330 receive_other_interception(), receive_reply_interception(),
331 handle_any_exception(), handle_all_exception();
335 Note that these in turn call the client-side interception points and
336 that is where information about the transport will be needed. In order
337 to make the transport information accessible inside those methods, we
338 changed Profile_Transport_Resolver and the TAO_ServerRequest classes to
339 incorporate an additional member:
344 TAO::Transport_Selection_Guard transport_;
350 This guard automatically keeps track of the currenty selected Transport from within its constructor and destructor. The rest of the TC framework makes sure this pointer is stored in a thread-specific storage, by adding an additional member to TSS_Resources:
355 TAO::Transport_Selection_Guard* tsg_;
360 The idea is to keep a pointer to the last guard on the current thread. Each guard keeps a pointer to the previous, effectively creating a stack of transport selection guards. The stack structure ensures both that the selection/deselection of a Transport will be correctly handled. It also ensures that, in case the current thread temporarily changes the Transport, the previous “current” transport will be preserved, no matter how many times such change occurs. A good example for this is a nested up-call scenario.
364 Inside an interceptor, one can use the methods from Transport Current to obtain information on the currently selected transport. The implementation simply looks up the TAO_Transport pointer via TSS_Resources::tsg_ and obtains the requested data.
370 Server Side: Request Processing
375 On the server side, the TAO_ServerRequest instance already has a
376 Transport pointer. The TAO_ServerRequest lives on the stack, starting
377 its life inside a call to TAO_GIOP_Message_Base::process_request().
381 Similarly to the client-side, we changed the TAO_ServerRequest
387 TAO::Transport_Selection_Guard transport_;
392 Operation is similar to the client-side case. In the collocated case there may not be a
393 transport available, so the TSS slot will be null.
397 Inside an interceptor then, one can use an RIR-resolved
398 TransportCurrent to create a specialization of TransportInfo, based on
399 the kind of Transport used. Then they would _downcast() it to the
404 Structural and Footprint Impact
408 As the IIOP implementation of the Transport Current functionality requires additional
409 data to be kept about the Transport, we added a new field to TAO_Transport:
414 /// Transport statistics
415 TAO::Transport::Stats* stats_
420 TAO::Transport::Stats is a simple structure, which keeps track of useful statistical
421 information about how a transport is used:
426 class TAO_Export Stats
431 void messages_sent (size_t message_length);
432 CORBA::LongLong messages_sent () const;
433 CORBA::LongLong bytes_sent () const;
435 void messages_received (size_t message_length);
436 CORBA::LongLong messages_received () const;
437 CORBA::LongLong bytes_received () const;
439 void opened_since (const ACE_Time_Value& tv);
440 const ACE_Time_Value& opened_since () const;
443 CORBA::LongLong messages_rcvd_; //
32bits not enough (?)
444 CORBA::LongLong messages_sent_; //
32bits not enough (?)
446 ACE_Basic_Stats bytes_rcvd_;
447 ACE_Basic_Stats bytes_sent_;
449 ACE_Time_Value opened_since_;
455 To gather the statistics the TAO_Transport::send_message_shared() and TAO_Transport::process_parsed_messages() must be modified. These are non-virtual methods and are being called as part of request and reply processing regardless of what the most derived Transport type is. This property ensures that any specific Transport will have access to these statistics.
463 As the implementation of the Transport Current functionality
464 necessitates some additional processing on the critical path of an
465 invocation, we are expecting a performance impact when the
466 functionality is being used.
470 It is possible at build time, to
471 disable the functionality, so that applications only incur the penalty
472 if they require the features. The ORB, by default enables the Transport::Current
473 functionality. Adding
"transport_current=0" to your default.features file will
482 Look at $TAO_ROOT/orbsvcs/tests/Transport_Current for code which illustrates and tests this feature.