ch10 (5)

Lemur zaprasza

Teach Yourself CORBA In 14 Days







Day 10
Learning About CORBA Design Issues



IDL Creep
Single-Threaded Applications

Server Applications
Client Applications
Mixed Server/Client Applications

Object Lifetime
Lack of Pass-by-Value Semantics

Rogue Wave ORBstreams.h++
Using CORBA structs
Using Conversion Constructors

CORBA and X Window System

Single-Threaded Applications Using CORBA and X
Multithreaded Applications Using CORBA and X

Summary
Q&A
Workshop

Quiz









By now you have probably determined for yourself that CORBA is a complex architecture.
Like any complex architecture, CORBA comes with its own set of issues that affect
the design and implementation of CORBA systems. For example, the fact that all interfaces
in CORBA are specified in IDL has an effect on developers who want to integrate existing
systems with CORBA--usually, IDL interfaces have to be written for a number of existing
classes (not a trivial undertaking). This chapter introduces you to such design issues
and offers suggestions on how to deal with them.
IDL Creep
The term IDL creep does not refer to that guy in the office down
the hall who thinks he knows everything about the Interface Definition Language.
Rather, it is a term coined to refer to the tendency for IDL to permeate a system
design--and permeate it does. Think about it: For a class to be understood by CORBA,
its interface must be expressed in IDL. Furthermore, if the classes referenced or
otherwise used by that class also need to be accessible to CORBA components, then
those classes must also have their interfaces expressed in IDL. Consequently, it
is not uncommon for most, if not all, classes in a system to require IDL specifications.
If you're designing an application from the ground up, having to define IDL interfaces
for most (or even all) classes isn't terribly demanding. However, if you're converting
an existing application to CORBA, the process can be an arduous one indeed. Because
the existing classes were probably not written with CORBA--or a distributed architecture
of any kind--in mind, the interfaces for those classes might have to be modified
somewhat to mesh well with IDL. Although the modifications themselves might not require
a great deal of effort, remember that if the interface of an object changes, any
code that uses that object might have to be modified as well. This cascade effect
can easily turn a few interface changes in a relatively few classes into a frustrating
mess of changes throughout an application.
This scenario doesn't even take into consideration the possibility that the non-CORBA
application's very architecture might not be amenable to the CORBA architecture.
In particular, CORBA's current lack of the capability to pass objects by value can
especially affect the design of an application (discussed later in this chapter).
Sometimes, modifying an existing application to use CORBA can be like trying to fit
a square peg into a round hole.
The moral is that IDL is pervasive--it has a way of creeping into a system design
and slowly taking it over. This is not necessarily a bad thing in itself, but it
can potentially make the "CORBAtization" of legacy applications a difficult
prospect. Be prepared to write IDL for any class in an application that might need
to be shared between application components.
It is not always possible to avoid introducing IDL into most classes of an existing
application without entailing a significant redesign of portions (or all!) of the
application. However, when designing an application from the ground up, there is
one guideline in particular for minimizing the impact of IDL on the rest of the application:
Pay close attention to which classes will likely need to be shared between application
components and which will not. The underlying classes (e.g., classes that aren't
part of any interfaces between components) generally will not require IDL interfaces.
Single-Threaded Applications
Although most modern operating systems support multithreaded applications--that
is, applications in which multiple threads of control might be executing in a single
program at the same time--the use of multithreading is still limited. There are several
reasons for this: Not all operating systems fully support threading, not all developers
use the later versions of operating systems, which do support threading, and not
all developers feel comfortable with it anyway. In addition, using multiple threads
in applications introduces new issues--not the least of which is the need to manage
concurrent access to objects--that complicate application design and development.
Consequently, the use of multithreading is not as widespread as it could be.
CORBA does not force developers into a multithreaded development paradigm; indeed,
it is perfectly feasible to create single-threaded CORBA applications. However, due
to the nature of the operation of distributed applications, great care must be taken
when designing and developing CORBA applications for a single-threaded environment.
This chapter tells you why, covering issues on both the server and client ends of
the application.
Server Applications
The justification for using multiple threads in server applications is simple:
A CORBA server might have multiple clients accessing it at any given time. If the
server is single-threaded, it can only process a request from one client at a time--if
another client attempts to access the server while the server is busy processing
a second client's request, the first client must wait until the server is finished
(see Figure 10.1). The obvious disadvantage to this architecture is that if the server
performs transactions that take time to complete, the apparent responsiveness of
the system (as far as the end users are concerned) suffers.

Figure 10.1. Single-threaded server
operation.

One approach to mitigating this problem is to employ the use of multiple servers
in an application. Normally, an enterprise-scale application employs multiple servers
anyway, for reasons such as load balancing and redundancy. However, it is simply
not practical to provide a server per concurrent client, given the amount of overhead
required by each server application. It is much more efficient for a single server
to handle multiple simultaneous clients, and this is precisely the capability afforded
by a multithreaded architecture.
In a multithreaded server architecture (see Figure 10.2), rather than process
only one client request at a time, the server can start a new thread of execution
for each transaction. Because there is always a thread listening for new requests,
other clients no longer need to wait for the server to complete a transaction before
it can accept the next one. The result is that the server appears more responsive
because it can respond immediately to incoming requests.

Figure 10.2. Multithreaded server
operation.

Although the multithreaded architecture can create the illusion of better server
performance by enhancing server responsiveness, the architecture does not magically
make servers faster. If the server is processing several transactions simultaneously,
the speed at which each transaction is processed is likely to decrease relative to
a server processing only one transaction at a time. (Multithreaded applications can
be more efficient than single-threaded applications, however, so a server processing
only one transaction at a time might not be twice as fast as a server processing
two transactions simultaneously.) So, although the use of multithreading is not intended
to replace the use of multiple servers, it is usually preferable to deploy multiple
multithreaded servers than multiple single-threaded servers. Furthermore, in most
cases, fewer multithreaded servers are required to deliver the same end user responsiveness.
Because multithreading does not come for free, it is important to understand when
it is appropriate. Managing multiple threads, especially when it is necessary (as
it often is) to prevent multiple threads from simultaneously accessing the same data,
can result in costly overhead. Consequently, on a machine with a single CPU, adding
multiple threads to an application that is already CPU-bound will only make it slower
(although response time to individual clients, as discussed previously, might still
improve). On the other hand, on a multiprocessing machine, because each thread can
potentially run on its own CPU, performance when using multithreading might increase,
even on a CPU-bound application. Where multiprocessing truly shines, however, is
in I/O-bound server applications or in applications that act as clients and servers
simultaneously (as you will see in the next section). In an I/O-bound server application
with multiple client connections, the likelihood that a given thread will be blocked
while waiting for I/O increases. Hence, other threads will be given the opportunity
to do useful work, thus using the available CPU(s) more efficiently.
The bottom line regarding the use of threads in CORBA servers is this: If the
server can process transactions quickly enough so that response time is not a concern,
a single-threaded server will probably suffice. If the response time of a single-threaded
server is not adequate, the use of multithreading is probably a better alternative.
Note that this is true only if the server does not also act as a client. If it performs
both roles, there might be additional issues involved, as you will soon see.
Client Applications
Unlike a server application, a client application does not need to concern itself
with providing a reasonable response time to other clients. In most cases, when a
client calls a remote method on a server, it is perfectly reasonable for the client
to wait for the server's response before continuing. This is true as long as one
assumption holds true--that the client application is a pure client; that
is, the application does not create any CORBA objects and pass references to those
objects to other applications.
Mixed Server/Client Applications
The guidelines for the use of threads in pure servers (applications that behave
as servers only, never as clients) are clear-cut: If the response time requirements
warrant it, multithreading is preferred; otherwise, single threading is adequate.
The guidelines for pure clients are simple as well: Under most circumstances, multithreading
is not required. Therefore, you can conclude that single-threaded architectures are
adequate for most CORBA applications. If your applications were all pure servers
and clients, you'd be right.
When an application demonstrates behaviors of a server and a client--call it a
mixed server/client application for lack of a better term--the design issues
associated with using a single-threaded architecture become insidious. Illustrated
in Figure 10.3 is the basic problem: If a single-threaded, mixed server/client application
passes one of its objects to a second application in a remote method call, and the
second application, in turn, tries to access the object passed to it, both applications
become blocked.

Figure 10.3. Single-threaded mixed
server/client application operation.

Of course, this problem is neatly solved by the use of multithreading in the mixed
server/client application, as illustrated in Figure 10.4. If multithreading is not
an option for whatever reason, another solution is required. The remainder of this
section discusses potential solutions to the problems involved in developing single-threaded
applications that need to assume the roles of both client and server.
Presented here are two useful design patterns for designing CORBA applications
using only single-threaded components. Again, the use of multithreading is probably
the cleanest method of implementing CORBA applications, but when multithreading is
not an option, you will want to consider one of these design patterns.
Object Factory Pattern
Recall that single-threaded applications that are pure servers or pure clients
don't suffer from the deadlock problem illustrated in

Figure 10.3. The Object Factory
pattern

capitalizes on this property of pure client and pure server applications by moving
functionality to the appropriate component of the application, resulting in application
components that are either pure clients or pure servers.





Note:In the Object Factory design pattern, a factory object is responsible
for creating objects of a particular type. For example, the Bank object
can be thought of as an Account factory, since Banks are responsible for creating
all Account objects in the system.





Figure 10.4. Multithreaded
mixed server/client application operation.

To understand how this is feasible, consider the following scenario: A client wishes
to call a remote method on a server. The method takes a particular type of object
as a parameter; call it a Widget. Now assume that the Widget is created by the client.
If the client were to pass a Widget that it created to the server through a remote
method, and that method attempted to call a method on the Widget, the result would
be a deadlock scenario, as described in Figure 10.3. These are the typical application
semantics over which single-threaded applications stumble. It would be most useful
if these types of semantics could be achieved in a way that worked with single-threaded
applications.
This is where the Object Factory pattern steps in (see Figure 10.5). This pattern
takes the place of the object creation step. Rather than create the Widget itself,
the client requests the Factory (which is the same object as the server whose method
the client wishes to invoke) to create the Widget on the client's behalf. The client
can then manipulate the Widget, if desired, and can finally invoke the desired remote
method on the server, passing the Widget as a parameter. Now, because the Widget
exists in the same address space as the rest of the server, the server can manipulate
the Widget as it sees fit.

Figure 10.5. Object Factory pattern.


The Object Factory pattern boasts the advantage of enabling single-threaded clients
to pass objects as parameters to remote methods. This capability comes at a price:
The server must provide methods for creating every type of CORBA object that a client
might want to create. Although providing implementations for these methods is simple,
it can be tedious, particularly in applications containing large numbers of classes.
Also, it can be more inconvenient for clients to call additional methods to create
objects rather than to directly use constructors, although this inconvenience might
be minimal. These drawbacks, however, are often outweighed by the advantages offered
by the Object Factory pattern.
Exclusive oneway Call Pattern
Another approach to creating harmony between single-threaded applications and
CORBA is what you might call the Exclusive oneway Call pattern.
This pattern calls for the exclusive use of oneway invocations throughout
the application. Because oneway methods don't block, the deadlock issue
associated with single-threaded CORBA applications is eliminated. However, this advantage
comes at a price, as you'll soon find out.





Note:The Exclusive oneway Call design pattern calls
for the exclusive use of oneway methods for communication between CORBA
objects.





Note:For a review of CORBA oneway methods, refer to Day 3, "Mastering
the Interface Definition Language (IDL)."





The exclusive use of oneway method calls throughout a CORBA application
exacts a potentially stiff penalty: First, the concept of a clearly laid-out program
flow is lost. Consider a typical client application. There is generally a well-defined
flow of control through the program. That is, there is a main method--it might very
well be C/C++/Java's main()--at which the program begins and proceeds to
call other methods. Usually, the flow of the program can be determined by tracing
the sequence of method calls. In other words, the behavior of the application is
at least somewhat predictable because the execution flow can be traced relatively
easily.
Using oneway methods exclusively, however, radically alters the landscape
of an application, as illustrated in Figure 10.6. Instead of a well-defined flow
of control traceable throughout the application, the client features a series of
seemingly disjointed oneway methods. The exchange between client and server,
rather than following the familiar pattern of "client calls server/server returns
result" is transformed into a volley of oneway calls from one application
to the other. The client starts by calling a method on the server. That method, when
completed, calls a method on the client that performs the second step in the application.
That method, in turn, calls another method on the server, which eventually calls
a method on the client, and so on.
Again, because each method called is oneway, there is no blocking due
to the client or server being busy. Consequently, each application is free to pass
any CORBA objects--including objects created by itself--without fear of blocking.
The downside of this architecture is that because the flow of control is now shared
between two applications, it is much more difficult to trace.
Another penalty that must be paid by developers wanting to use the Exclusive oneway
Call pattern stems from a characteristic of oneway methods which you should
recall--namely, that oneway messages are not guaranteed to be delivered
to their destination. Building an entire application based on this mechanism is certain
to be a trying experience, primarily because if there are any methods in the application
which require reliable delivery, the developer must implement a mechanism to determine
whether a oneway method call actually executed successfully. In other words,
the developer essentially must implement reliable delivery semantics on top of the
unreliable oneway mechanism, in addition to implementing all the usual application
functionality.

Figure 10.6. Exclusive oneway
Call pattern.

To summarize the Exclusive oneway Call design pattern, it should be stressed
that this pattern would be extremely difficult to implement for most real-world production
systems. Consequently, developers are strongly encouraged to pursue a different method
of marrying client and server functionality in a single-threaded application if at
all possible.
Object Lifetime
In a non-distributed application, management of object lifetime is a non-issue:
When the application is finished using an object, it simply destroys it. With garbage-collected
languages like Java, the developer does not even need to write code to do this--the
application handles it automatically. If the application crashes, the memory used
by its objects is reclaimed by the operating system. Because all objects are self-contained
in the application, there are no issues associated with object lifetime.
In a distributed application, circumstances are different. An application might
use objects that are local to the application--that is, objects that live in the
same address space as the application--or it might use remote objects, which might
reside in a different process on the same machine or on a different machine somewhere
on the network. Many CORBA ORB products use reference counting for managing object
lifetime--a mechanism which works well when applications behave normally. Although
the use of a reference-counting mechanism is not dictated by CORBA, its inclusion
into some major ORB products merits some discussion here. Recall that in such a reference-counting
mechanism, object references are duplicated--that is, their reference count is incremented--when
the reference is passed to an application. Similarly, when an application is finished
using an object, it releases the object reference, that is, decrements the reference
count. When the reference count reaches zero, the object is no longer in use and
can safely be destroyed.
But what happens when an application holding an object reference crashes before
it can release that object reference? This is where the reference-counting mechanism
begins to break down. Under these circumstances, the object's reference count never
reaches zero, and thus the object is never destroyed. This can be thought of as a
sort of memory leak in a distributed application. Consequently, developers might
need to think beyond the reference counting mechanism and consider a contingency
mechanism that picks up where reference counting leaves off.
Because a distributed application cannot truly know when all other applications
are finished using its objects (because it doesn't know whether any of those applications
have crashed), a mechanism over and above the basic reference-counting mechanism
is required. Such a mechanism manages the lifetime of CORBA objects, automatically
determining whether an object is in use and, if not, destroying that object. But
how does this mechanism determine whether an object is still in use? Actually, it
can only guess. To understand how such a mechanism works, consider the following
case study.
One such mechanism, known as the Evictor, manages object lifetime by tracking
the usage of each CORBA object within a server (each CORBA server would contain its
own Evictor). When an object has not been in use for a predetermined period of time
(for example, a day), the Evictor evicts that object. Although it's possible
for the eviction process to simply destroy the unused object, recall that the Evictor
does not know for certain that the object is no longer in use. It is possible that
one of the clients using that object could be dormant for a period of time, and if
the object were destroyed, the client, on waking up, would no longer be able to access
that object. To accommodate this possibility, the Evictor does not actually destroy
a CORBA object after a period of non-use but evicts it into a persistent store, such
as a database. If that object is needed later, it can be resurrected from the persistent
store. All this occurs transparently to clients, which are completely unaware that
objects are being evicted and resurrected as necessary.
Of course, a mechanism such as the Evictor, rather than enabling potentially unused
objects to consume memory in a server process's address space, simply moves the unused
objects to some form of persistent storage. The result is that unused objects still
exist somewhere--in this case, the persistent storage rather than the server application
address space. Using persistent storage for this purpose, in addition to offering
the advantage of freeing up a server machine's memory resources, provides for simpler
maintenance. That is, the objects in persistent storage can be cleaned up periodically,
perhaps as a part of the system's periodic maintenance cycle. Purging the database
of unused objects in this way would not require system administrators to bring down
the server, thus enhancing the server availability.
Lack of Pass-by-Value Semantics
Perhaps one of the trickiest issues associated with CORBA development is that
CORBA does not currently support the capability to pass objects by value. (This limitation
is expected to be removed in a later version of CORBA; see Appendix C, "What
Lies Ahead? The Future of CORBA," for more details on this and other future
enhancements to the CORBA architecture.) Sometimes it is far more efficient for a
server to return an object by value to a client so that the client can act on the
object locally rather than call a series of remote methods--each of which incurs
the overhead of executing a method remotely--on the object. See Figure 10.7 for an
illustration of this scenario.
Clearly, if a client is to invoke a large number of methods on an object, it is
preferable, in terms of efficiency, to act on a local copy of the object rather than
a remote one. This is particularly true if the parameters or return value of the
method(s) are complex values. Such values are even more expensive to transmit across
the network, as is the case with remote methods.
If passing objects by value is sometimes a good idea, but CORBA doesn't offer
the capability, then isn't the entire discussion a moot point anyway? As it turns
out, even though CORBA doesn't offer this capability directly, there are several
approaches that emulate this behavior.
Rogue Wave ORBstreams.h++
Rogue Wave Software offers a product that enables CORBA applications to pass C++
objects by value. The product, which builds on Rogue Wave's Tools.h++ product,
provides the capability to pass many of the Tools.h++ classes by value,
as well as user-defined classes that derive from certain Tools.h++ classes
or conform to the proper Rogue Wave-supplied interfaces.

Figure 10.7. Pass-by-reference
versus pass-by-value.

ORBstreams.h++ does have some disadvantages. For one, it only supports C++.
(If you're implementing a CORBA application entirely in C++--which isn't altogether
unlikely--this probably isn't of concern to you.) Also, the product currently supports
only one ORB--IONA Technologies' Orbix--further limiting your choice of development
tools. Finally, because ORBstreams.h++ builds on the Tools.h++
product, you might be saddled with additional baggage associated with using Tools.h++,
if you didn't originally plan on using that product. For all its drawbacks, however,
ORBstreams.h++ is a good stopgap solution to the current lack of pass-by-value
capability in CORBA.
Using CORBA structs
Another approach to achieving a pass-by-value-like behavior is the strategic use
of CORBA structs. For each CORBA interface that needs to be passed by value,
the developer creates a struct that contains members corresponding to all
the data members of the class implementing the interface. After these structs
are defined, the mechanism works something like this:


1. A method that ordinarily uses interface types for parameters and return
value instead uses the corresponding struct types.

2. Before calling such a method, the client creates struct versions
of the objects it wants to pass by value. It then invokes the method with these parameters.

3. The server creates objects corresponding to the structs (if necessary),
performs its processing, and creates structs for any output parameters or
return values that are to be passed by value.

4. The client receives the output parameters and/or return value from the server
and, if necessary, creates objects that correspond to the struct parameters.


There are a few disadvantages to this approach. The most significant is that inheritance
is not a feature of structs; therefore, polymorphism is not supported. In
other words, if a particular method takes a certain kind of struct as a
parameter, it is not possible to pass another type of struct in its place.
Referring to the Bank example, this is akin to creating a CheckingAccount
object and passing it back in the place of an Account parameter. However,
the CORBA any type might be of use here, at the expense of increased complexity.
Using Conversion Constructors
A third approach that emulates pass-by-value capability in CORBA is to pass an
object normally, but then for the client (or server, depending on whether the object
is an input or output parameter) to copy the object's state immediately on receipt.
The process is as follows:


1. A client calls a method on a server, which returns an object reference.
The server simply returns the object reference as usual.

2. On receiving the object reference, the client creates a new object of the
same type, copying the remote object's state into the local one. This is generally
done through the use of a constructor that takes the remote object as an argument,
converting that object into a local one (hence the term conversion constructor.)

3. The client releases the remote object and continues working with the local
one.


Compared to the struct approach, the conversion constructor approach
has the advantage of being able to work with objects of inherited class types. Additionally,
this approach does not require the development of separate IDL interfaces and structs--it
is possible to use the exact same implementation classes for local and remote objects.
One potential disadvantage to this mechanism is that the local object must call a
number of methods on the remote object to obtain its initial state (often preferential
to making a number of remote calls over the life of the object). Furthermore, this
approach requires that for an object to be passed by value, its interface must provide
methods that enable its entire state to be read by another object. This requirement
goes against the concept of encapsulation, one of the goals of object-oriented design.
It might also require the developer to write more code.
CORBA and X Window System
One last issue involves the use of CORBA with applications written for the X Window
System. In both single-threaded and multithreaded applications, using CORBA and X
raises a number of concerns.
Single-Threaded Applications Using
CORBA and X
The primary issue in writing single-threaded applications that use CORBA and X
is that both these products try to install what is known as an event loop.
An event loop is what the name suggests: a loop in the application code (actually
in the windowing system code which is linked with the application code, in the case
of X) that waits for an event, processes it, and loops back to wait for another event,
and so on, ad nauseum. Such an event loop exists for X as well as for
CORBA. In the case of X, the event loop receives and processes events from the X
server; in the case of CORBA, the event loop processes events from other CORBA applications.
In either case, the event loop is the main loop of the application, designed such
that it expects to be running in its own thread all the time. Therein lies the problem
with single-threaded applications: Both CORBA and X expect to use their own event
loops, each of which expects to be run in its own thread, but there is only one thread
in the application.
Fortunately, ORB products usually have a mechanism for integrating the CORBA event
loop with an X event loop. In these cases, the CORBA events are registered with the
X event loop, so the single-event loop can handle events for both products. You can
refer to your product's documentation for more information on how this is accomplished.
Multithreaded Applications Using
CORBA and X
In a multithreaded environment, it is perfectly viable to run separate event loops
for X and CORBA, so the issues applying to single-threaded applications don't apply
to multithreaded applications. However, there are a couple of issues to be aware
of: Older revisions of X--versions prior to X11R6.1--are not thread-safe and therefore
must be used with care in a multithreading environment. This means that the developer
must take additional steps to ensure that multiple threads don't access X library
calls at the same time. (As of X11R6.1, however, X is thread-safe and does not suffer
from this restriction.)
A related issue is Motif, a common user interface library for X. As of the time
of this writing, there is not yet a thread-safe version of the Motif library. Thus,
even with the thread-safe X11R6.1 or greater, developers still need to take care
that multiple threads don't execute Motif library calls at the same time. As a result,
integrating CORBA with a Motif application in a multithreaded environment, at least
with the current version of Motif, takes as much effort as integrating CORBA with
a non-thread-safe X library in a multithreaded environment.
Integrating multithreading, CORBA, and non-thread-safe X and/or Motif is certainly
possible, although you can expect it to take some work. All non-thread-safe calls
need to be wrapped in methods that ensure that only one thread can call such a method
at any given time. One way of ensuring this is through a thread queue, a mechanism
enabling multiple threads to be queued (in other words, wait in line) for access
to non-thread-safe code. As thread-safe versions of X and Motif proliferate, this
will become less of an issue, but for now, CORBA developers should be aware.
Summary
Today you examined several issues associated with developing CORBA applications.
The most significant are those associated with developing CORBA applications in a
single-threaded environment and those raised by CORBA's current lack of pass-by-value
capability. You also learned a few, and by no means an exhaustive list of, workarounds
for these issues.
On Day 11, you'll move on to the next topic in advanced CORBA development: use
of the Dynamic Invocation Interface (DII). The DII enables CORBA applications to
learn about each other dynamically (in other words, at runtime) and access newly
discovered services.
Q&A


Q If non-trivial single-threaded CORBA applications raise so many design issues,
why wouldn't someone just use multithreading?

A Although multithreading is often the preferable alternative to wrestling with
the issues raised by single-threaded applications, there are times when multithreading
simply isn't available, such as when single-threading is dictated by choices of other
applications or development tools. It is for cases such as these that the design
patterns dealing with single-threaded applications are intended.

Q It was mentioned earlier in the chapter that some CORBA products implement reference
counting to manage object lifetime. What other way can this be accomplished?

A Another mechanism that can be used to manage object lifetime is for each remote
object to have a heartbeat. Other objects, or the ORBs themselves, can ping each
remote object to determine whether that object is still alive. If an object doesn't
respond to the ping within a preset period of time, the other object can assume that
the application containing that object has crashed. (As it turns out, a mechanism
similar to this one is used by other ORB-like products such as Microsoft's DCOM and
ObjectSpace's Voyager.)


Workshop
The following section will help you test your comprehension of the material presented
today and put what you've learned into practice. You'll find the answers to the quiz
in Appendix A. On most days, a few exercises will accompany the quiz; today, because
no real "working knowledge" material was presented, there are no exercises.
Quiz


1. What is the major issue associated with mixing client and server functionality
in a single-threaded CORBA application?

2. How can the use of reference counting in a CORBA application lead to problems?

3. Which version of X11 (the X Window System) would be required to safely run
multithreaded X-based applications?

4. Why is the capability to pass objects by value sometimes useful?

5. Why is it usually inadvisable to use the Exclusive oneway Call design
pattern introduced earlier in this chapter?










© Copyright, Macmillan Computer Publishing. All
rights reserved.
  • zanotowane.pl
  • doc.pisz.pl
  • pdf.pisz.pl
  • teen-mushing.xlx.pl
  • Wątki
    Powered by wordpress | Theme: simpletex | © Lemur zaprasza